package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.LogsService;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Data;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

@Named("logsSystemeBean")
@SessionScoped
@Data
public class LogsSystemeBean implements Serializable {

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

    @Inject
    @RestClient
    private LogsService logsService;

    @Inject
    private UserSession userSession;

    // Logs système
    private List<Map<String, Object>> logsSysteme = new ArrayList<>();
    private List<Map<String, Object>> logsAuditFinance = new ArrayList<>();
    private List<Map<String, Object>> anomalies = new ArrayList<>();

    // Santé système
    private Map<String, Object> santeSysteme;
    private Map<String, Object> metriques;

    // Filtres logs système
    private String filtreLevel;
    private String filtreSource;
    private String filtreUserId;
    private String dateDebut;
    private String dateFin;
    private String motCle;

    // Filtres audit finance
    private String filtreOperation;
    private String filtreEntityType;
    private String filtreSeverity;

    // Pagination
    private int page = 0;
    private int taille = 50;

    private UUID getOrgId() {
        return userSession.getEntite() != null ? userSession.getEntite().getId() : null;
    }

    @PostConstruct
    public void init() {
        chargerSanteSysteme();
        chargerLogsSysteme();
    }

    public void chargerSanteSysteme() {
        try {
            santeSysteme = logsService.obtenirSanteSysteme();
            metriques = logsService.obtenirMetriques();
        } catch (Exception e) {
            LOGGER.warning("Santé système indisponible: " + e.getMessage());
        }
    }

    public void chargerLogsSysteme() {
        try {
            logsSysteme = logsService.rechercherLogs(
                    filtreLevel, filtreSource, filtreUserId,
                    dateDebut, dateFin, motCle, page, taille);
        } catch (Exception e) {
            LOGGER.severe("Erreur chargement logs: " + e.getMessage());
            logsSysteme = new ArrayList<>();
            ajouterMessageErreur("Impossible de charger les logs système.");
        }
    }

    public void chargerLogsAuditFinance() {
        try {
            UUID orgId = getOrgId();
            logsAuditFinance = logsService.obtenirLogsAuditFinance(
                    orgId, dateDebut, dateFin,
                    filtreOperation, filtreEntityType, filtreSeverity, taille);
        } catch (Exception e) {
            LOGGER.severe("Erreur chargement audit finance: " + e.getMessage());
            logsAuditFinance = new ArrayList<>();
            ajouterMessageErreur("Impossible de charger les logs d'audit finance.");
        }
    }

    public void chargerAnomalies() {
        try {
            UUID orgId = getOrgId();
            anomalies = logsService.obtenirAnomalies(orgId, dateDebut, dateFin);
        } catch (Exception e) {
            LOGGER.warning("Impossible de charger les anomalies: " + e.getMessage());
            anomalies = new ArrayList<>();
        }
    }

    public void appliquerFiltres() {
        page = 0;
        chargerLogsSysteme();
    }

    public void reinitialiserFiltres() {
        filtreLevel = null;
        filtreSource = null;
        filtreUserId = null;
        dateDebut = null;
        dateFin = null;
        motCle = null;
        page = 0;
        chargerLogsSysteme();
    }

    public void actualiser() {
        chargerSanteSysteme();
        chargerLogsSysteme();
    }

    public String getLevelSeverity(String level) {
        if (level == null) return "info";
        return switch (level.toUpperCase()) {
            case "ERROR", "SEVERE" -> "danger";
            case "WARN", "WARNING" -> "warning";
            case "INFO" -> "info";
            default -> "secondary";
        };
    }

    public String getSanteSeverity(String status) {
        if (status == null) return "warning";
        return switch (status.toUpperCase()) {
            case "UP" -> "success";
            case "DEGRADED" -> "warning";
            default -> "danger";
        };
    }

    private void ajouterMessageErreur(String detail) {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", detail));
    }
}
