package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.BeneficiaireEffectifRestClient;
import dev.lions.unionflow.server.api.dto.kyc.request.CreateBeneficiaireEffectifRequest;
import dev.lions.unionflow.server.api.dto.kyc.request.UpdateBeneficiaireEffectifRequest;
import dev.lions.unionflow.server.api.dto.kyc.response.BeneficiaireEffectifResponse;
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.Collections;
import java.util.List;
import java.util.UUID;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.logging.Logger;

/**
 * Bean CRUD des Bénéficiaires Effectifs (Sprint 11 ⇄ backend Sprint 10).
 */
@Named
@ViewScoped
public class BeneficiaireEffectifBean implements Serializable {

  private static final long serialVersionUID = 1L;
  private static final Logger LOG = Logger.getLogger(BeneficiaireEffectifBean.class);

  @Inject @RestClient BeneficiaireEffectifRestClient client;

  // Filtres
  private UUID kycDossierId;
  private UUID organisationCibleId;
  private Boolean filtrePep;

  private List<BeneficiaireEffectifResponse> ubos = Collections.emptyList();
  private BeneficiaireEffectifResponse selection;
  private String erreur;

  // Formulaire de création
  private String nom;
  private String prenoms;
  private String nationalite;
  private String paysResidence;
  private String numeroPieceIdentite;
  private String pourcentageCapital;
  private String natureControle = "DETENTION_CAPITAL";
  private boolean estPep;

  public void rechercher() {
    erreur = null;
    try {
      ubos = client.lister(kycDossierId, organisationCibleId, filtrePep);
      LOG.infof("UBOs chargés : %d", ubos.size());
    } catch (Exception e) {
      handleError("Recherche UBO échouée", e);
      ubos = Collections.emptyList();
    }
  }

  public void creer() {
    if (kycDossierId == null && organisationCibleId == null) {
      addMessage(FacesMessage.SEVERITY_WARN, "Cible requise",
          "Sélectionnez d'abord un KycDossier ou une organisation cible");
      return;
    }
    try {
      CreateBeneficiaireEffectifRequest req = CreateBeneficiaireEffectifRequest.builder()
          .kycDossierId(kycDossierId)
          .organisationCibleId(organisationCibleId)
          .nom(nom)
          .prenoms(prenoms)
          .nationalite(nationalite != null ? nationalite.toUpperCase() : null)
          .paysResidence(paysResidence != null ? paysResidence.toUpperCase() : null)
          .numeroPieceIdentite(numeroPieceIdentite)
          .pourcentageCapital(pourcentageCapital != null && !pourcentageCapital.isBlank()
              ? new java.math.BigDecimal(pourcentageCapital) : null)
          .natureControle(natureControle)
          .estPep(estPep)
          .build();
      BeneficiaireEffectifResponse created = client.creer(req);
      addMessage(FacesMessage.SEVERITY_INFO, "UBO créé",
          created.prenoms() + " " + created.nom());
      resetForm();
      rechercher();
    } catch (Exception e) {
      handleError("Création UBO échouée", e);
    }
  }

  public void desactiverSelection() {
    if (selection == null) return;
    try {
      client.desactiver(selection.id());
      addMessage(FacesMessage.SEVERITY_INFO, "UBO désactivé",
          selection.prenoms() + " " + selection.nom());
      rechercher();
    } catch (Exception e) {
      handleError("Désactivation échouée", e);
    }
  }

  public void marquerPepSelection() {
    if (selection == null) return;
    try {
      UpdateBeneficiaireEffectifRequest req = UpdateBeneficiaireEffectifRequest.builder()
          .estPep(true).build();
      client.mettreAJour(selection.id(), req);
      addMessage(FacesMessage.SEVERITY_INFO, "UBO marqué PEP", "");
      rechercher();
    } catch (Exception e) {
      handleError("Mise à jour PEP échouée", e);
    }
  }

  private void resetForm() {
    nom = null;
    prenoms = null;
    nationalite = null;
    paysResidence = null;
    numeroPieceIdentite = null;
    pourcentageCapital = null;
    natureControle = "DETENTION_CAPITAL";
    estPep = false;
  }

  private void handleError(String summary, Exception e) {
    LOG.warnf("%s : %s", summary, e.getMessage());
    erreur = summary + " — " + e.getMessage();
    addMessage(FacesMessage.SEVERITY_ERROR, "Erreur", erreur);
  }

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

  // Getters / setters
  public UUID getKycDossierId() { return kycDossierId; }
  public void setKycDossierId(UUID kycDossierId) { this.kycDossierId = kycDossierId; }
  public UUID getOrganisationCibleId() { return organisationCibleId; }
  public void setOrganisationCibleId(UUID id) { this.organisationCibleId = id; }
  public Boolean getFiltrePep() { return filtrePep; }
  public void setFiltrePep(Boolean filtrePep) { this.filtrePep = filtrePep; }
  public List<BeneficiaireEffectifResponse> getUbos() { return ubos; }
  public BeneficiaireEffectifResponse getSelection() { return selection; }
  public void setSelection(BeneficiaireEffectifResponse selection) { this.selection = selection; }
  public String getErreur() { return erreur; }
  public String getNom() { return nom; }
  public void setNom(String nom) { this.nom = nom; }
  public String getPrenoms() { return prenoms; }
  public void setPrenoms(String prenoms) { this.prenoms = prenoms; }
  public String getNationalite() { return nationalite; }
  public void setNationalite(String nationalite) { this.nationalite = nationalite; }
  public String getPaysResidence() { return paysResidence; }
  public void setPaysResidence(String paysResidence) { this.paysResidence = paysResidence; }
  public String getNumeroPieceIdentite() { return numeroPieceIdentite; }
  public void setNumeroPieceIdentite(String n) { this.numeroPieceIdentite = n; }
  public String getPourcentageCapital() { return pourcentageCapital; }
  public void setPourcentageCapital(String pct) { this.pourcentageCapital = pct; }
  public String getNatureControle() { return natureControle; }
  public void setNatureControle(String nc) { this.natureControle = nc; }
  public boolean isEstPep() { return estPep; }
  public void setEstPep(boolean estPep) { this.estPep = estPep; }
}
