package com.sonymusic.dx.dxuiservice.usm;

import java.util.Base64;
import java.util.List;
import java.util.Optional;

import com.sonymusic.dx.dxuiservice.exception.ServiceUnavailableException;
import com.sonymusic.dx.dxuiservice.properties.USMApiClientProperties;
import com.sonymusic.dx.dxuiservice.service.dto.UserInputDto;
import com.sonymusic.dx.dxuiservice.usm.api.USMApiClient;
import com.sonymusic.dx.dxuiservice.usm.api.UserLookUpData;
import com.sonymusic.dx.dxuiservice.usm.api.UserSearchData;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * Usm user service.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class USMUserService {

    private final USMApiClient usmApiClient;
    private final USMApiClientProperties usmApiClientProperties;

    /**
     * Search users.
     *
     * @param query search query.
     * @return List of {@link UserSearchData}
     */
    public List<UserSearchData> searchUsers(String query) {
        var header = getBasicAuthHeader(usmApiClientProperties.getClientId(),
                usmApiClientProperties.getClientSecret());

        var response = usmApiClient.searchUsers(query, header);

        if (response.getSuccess()) {
            return response.getData();
        }

        var error = "Failed to search users with query %s - status: %d, reason: %s"
                .formatted(query, response.getStatusCode(), response.getMessage());
        log.error(error);

        throw new ServiceUnavailableException(error);
    }

    /**
     * Lookup user.
     *
     * @param email user email.
     * @return {@link UserSearchData}
     */
    public Optional<UserLookUpData> lookupUser(String email) {
        var header = getBasicAuthHeader(usmApiClientProperties.getClientId(),
                usmApiClientProperties.getClientSecret());

        var response = usmApiClient.lookupUser(new USMApiClient.LookupRequestData().setEmail(email),
                header);

        if (response.getSuccess()) {
            return Optional.ofNullable(response.getData());
        }

        return Optional.empty();
    }

    /**
     * Save user.
     *
     * @param dto user input dto.
     */
    public void saveUser(UserInputDto dto) {
        var header = getBasicAuthHeader(usmApiClientProperties.getClientId(),
                usmApiClientProperties.getClientSecret());

        var saveData = new USMApiClient.SaveRequestData()
                .setEmail(dto.getEmail())
                .setFirstName(dto.getFirstName())
                .setLastName(dto.getLastName())
                .setJobTitle(dto.getJobTitle())
                .setDepartment(dto.getDepartment())
                .setCompanyName(dto.getCompany())
                .setOfficeLocation(dto.getOfficeLocation())
                .setStreetAddress(dto.getStreetAddress())
                .setSendWelcomeEmail(true);

        var response = usmApiClient.saveUser(saveData, header);

        if (!response.getSuccess()) {
            throw new ServiceUnavailableException(
                    "Failed to save user with email: %s in USM - reason: %s"
                            .formatted(dto.getEmail(), response.getMessage())
            );
        }
    }

    private String getBasicAuthHeader(String clientId, String clientSecret) {
        String credentials = clientId + ":" + clientSecret;
        return "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes());
    }

}
