"use client";

import React, { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import Link from "next/link";
import ConfirmableForm from "@/components/ConfirmableForm";
import { api } from "@/lib/fetcher";
import AccessDeniedCard from "@/components/AccessDeniedCard";
import { usePageTitle } from "@/hooks/usePageTitle";

// Types
type Member = {
  user_id: string;
  first_name?: string;
  email: string;
  role: "SUPER_ADMIN" | "ADMIN" | "AGENT" | "COMPTA";
  created_at: string;
  revoked: boolean;
  revoked_at?: string;
  last_sign_in_at?: string | null;
};

type ClientInfo = {
  id: string;
  name: string;
  api_name?: string;
} | null;

// Hook pour récupérer l'utilisateur courant (user_id) depuis /api/me
function useCurrentUserId() {
  return useQuery({
    queryKey: ["current-user-id"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", { 
          cache: "no-store", 
          headers: { Accept: "application/json" },
          credentials: "include"
        });
        if (!res.ok) return null;
        const me = await res.json();
        return me.user_id || me.userId || me.id || null;
      } catch {
        return null;
      }
    },
    staleTime: 30_000,
  });
}

// Hook pour récupérer l'email de l'utilisateur courant depuis /api/me
function useCurrentUserEmail() {
  return useQuery({
    queryKey: ["current-user-email"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", {
          cache: "no-store",
          headers: { Accept: "application/json" },
          credentials: "include",
        });
        if (!res.ok) return null;
        const me = await res.json();
        const rawEmail =
          me.email ||
          me.user_email ||
          (typeof me.user === "object" && me.user?.email) ||
          null;
        return typeof rawEmail === "string" ? rawEmail : null;
      } catch {
        return null;
      }
    },
    staleTime: 30_000,
  });
}

// Hook pour récupérer les infos client depuis /api/me
function useClientInfo() {
  return useQuery({
    queryKey: ["client-info"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", { 
          cache: "no-store", 
          headers: { Accept: "application/json" },
          credentials: "include"
        });
        if (!res.ok) return null;
        const me = await res.json();
        
        return {
          id: me.active_org_id || me.orgId || "unknown",
          name: me.active_org_name || me.orgName || "Organisation",
          api_name: me.active_org_api_name || me.orgApiName
        } as ClientInfo;
      } catch {
        return null;
      }
    },
    staleTime: 30_000, // Cache 30s
  });
}

// Hook pour récupérer les membres de l'organisation
function useOrganizationMembers(clientInfo: ClientInfo) {
  return useQuery({
    queryKey: ["organization-members", clientInfo?.id],
    queryFn: async () => {
      if (!clientInfo) throw new Error("Pas d'information client disponible");
      // Utilise la fonction api() avec clientInfo pour injecter les bons headers
      const response = await api<{ items: Member[] }>("/access", {}, clientInfo);
      const raw = response.items || [];
      const normalized = raw.map((it: any) => {
        const uid =
          it.user_id ||
          it.user_uuid ||
          it.userId ||
          it.uid ||
          it.id ||
          (typeof it.user === "object" && (it.user.id || it.user.user_id || it.user.userId)) ||
          null;
        const role = (it.role || "").toUpperCase();
        return {
          ...it,
          user_id: uid,
          role,
        } as Member;
      });
      return normalized;
    },
    enabled: !!clientInfo, // Ne s'exécute que si on a les infos client
    staleTime: 15_000,
  });
}

