package org.eclipse.openk.contactbasedata.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import feign.Response;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.eclipse.openk.contactbasedata.api.AuthNAuthApi;
import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
import org.eclipse.openk.contactbasedata.model.*;
import org.eclipse.openk.contactbasedata.repository.CommunicationRepository;
import org.eclipse.openk.contactbasedata.repository.CommunicationTypeRepository;
import org.eclipse.openk.contactbasedata.repository.InternalPersonRepository;
import org.eclipse.openk.contactbasedata.service.util.LdapUserAttributesMapper;
import org.eclipse.openk.contactbasedata.viewmodel.LdapUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

@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 = mapKeycloakUserToInternaPerson(tblInternalPerson, keyCloakUserToSync);

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

    private boolean mapKeycloakUserToInternaPerson(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;
    }


}
