package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.TypeOrganisationClientDTO;
import dev.lions.unionflow.client.service.TypeOrganisationClientService;
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 java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;
import org.eclipse.microprofile.rest.client.inject.RestClient;

/**
 * Bean de gestion du catalogue des types d'organisation (UI Super Admin).
 */
@Named("typeOrganisationsAdminBean")
@ViewScoped
public class TypeOrganisationsAdminBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(TypeOrganisationsAdminBean.class.getName());

    @Inject
    @RestClient
    TypeOrganisationClientService typeOrganisationClientService;

    private List<TypeOrganisationClientDTO> types = new ArrayList<>();
    /** Type actuellement édité dans le dialogue (nouveau ou existant). */
    private TypeOrganisationClientDTO typeCourant;
    private TypeOrganisationClientDTO typeSelectionne;

    @PostConstruct
    public void init() {
        chargerTypes();
    }

    public void chargerTypes() {
        try {
            types = typeOrganisationClientService.list(false);
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des types d'organisation: " + e.getMessage());
            types = new ArrayList<>();
        }
    }

    public void preparerNouveauType() {
        typeCourant = new TypeOrganisationClientDTO();
        typeCourant.setActif(true);
        typeSelectionne = null;
    }

    private void creerType() {
        try {
            TypeOrganisationClientDTO cree = typeOrganisationClientService.create(typeCourant);
            types.add(cree);
            typeCourant = null;
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Succès", "Type d'organisation créé avec succès"));
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la création du type d'organisation: " + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Erreur", "Impossible de créer le type d'organisation: " + e.getMessage()));
        }
    }

    /**
     * Méthode unique utilisée par le bouton "Enregistrer" du dialogue.
     * Si un nouveau type est en cours d'édition, on crée, sinon on met à jour le type sélectionné.
     */
    public void enregistrerType() {
        if (typeCourant == null) {
            return;
        }
        if (typeCourant.getId() == null) {
            creerType();
        } else {
            sauvegarderType();
        }
    }
    private void sauvegarderType() {
        if (typeCourant == null || typeCourant.getId() == null) {
            return;
        }
        try {
            TypeOrganisationClientDTO maj =
                typeOrganisationClientService.update(typeCourant.getId(), typeCourant);
            // Remplacer dans la liste
            types.replaceAll(t -> t.getId().equals(maj.getId()) ? maj : t);
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Succès", "Type d'organisation mis à jour"));
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la mise à jour du type d'organisation: " + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Erreur", "Impossible de mettre à jour le type d'organisation: " + e.getMessage()));
        }
    }

    public void desactiverType(UUID id) {
        try {
            typeOrganisationClientService.disable(id);
            types.stream()
                .filter(t -> t.getId().equals(id))
                .findFirst()
                .ifPresent(t -> t.setActif(false));
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Succès", "Type d'organisation désactivé"));
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la désactivation du type d'organisation: " + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Erreur", "Impossible de désactiver le type d'organisation: " + e.getMessage()));
        }
    }

    // Getters / Setters
    public List<TypeOrganisationClientDTO> getTypes() { return types; }
    public void setTypes(List<TypeOrganisationClientDTO> types) { this.types = types; }

    public TypeOrganisationClientDTO getTypeSelectionne() { return typeSelectionne; }
    public void setTypeSelectionne(TypeOrganisationClientDTO typeSelectionne) {
        this.typeSelectionne = typeSelectionne;
        this.typeCourant = typeSelectionne;
    }

    /**
     * Retourne le type actuellement édité dans le dialogue.
     * Initialise un nouveau type par défaut si aucun n'est encore défini,
     * ce qui évite les erreurs "Target Unreachable" lors de la validation JSF.
     */
    public TypeOrganisationClientDTO getTypeCourant() {
        if (typeCourant == null) {
            typeCourant = new TypeOrganisationClientDTO();
            typeCourant.setActif(true);
        }
        return typeCourant;
    }
    public void setTypeCourant(TypeOrganisationClientDTO typeCourant) { this.typeCourant = typeCourant; }
}


