package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.BackupService;
import dev.lions.unionflow.server.api.dto.backup.request.CreateBackupRequest;
import dev.lions.unionflow.server.api.dto.backup.request.RestoreBackupRequest;
import dev.lions.unionflow.server.api.dto.backup.request.UpdateBackupConfigRequest;
import dev.lions.unionflow.server.api.dto.backup.response.BackupConfigResponse;
import dev.lions.unionflow.server.api.dto.backup.response.BackupResponse;
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.UUID;
import java.util.logging.Logger;

@Named("sauvegardeBean")
@SessionScoped
@Data
public class SauvegardeBean implements Serializable {

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

    @Inject
    @RestClient
    private BackupService backupService;

    private List<BackupResponse> sauvegardes = new ArrayList<>();
    private BackupConfigResponse configuration;
    private BackupResponse sauvegardeSelectionnee;

    private NouvelleSauvegarde nouvelleSauvegarde = new NouvelleSauvegarde();
    private OptionsRestauration optionsRestauration = new OptionsRestauration();
    private ConfigSauvegarde configSauvegarde = new ConfigSauvegarde();

    private int page = 0;
    private int taille = 20;

    @PostConstruct
    public void init() {
        chargerSauvegardes();
        chargerConfiguration();
    }

    public void chargerSauvegardes() {
        try {
            sauvegardes = backupService.listerSauvegardes(page, taille);
        } catch (Exception e) {
            LOGGER.severe("Erreur chargement sauvegardes: " + e.getMessage());
            sauvegardes = new ArrayList<>();
            ajouterMessageErreur("Impossible de charger les sauvegardes.");
        }
    }

    public void chargerConfiguration() {
        try {
            configuration = backupService.obtenirConfiguration();
            if (configuration != null) {
                configSauvegarde.autoActivee = configuration.getAutoBackupEnabled();
                configSauvegarde.frequence = configuration.getFrequency();
                configSauvegarde.retentionJours = configuration.getRetentionDays();
                configSauvegarde.heure = configuration.getBackupTime();
                configSauvegarde.includeDatabase = configuration.getIncludeDatabase();
                configSauvegarde.includeFiles = configuration.getIncludeFiles();
                configSauvegarde.includeConfiguration = configuration.getIncludeConfiguration();
            }
        } catch (Exception e) {
            LOGGER.warning("Configuration sauvegarde indisponible: " + e.getMessage());
        }
    }

    public void creerSauvegarde() {
        try {
            CreateBackupRequest request = CreateBackupRequest.builder()
                .name(nouvelleSauvegarde.nom)
                .description(nouvelleSauvegarde.description)
                .type(nouvelleSauvegarde.type)
                .includeDatabase(nouvelleSauvegarde.includeDatabase)
                .includeFiles(nouvelleSauvegarde.includeFiles)
                .includeConfiguration(nouvelleSauvegarde.includeConfiguration)
                .build();
            BackupResponse creee = backupService.creerSauvegarde(request);
            sauvegardes.add(0, creee);
            nouvelleSauvegarde = new NouvelleSauvegarde();
            ajouterMessageSucces("Sauvegarde lancée : " + creee.getName());
        } catch (Exception e) {
            LOGGER.severe("Erreur création sauvegarde: " + e.getMessage());
            ajouterMessageErreur("Impossible de créer la sauvegarde.");
        }
    }

    public void creerPointDeRestauration() {
        try {
            CreateBackupRequest request = CreateBackupRequest.builder()
                .name("Point de restauration - " + java.time.LocalDateTime.now())
                .type("RESTORE_POINT")
                .includeDatabase(true)
                .includeConfiguration(true)
                .build();
            BackupResponse point = backupService.creerPointDeRestauration(request);
            sauvegardes.add(0, point);
            ajouterMessageSucces("Point de restauration créé.");
        } catch (Exception e) {
            LOGGER.severe("Erreur création point restauration: " + e.getMessage());
            ajouterMessageErreur("Impossible de créer le point de restauration.");
        }
    }

    public void selectionnerPourRestauration(BackupResponse sauvegarde) {
        this.sauvegardeSelectionnee = sauvegarde;
        this.optionsRestauration = new OptionsRestauration();
        this.optionsRestauration.backupId = sauvegarde.getId();
    }

