package dev.lions.user.manager.client.view;

import dev.lions.user.manager.client.service.SyncServiceClient;
import dev.lions.user.manager.dto.sync.HealthStatusDTO;
import dev.lions.user.manager.dto.sync.SyncConsistencyDTO;
import dev.lions.user.manager.dto.sync.SyncHistoryDTO;
import dev.lions.user.manager.dto.sync.SyncResultDTO;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import java.io.Serializable;
import java.time.format.DateTimeFormatter;
import java.util.logging.Logger;

@Named
@ViewScoped
public class SyncDashboardBean implements Serializable {

    private static final Logger LOGGER = Logger.getLogger(SyncDashboardBean.class.getName());

    private static final DateTimeFormatter DISPLAY_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");

    @Inject
    @RestClient
    SyncServiceClient syncService;

    @ConfigProperty(name = "lions.user.manager.default.realm", defaultValue = "lions-user-manager")
    String defaultRealm;

    private HealthStatusDTO keycloakStatus;
    private SyncConsistencyDTO consistencyResult;
    private SyncHistoryDTO lastSyncStatus;
    private String syncMessage;
    private String targetRealm;

    @PostConstruct
    public void init() {
        this.targetRealm = defaultRealm;
        checkKeycloakStatus();
        loadLastSyncStatus();
    }

    public void checkKeycloakStatus() {
        try {
            this.keycloakStatus = syncService.checkKeycloakHealth();
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la vérification de l'état de Keycloak: " + e.getMessage());
            this.keycloakStatus = new HealthStatusDTO();
            this.keycloakStatus.setOverallHealthy(false);
            this.keycloakStatus.setErrorMessage("Erreur de connexion: " + e.getMessage());
        }
    }

    public void syncUsers() {
        try {
            SyncResultDTO result = syncService.syncUsers(targetRealm);
            handleSyncResult("Utilisateurs", result);
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la synchronisation des utilisateurs: " + e.getMessage());
            addMessage(FacesMessage.SEVERITY_ERROR, "Erreur",
                    "Echec de la synchronisation des utilisateurs: " + e.getMessage());
        }
    }

    public void syncRoles() {
        try {
            // Sychronize realm roles
            SyncResultDTO result = syncService.syncRoles(targetRealm, null);
            handleSyncResult("Rôles", result);
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la synchronisation des rôles: " + e.getMessage());
            addMessage(FacesMessage.SEVERITY_ERROR, "Erreur",
                    "Echec de la synchronisation des rôles: " + e.getMessage());
        }
    }

    public void checkDataConsistency() {
        try {
            this.consistencyResult = syncService.checkDataConsistency(targetRealm);
            String status = consistencyResult.getStatus();
            if ("OK".equals(status)) {
                addMessage(FacesMessage.SEVERITY_INFO, "Cohérence OK",
                        consistencyResult.getUsersKeycloakCount() + " utilisateurs, "
                        + consistencyResult.getRolesKeycloakCount() + " rôles — données cohérentes.");
            } else {
                int missingLocal = (consistencyResult.getMissingUsersInLocal() != null
                        ? consistencyResult.getMissingUsersInLocal().size() : 0)
                        + (consistencyResult.getMissingRolesInLocal() != null
                        ? consistencyResult.getMissingRolesInLocal().size() : 0);
                addMessage(FacesMessage.SEVERITY_WARN, "Incohérence détectée",
                        missingLocal + " élément(s) manquant(s) localement. Lancez une synchronisation.");
            }
        } catch (Exception e) {
            LOGGER.severe("Erreur vérification cohérence: " + e.getMessage());
            addMessage(FacesMessage.SEVERITY_ERROR, "Erreur", "Impossible de vérifier la cohérence: " + e.getMessage());
        }
    }

    public void loadLastSyncStatus() {
        try {
            this.lastSyncStatus = syncService.getLastSyncStatus(targetRealm);
        } catch (Exception e) {
            LOGGER.warning("Impossible de charger le statut de sync: " + e.getMessage());
        }
    }