export default function StaffUsersListPage() {
  usePageTitle("Vos accès");
  
  // Récupération des infos client
  const { data: clientInfo = null, isLoading: isLoadingClient, error: clientError } = useClientInfo();

  // Récupération de l'utilisateur courant
  const { data: currentUserId, isLoading: isLoadingMe } = useCurrentUserId();
  // Récupération de l'email utilisateur courant
  const { data: currentUserEmail, isLoading: isLoadingEmail } = useCurrentUserEmail();
  
  // Récupération des membres
  const { 
    data: members = [], 
    isLoading: isLoadingMembers, 
    error: membersError,
    refetch 
  } = useOrganizationMembers(clientInfo);

  const isLoading = isLoadingClient || isLoadingMembers || isLoadingMe || isLoadingEmail;
  const error = clientError || membersError;

  const ROLE_PRIORITY: Record<Member["role"], number> = {
    SUPER_ADMIN: 0,
    ADMIN: 1,
    AGENT: 2,
    COMPTA: 3,
  };
  const sortedMembers = [...members].sort((a, b) => {
    const pa = ROLE_PRIORITY[a.role];
    const pb = ROLE_PRIORITY[b.role];
    if (pa !== pb) return pa - pb;
    const da = a.created_at ? new Date(a.created_at).getTime() : 0;
    const db = b.created_at ? new Date(b.created_at).getTime() : 0;
    // plus récent en premier
    return db - da;
  });

  // États de chargement et erreur
  if (isLoading) {
    return (
      <main className="p-6">
        <h1 className="text-lg font-semibold">Utilisateurs de la structure</h1>
        <p className="text-sm text-slate-600">Chargement...</p>
      </main>
    );
  }

  if (error || !clientInfo) {
    const msg = (error as any)?.message || "Aucune structure active trouvée";
    const isForbidden = /forbidden|403|not_allowed|insufficient|habilitations/i.test(String(msg));
    return (
      <main className="p-6 space-y-4">
        <h1 className="text-lg font-semibold">Utilisateurs de la structure</h1>
        {isForbidden ? (
          <AccessDeniedCard
            title="Accès restreint"
            message="Vous n'avez pas les habilitations nécessaires pour accéder à la gestion des utilisateurs."
            hint="Seul un ADMIN ou SUPER ADMIN peut accéder à cette section."
          />
        ) : (
          <div className="rounded-xl border border-red-200 bg-red-50 text-red-700 p-4 text-sm">
            Erreur de chargement : {msg}
          </div>
        )}
      </main>
    );
  }

  return (
    <main className="p-6 space-y-4">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
        <h1 className="text-lg font-semibold">
          Utilisateurs de la structure<span className="hidden sm:inline"> {clientInfo.name}</span>
        </h1>
        <Link
          href="/vos-acces/nouveau"
          className="inline-flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm bg-emerald-600 text-white hover:bg-emerald-700 w-full sm:w-auto"
        >
          + Créer un utilisateur
        </Link>
      </div>

      <section className="rounded-2xl border bg-white p-4">
        <h2 className="text-sm font-semibold mb-2">Niveaux d'habilitation</h2>
        <ul className="text-sm leading-6 text-slate-700 list-disc pl-5 space-y-1">
          <li>
            <span className="font-medium uppercase tracking-wide text-xs">Super Admin</span> — accès principal avec un accès total : gestion des utilisateurs (création, modification de niveau, révocation),
            toutes les données (contrats, paies, salarié·es, facturation). Ne peut être modifié que par le support Odentas.
          </li>
          <li>
            <span className="font-medium uppercase tracking-wide text-xs">Admin</span> — accès total : gestion des utilisateurs (création, modification de niveau, révocation) sauf le Super Admin,
            toutes les données (contrats, paies, salarié·es, facturation).
          </li>
          <li>
            <span className="font-medium uppercase tracking-wide text-xs">Agent</span> — accès opérationnel courant : création et suivi des contrats/paies et consultation salariés.
            Pas d'accès à la facturation ni à la gestion des utilisateurs.
          </li>
          <li>
            <span className="font-medium uppercase tracking-wide text-xs">Compta</span> — accès en lecture aux éléments financiers (paies, cotisations, facturation) et documents associés.
            Pas de création/modification de contrats ni gestion des utilisateurs.
          </li>
        </ul>
      </section>

      <div className="rounded-2xl border bg-white overflow-hidden">
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead className="bg-slate-50 text-slate-600">
              <tr>
                <th className="sticky left-0 z-10 bg-slate-50 text-left px-4 py-3 border-r">Prénom</th>
                <th className="text-left px-4 py-3">Email</th>
                <th className="text-left px-4 py-3">Niveau</th>
                <th className="text-left px-4 py-3">Créé le</th>
                <th className="text-left px-4 py-3">Statut</th>
                <th className="text-left px-4 py-3">Actions</th>
              </tr>
            </thead>
            <tbody>
              {members.length === 0 ? (
                <tr>
                  <td colSpan={6} className="px-4 py-6 text-slate-500">
                    Aucun utilisateur pour cette structure.
                  </td>
                </tr>
              ) : (
                sortedMembers.map((m) => {
                  const created = m.created_at ? new Date(m.created_at as string) : null;
                  const createdFmt = created
                    ? created.toLocaleString("fr-FR", {
                        year: "numeric",
                        month: "2-digit",
                        day: "2-digit",
                        hour: "2-digit",
                        minute: "2-digit",
                      })
                    : "—";
                  
                  // Déterminer le statut : révoqué, invitation envoyée, ou actif
                  let status = "Actif";
                  if (m.revoked) {
                    status = "Révoqué";
                  } else if (!m.last_sign_in_at) {
                    status = "Invitation envoyée";
                  }
                  
                  const disabled = !!m.revoked;
                  const isSelf =
                    (currentUserId && m.user_id === currentUserId) ||
                    (currentUserEmail && typeof m.email === "string" && m.email.toLowerCase() === currentUserEmail.toLowerCase());
                  // console.debug("ROW SELF CHECK", { currentUserId, rowUserId: m.user_id, currentUserEmail, rowEmail: m.email, isSelf });
                  return (
                    <tr key={m.user_id} className="border-t align-top">
                      <td className="sticky left-0 z-10 bg-white px-4 py-3 whitespace-nowrap border-r">{m.first_name || "—"}</td>
                      <td className="px-4 py-3">{m.email}</td>
                      <td className="px-4 py-3 uppercase tracking-wide text-xs">{m.role || "—"}</td>
                      <td className="px-4 py-3 whitespace-nowrap">{createdFmt}</td>
                      <td className="px-4 py-3">{status}</td>
                    <td className="px-4 py-2">
                      {
                        m.role === "SUPER_ADMIN" ? (
                          // Cas SUPER_ADMIN : on garde la card actuelle
                          <div className="rounded-xl border border-slate-200 bg-slate-50 p-3 shadow-sm">
                            <div className="flex items-start gap-3">
                              <div className="space-y-1">
                                <p className="text-xs text-slate-600">
                                  Contactez l'équipe Odentas pour modifier le <span className="font-medium uppercase tracking-wide text-xs">SUPER ADMIN</span>.
                                </p>
                              </div>
                            </div>
                          </div>
                        ) : isSelf ? (
                          // Cas utilisateur connecté (non SUPER_ADMIN) : petite card informative
                          <div className="rounded-xl border border-slate-200 bg-slate-50 p-3 shadow-sm">
                            <div className="space-y-1">
                              <p className="text-xs text-slate-600">
                                Contactez votre <span className="font-medium uppercase tracking-wide text-xs">SUPER ADMIN</span> ou le Staff Odentas pour supprimer votre propre accès.
                              </p>
                            </div>
                          </div>
                        ) : (
                          // Cas standard : formulaires d'action
                          <div className="flex flex-col gap-2">
                            <RoleUpdateForm
                              member={m}
                              orgId={clientInfo.id}
                              disabled={disabled}
                              onSuccess={() => refetch()}
                            />
                            {!disabled ? (
                              <RevokeForm
                                member={m}
                                orgId={clientInfo.id}
                                onSuccess={() => refetch()}
                              />
                            ) : (
                              <UnrevokeForm
                                member={m}
                                orgId={clientInfo.id}
                                onSuccess={() => refetch()}
                              />
                            )}
                            {disabled && (
                              <div className="text-xs text-slate-500">
                                Utilisateur révoqué — accès désactivé
                              </div>
                            )}
                          </div>
                        )
                      }
                    </td>
                  </tr>
                );
              })
            )}
          </tbody>
        </table>
        </div>
      </div>

      <div className="text-xs text-slate-500">
        * La suppression est une révocation : l'utilisateur reste historisé dans la base, mais ne peut plus se connecter.
      </div>
    </main>
  );
}

