package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.RoleDelegationRestClient;
import dev.lions.unionflow.server.api.dto.delegation.request.CreateRoleDelegationRequest;
import dev.lions.unionflow.server.api.dto.delegation.response.RoleDelegationResponse;
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.time.LocalDateTime;
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 liste/création/révocation des délégations de rôle (Sprint 11 ⇄ backend Sprint 10).
 */
@Named
@ViewScoped
public class RoleDelegationBean implements Serializable {

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

  @Inject @RestClient RoleDelegationRestClient client;

  private UUID organisationId;
  private List<RoleDelegationResponse> delegations = Collections.emptyList();
  private RoleDelegationResponse selection;
  private String erreur;

  // Formulaire création
  private UUID delegantUserId;
  private UUID delegataireUserId;
  private String roleDelegue = "TRESORIER";
  private LocalDateTime dateDebut = LocalDateTime.now().plusHours(1);
  private LocalDateTime dateFin = LocalDateTime.now().plusDays(14);
  private String motif;
  private String rolesDelegataireCsv;

  public void rechercher() {
    erreur = null;
    if (organisationId == null) return;
    try {
      delegations = client.listerParOrganisation(organisationId);
      LOG.infof("Délégations chargées org=%s : %d", organisationId, delegations.size());
    } catch (Exception e) {
      handleError("Chargement délégations échoué", e);
      delegations = Collections.emptyList();
    }
  }

  public void creer() {
    if (organisationId == null || delegantUserId == null || delegataireUserId == null) {
      addMessage(FacesMessage.SEVERITY_WARN, "Champs requis",
          "Organisation, déléguant et délégataire sont obligatoires");
      return;
    }
    try {
      CreateRoleDelegationRequest req = CreateRoleDelegationRequest.builder()
          .organisationId(organisationId)
          .delegantUserId(delegantUserId)
          .delegataireUserId(delegataireUserId)
          .roleDelegue(roleDelegue)
          .dateDebut(dateDebut)
          .dateFin(dateFin)
          .motif(motif)
          .build();
      RoleDelegationResponse created = client.creer(req, rolesDelegataireCsv);
      addMessage(FacesMessage.SEVERITY_INFO, "Délégation créée",
          "Rôle " + created.roleDelegue() + " jusqu'au " + created.dateFin());
      resetForm();
      rechercher();
    } catch (Exception e) {
      handleError("Création délégation échouée", e);
    }
  }

  public void revoquerSelection() {
    if (selection == null) return;
    try {
      client.revoquer(selection.id());
      addMessage(FacesMessage.SEVERITY_INFO, "Délégation révoquée",
          "Rôle " + selection.roleDelegue());
      rechercher();
    } catch (Exception e) {
      handleError("Révocation échouée", e);
    }
  }

  public String getCouleurStatut(String statut) {
    if (statut == null) return "secondary";
    return switch (statut) {
      case "ACTIVE" -> "success";
      case "REVOQUEE" -> "danger";
      case "EXPIREE" -> "warning";
      default -> "secondary";
    };
  }

  private void resetForm() {
    delegantUserId = null;
    delegataireUserId = null;
    roleDelegue = "TRESORIER";
    dateDebut = LocalDateTime.now().plusHours(1);
    dateFin = LocalDateTime.now().plusDays(14);
    motif = null;
    rolesDelegataireCsv = null;
  }

  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 getOrganisationId() { return organisationId; }
  public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; }
  public List<RoleDelegationResponse> getDelegations() { return delegations; }
  public RoleDelegationResponse getSelection() { return selection; }
  public void setSelection(RoleDelegationResponse selection) { this.selection = selection; }
  public String getErreur() { return erreur; }
  public UUID getDelegantUserId() { return delegantUserId; }
  public void setDelegantUserId(UUID id) { this.delegantUserId = id; }
  public UUID getDelegataireUserId() { return delegataireUserId; }
  public void setDelegataireUserId(UUID id) { this.delegataireUserId = id; }
  public String getRoleDelegue() { return roleDelegue; }
  public void setRoleDelegue(String roleDelegue) { this.roleDelegue = roleDelegue; }
  public LocalDateTime getDateDebut() { return dateDebut; }
  public void setDateDebut(LocalDateTime dateDebut) { this.dateDebut = dateDebut; }
  public LocalDateTime getDateFin() { return dateFin; }
  public void setDateFin(LocalDateTime dateFin) { this.dateFin = dateFin; }
  public String getMotif() { return motif; }
  public void setMotif(String motif) { this.motif = motif; }
  public String getRolesDelegataireCsv() { return rolesDelegataireCsv; }
  public void setRolesDelegataireCsv(String csv) { this.rolesDelegataireCsv = csv; }
}