    public void forceSyncRealm() {
        try {
            this.lastSyncStatus = syncService.forceSyncRealm(targetRealm);
            String status = lastSyncStatus != null ? lastSyncStatus.getStatus() : "UNKNOWN";
            if ("SUCCESS".equals(status)) {
                Integer items = lastSyncStatus.getItemsProcessed();
                addMessage(FacesMessage.SEVERITY_INFO, "Synchronisation forcée réussie",
                        (items != null ? items : 0) + " éléments traités.");
            } else {
                addMessage(FacesMessage.SEVERITY_WARN, "Synchronisation terminée avec avertissement",
                        lastSyncStatus != null ? lastSyncStatus.getErrorMessage() : "Statut inconnu");
            }
        } catch (Exception e) {
            LOGGER.severe("Erreur synchronisation forcée: " + e.getMessage());
            addMessage(FacesMessage.SEVERITY_ERROR, "Erreur", "Echec de la synchronisation forcée: " + e.getMessage());
        }
    }

    // Convenience methods for view
    public String getLastSyncDate() {
        if (lastSyncStatus == null || lastSyncStatus.getSyncDate() == null) return "Jamais synchronisé";
        return lastSyncStatus.getSyncDate().format(DISPLAY_FORMATTER);
    }

    public String getLastSyncStatusLabel() {
        if (lastSyncStatus == null) return "INCONNU";
        return lastSyncStatus.getStatus() != null ? lastSyncStatus.getStatus() : "INCONNU";
    }

    public String getLastSyncItemsProcessed() {
        if (lastSyncStatus == null || lastSyncStatus.getItemsProcessed() == null) return "N/A";
        return String.valueOf(lastSyncStatus.getItemsProcessed());
    }

    public String getConsistencyStatusLabel() {
        if (consistencyResult == null) return "Non vérifié";
        return consistencyResult.getStatus() != null ? consistencyResult.getStatus() : "N/A";
    }

    public int getConsistencyMissingCount() {
        if (consistencyResult == null) return 0;
        int missing = 0;
        if (consistencyResult.getMissingUsersInLocal() != null) missing += consistencyResult.getMissingUsersInLocal().size();
        if (consistencyResult.getMissingRolesInLocal() != null) missing += consistencyResult.getMissingRolesInLocal().size();
        return missing;
    }

    private void handleSyncResult(String type, SyncResultDTO result) {
        String msg = result.isSuccess()
                ? "Synchronisation réussie. " + type + " synchronisés : "
                        + ("Utilisateurs".equals(type) ? result.getUsersCount() : result.getRealmRolesCount())
                : result.getErrorMessage();

        if (result.isSuccess()) {
            addMessage(FacesMessage.SEVERITY_INFO, "Succès", msg);
        } else {
            addMessage(FacesMessage.SEVERITY_WARN, "Attention", type + ": " + msg);
        }
        this.syncMessage = msg;
    }

    private void addMessage(FacesMessage.Severity severity, String summary, String detail) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(severity, summary, detail));
    }

    // Getters and Setters
    public HealthStatusDTO getKeycloakStatus() { return keycloakStatus; }
    public void setKeycloakStatus(HealthStatusDTO keycloakStatus) { this.keycloakStatus = keycloakStatus; }
    public SyncConsistencyDTO getConsistencyResult() { return consistencyResult; }
    public SyncHistoryDTO getLastSyncStatusDTO() { return lastSyncStatus; }

    public String getKeycloakStatusLabel() {
        return (keycloakStatus != null && keycloakStatus.isOverallHealthy()) ? "UP" : "DOWN";
    }

    public String getKeycloakStatusMessage() {
        if (keycloakStatus == null)
            return "Unknown status";
        if (keycloakStatus.isOverallHealthy())
            return "Keycloak est accessible.";
        return keycloakStatus.getErrorMessage() != null ? keycloakStatus.getErrorMessage() : "Erreur inconnue";
    }

    public String getKeycloakVersion() {
        return (keycloakStatus != null) ? keycloakStatus.getKeycloakVersion() : "N/A";
    }

    public String getSyncMessage() {
        return syncMessage;
    }

    public void setSyncMessage(String syncMessage) {
        this.syncMessage = syncMessage;
    }

    public String getTargetRealm() {
        return targetRealm;
    }

    public void setTargetRealm(String targetRealm) {
        this.targetRealm = targetRealm;
    }
}
