package org.eclipse.openk.contactbasedata.service;

import lombok.extern.log4j.Log4j2;
import org.eclipse.openk.contactbasedata.api.AuthNAuthApi;
import org.eclipse.openk.contactbasedata.model.JwtToken;
import org.eclipse.openk.contactbasedata.model.KeyCloakUser;
import org.eclipse.openk.contactbasedata.model.LoginCredentials;
import org.eclipse.openk.contactbasedata.model.TblInternalPerson;
import org.eclipse.openk.contactbasedata.repository.InternalPersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Log4j2
@Service
public class AuthNAuthService {

    @Value("${authnauth-sync.technical-username}")
    private String technicalUsername;

    @Value("${authnauth-sync.technical-userpassword}")
    private String technicalUserPassword;

    @Autowired
    private InternalPersonRepository internalPersonRepository;

    @Autowired
    AuthNAuthApi authNAuthApi;

    public List<KeyCloakUser> getKeycloakUsersWithTechnicalLogin() {
        LoginCredentials loginCredentials = new LoginCredentials(technicalUsername, technicalUserPassword);
        JwtToken jwtToken = authNAuthApi.login(loginCredentials);
        List<KeyCloakUser> keycloakUsers = authNAuthApi.getKeycloakUsers(jwtToken.getAccessToken());
        authNAuthApi.logout(jwtToken.getAccessToken());
        return keycloakUsers;
    }

    @Transactional
    public void synchronizeAuthNAuth() {
        List<KeyCloakUser> keycloakUsers = getKeycloakUsersWithTechnicalLogin();
        List<TblInternalPerson> internalPersonList = internalPersonRepository.findByUserRefNotNull();

        Map<String, KeyCloakUser> userRefToKeycloakMap = keycloakUsers.stream().collect(
                Collectors.toMap(KeyCloakUser::getUsername, Function.identity()));

        List<TblInternalPerson> internalPersonListSynchronized = getTblInternalPersonSynchronized(internalPersonList, userRefToKeycloakMap);

        //Update all Users with the synchronized KeyCloak data
        internalPersonRepository.saveAll(internalPersonListSynchronized);

        log.info("Synchronization changed data of: " + internalPersonListSynchronized.size() + " internal user/s");
        log.info("Attribute/s of the following internal user/s were updated:");
        for (TblInternalPerson tblInternalPerson : internalPersonListSynchronized) {
            log.info("Id: " + tblInternalPerson.getId() + " Firstname: " + tblInternalPerson.getFirstName() + " Lastname: " + tblInternalPerson.getLastName());
        }

    }

    private List<TblInternalPerson> getTblInternalPersonSynchronized(List<TblInternalPerson> internalPersonList, Map<String, KeyCloakUser> userRefToKeycloakMap) {
        List<TblInternalPerson> internalPersonListSynchronized = new ArrayList<>();

        for (TblInternalPerson tblInternalPerson : internalPersonList) {

            KeyCloakUser keyCloakUserToSync = userRefToKeycloakMap.get(tblInternalPerson.getUserRef());
            boolean attributesChanged = mapKeycloakUserToInternalPerson(tblInternalPerson, keyCloakUserToSync);

            if (attributesChanged) {
                internalPersonListSynchronized.add(tblInternalPerson);
            }
        }
        return internalPersonListSynchronized;
    }

    private boolean mapKeycloakUserToInternalPerson(TblInternalPerson tblInternalPerson, KeyCloakUser keyCloakUserToSync) {
        boolean attributesChanged = false;
        if (keyCloakUserToSync == null) {
            tblInternalPerson.setUserRef(null);
            attributesChanged = true;
        } else {
            if (!Objects.equals(tblInternalPerson.getFirstName(), keyCloakUserToSync.getFirstName())
                    || !Objects.equals(tblInternalPerson.getLastName(), keyCloakUserToSync.getLastName())) {
                tblInternalPerson.setLastName(keyCloakUserToSync.getLastName());
                tblInternalPerson.setFirstName(keyCloakUserToSync.getFirstName());
                attributesChanged = true;
            }
        }
        return attributesChanged;
    }


}