    public void restaurer() {
        if (sauvegardeSelectionnee == null) return;
        try {
            RestoreBackupRequest request = RestoreBackupRequest.builder()
                .backupId(sauvegardeSelectionnee.getId())
                .restoreDatabase(optionsRestauration.restoreDatabase)
                .restoreFiles(optionsRestauration.restoreFiles)
                .restoreConfiguration(optionsRestauration.restoreConfiguration)
                .createRestorePoint(optionsRestauration.creerPointAvant)
                .build();
            backupService.restaurer(request);
            sauvegardeSelectionnee = null;
            ajouterMessageSucces("Restauration lancée. Le système va redémarrer.");
        } catch (Exception e) {
            LOGGER.severe("Erreur restauration: " + e.getMessage());
            ajouterMessageErreur("Impossible de lancer la restauration.");
        }
    }

    public void supprimer(BackupResponse sauvegarde) {
        try {
            backupService.supprimer(sauvegarde.getId());
            sauvegardes.remove(sauvegarde);
            ajouterMessageSucces("Sauvegarde supprimée.");
        } catch (Exception e) {
            LOGGER.severe("Erreur suppression sauvegarde: " + e.getMessage());
            ajouterMessageErreur("Impossible de supprimer la sauvegarde.");
        }
    }

    public void sauvegarderConfiguration() {
        try {
            UpdateBackupConfigRequest request = UpdateBackupConfigRequest.builder()
                .autoBackupEnabled(configSauvegarde.autoActivee)
                .frequency(configSauvegarde.frequence)
                .retentionDays(configSauvegarde.retentionJours)
                .backupTime(configSauvegarde.heure)
                .includeDatabase(configSauvegarde.includeDatabase)
                .includeFiles(configSauvegarde.includeFiles)
                .includeConfiguration(configSauvegarde.includeConfiguration)
                .build();
            configuration = backupService.mettreAJourConfiguration(request);
            ajouterMessageSucces("Configuration sauvegardée.");
        } catch (Exception e) {
            LOGGER.severe("Erreur mise à jour configuration: " + e.getMessage());
            ajouterMessageErreur("Impossible de mettre à jour la configuration.");
        }
    }

    public void actualiser() {
        chargerSauvegardes();
        chargerConfiguration();
    }

    public String getStatusSeverity(String status) {
        if (status == null) return "warning";
        return switch (status) {
            case "COMPLETED" -> "success";
            case "IN_PROGRESS" -> "info";
            case "FAILED" -> "danger";
            default -> "warning";
        };
    }

    public String getStatusIcon(String status) {
        if (status == null) return "pi-clock";
        return switch (status) {
            case "COMPLETED" -> "pi-check-circle";
            case "IN_PROGRESS" -> "pi-spin pi-spinner";
            case "FAILED" -> "pi-times-circle";
            default -> "pi-clock";
        };
    }

    public String getTypeSeverity(String type) {
        if (type == null) return "info";
        return switch (type) {
            case "AUTO" -> "info";
            case "RESTORE_POINT" -> "warning";
            default -> "success";
        };
    }

    private void ajouterMessageSucces(String detail) {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", detail));
    }

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

    @Data
    public static class NouvelleSauvegarde {
        private String nom = "Sauvegarde manuelle";
        private String description;
        private String type = "MANUAL";
        private Boolean includeDatabase = true;
        private Boolean includeFiles = false;
        private Boolean includeConfiguration = true;
    }

    @Data
    public static class OptionsRestauration {
        private UUID backupId;
        private Boolean restoreDatabase = true;
        private Boolean restoreFiles = false;
        private Boolean restoreConfiguration = true;
        private Boolean creerPointAvant = true;
    }

    @Data
    public static class ConfigSauvegarde {
        private Boolean autoActivee = true;
        private String frequence = "DAILY";
        private Integer retentionJours = 30;
        private String heure = "02:00";
        private Boolean includeDatabase = true;
        private Boolean includeFiles = false;
        private Boolean includeConfiguration = true;
    }
}