// Composant pour la modification du rôle
function RoleUpdateForm({ 
  member, 
  orgId, 
  disabled, 
  onSuccess 
}: { 
  member: Member; 
  orgId: string; 
  disabled: boolean; 
  onSuccess: () => void; 
}) {
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleSubmit = async (formData: FormData) => {
    if (isSubmitting) return;
    
    setIsSubmitting(true);
    try {
      const role = formData.get("role") as string;
      
      const response = await fetch(`/api/access/${member.user_id}/role`, {
        method: "PATCH",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: "include",
        body: JSON.stringify({ role }),
      });

      if (!response.ok) {
        const error = await response.json().catch(() => ({}));
        throw new Error(error.message || "Erreur lors de la modification du rôle");
      }

      onSuccess();
    } catch (error: any) {
      alert(`Erreur: ${error.message}`);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <ConfirmableForm
      action={handleSubmit}
      className="flex items-center gap-2"
      disabled={disabled || isSubmitting}
      confirmTitle="Confirmer la modification du niveau"
      confirmMessage={`Voulez-vous vraiment appliquer ce niveau à ${member.first_name || member.email} ?`}
    >
      <input type="hidden" name="org_id" value={orgId} />
      <input type="hidden" name="user_id" value={member.user_id} />
      <select
        name="role"
        defaultValue={member.role || "ADMIN"}
        disabled={disabled || isSubmitting}
        className="px-2 py-1 rounded border"
      >
        <option value="ADMIN">Admin</option>
        <option value="AGENT">Agent</option>
        <option value="COMPTA">Compta</option>
      </select>
      <button
        type="submit"
        disabled={disabled || isSubmitting}
        className="px-3 py-1 rounded bg-slate-900 text-white text-xs hover:bg-slate-700 disabled:opacity-50"
      >
        {isSubmitting ? "..." : "Modifier"}
      </button>
    </ConfirmableForm>
  );
}

// Composant pour la révocation
function RevokeForm({ 
  member, 
  orgId, 
  onSuccess 
}: { 
  member: Member; 
  orgId: string; 
  onSuccess: () => void; 
}) {
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleSubmit = async () => {
    if (isSubmitting) return;
    
    setIsSubmitting(true);
    try {
      const response = await fetch(`/api/access/${member.user_id}/revoke`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: "include",
      });

      if (!response.ok) {
        const error = await response.json().catch(() => ({}));
        throw new Error(error.message || "Erreur lors de la révocation");
      }

      onSuccess();
    } catch (error: any) {
      alert(`Erreur: ${error.message}`);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <ConfirmableForm
      action={handleSubmit}
      className="flex items-center gap-2"
      disabled={isSubmitting}
      confirmTitle="Confirmer la révocation"
      confirmMessage={`Voulez-vous révoquer l'accès de ${member.first_name || member.email} pour cette structure ?`}
      confirmCta="Révoquer"
    >
      <input type="hidden" name="org_id" value={orgId} />
      <input type="hidden" name="user_id" value={member.user_id} />
      <button
        type="submit"
        disabled={isSubmitting}
        className="px-3 py-1 rounded text-xs bg-red-600 text-white hover:bg-red-700 disabled:opacity-50"
      >
        {isSubmitting ? "..." : "Supprimer"}
      </button>
    </ConfirmableForm>
  );
}

// Composant pour la réintégration
function UnrevokeForm({ 
  member, 
  orgId, 
  onSuccess 
}: { 
  member: Member; 
  orgId: string; 
  onSuccess: () => void; 
}) {
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleSubmit = async () => {
    if (isSubmitting) return;
    
    setIsSubmitting(true);
    try {
      const response = await fetch(`/api/access/${member.user_id}/unrevoke`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: "include",
      });

      if (!response.ok) {
        const error = await response.json().catch(() => ({}));
        throw new Error(error.message || "Erreur lors de la réintégration");
      }

      onSuccess();
    } catch (error: any) {
      alert(`Erreur: ${error.message}`);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <ConfirmableForm
      action={handleSubmit}
      className="flex items-center gap-2"
      disabled={isSubmitting}
      confirmTitle="Confirmer la réintégration"
      confirmMessage={`Réintégrer ${member.first_name || member.email} et lui redonner l'accès à cette structure ?`}
      confirmCta="Réintégrer"
    >
      <input type="hidden" name="org_id" value={orgId} />
      <input type="hidden" name="user_id" value={member.user_id} />
      <button
        type="submit"
        disabled={isSubmitting}
        className="px-3 py-1 rounded text-xs bg-emerald-600 text-white hover:bg-emerald-700 disabled:opacity-50"
      >
        {isSubmitting ? "..." : "Réintégrer"}
      </button>
    </ConfirmableForm>
  );
}
