import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { User, Lock, Bell, Palette, Save, Check, Eye, EyeOff, Mail } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
import { Switch } from "@/components/ui/switch";
import { Skeleton } from "@/components/ui/skeleton";
import { useAuth } from "@/auth/AuthProvider";
import { useListUsers, useUpdateUser } from "@/api/users";

// ─── Schemas ──────────────────────────────────────────────────────────────────

const profileSchema = z.object({
  name: z.string().min(1, "Le nom est requis"),
});

const passwordSchema = z
  .object({
    password: z.string().min(8, "Minimum 8 caractères"),
    confirmPassword: z.string(),
  })
  .refine((d) => d.password === d.confirmPassword, {
    message: "Les mots de passe ne correspondent pas",
    path: ["confirmPassword"],
  });

type ProfileFormData = z.infer<typeof profileSchema>;
type PasswordFormData = z.infer<typeof passwordSchema>;

// ─── Theme helpers ────────────────────────────────────────────────────────────

function getStoredTheme(): "light" | "dark" {
  return (localStorage.getItem("veylant_theme") as "light" | "dark") ?? "light";
}

function applyTheme(theme: "light" | "dark") {
  localStorage.setItem("veylant_theme", theme);
  if (theme === "dark") {
    document.documentElement.classList.add("dark");
  } else {
    document.documentElement.classList.remove("dark");
  }
}

// ─── Section nav ──────────────────────────────────────────────────────────────

const SECTIONS = [
  { id: "profile", label: "Profil", icon: User },
  { id: "security", label: "Sécurité", icon: Lock },
  { id: "notifications", label: "Notifications", icon: Bell },
  { id: "appearance", label: "Apparence", icon: Palette },
] as const;

type SectionId = (typeof SECTIONS)[number]["id"];

// ─── Component ────────────────────────────────────────────────────────────────

export function SettingsPage() {
  const { user } = useAuth();
  const { data: users, isLoading: usersLoading } = useListUsers();
  const updateUser = useUpdateUser();

  const [activeSection, setActiveSection] = useState<SectionId>("profile");
  const [profileSaved, setProfileSaved] = useState(false);
  const [passwordSaved, setPasswordSaved] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const [theme, setTheme] = useState<"light" | "dark">(getStoredTheme);

  // Notification preferences stored in localStorage
  const [notifBudget, setNotifBudget] = useState(
    () => localStorage.getItem("veylant_notif_budget") !== "false"
  );
  const [notifSecurity, setNotifSecurity] = useState(
    () => localStorage.getItem("veylant_notif_security") !== "false"
  );
  const [notifEmail, setNotifEmail] = useState(
    () => localStorage.getItem("veylant_notif_email") ?? ""
  );
  const [emailSaved, setEmailSaved] = useState(false);

  // Find the current user's full record from the API (to get department, role, is_active)
  const currentUserRecord = users?.find((u) => u.id === user?.id);

  const profileForm = useForm<ProfileFormData>({
    resolver: zodResolver(profileSchema),
    defaultValues: { name: user?.name ?? "" },
  });

  const passwordForm = useForm<PasswordFormData>({
    resolver: zodResolver(passwordSchema),
    defaultValues: { password: "", confirmPassword: "" },
  });

  // Sync name field once the user record loads from API
  useEffect(() => {
    if (currentUserRecord) {
      profileForm.reset({ name: currentUserRecord.name });
    }
  }, [currentUserRecord, profileForm]);

  const handleProfileSave = profileForm.handleSubmit(async (data) => {
    if (!user || !currentUserRecord) return;
    await updateUser.mutateAsync({
      id: user.id,
      email: currentUserRecord.email,
      name: data.name,
      department: currentUserRecord.department,
      role: currentUserRecord.role,
      is_active: currentUserRecord.is_active,
    });
    setProfileSaved(true);
    setTimeout(() => setProfileSaved(false), 2500);
  });

  const handlePasswordSave = passwordForm.handleSubmit(async (data) => {
    if (!user || !currentUserRecord) return;
    await updateUser.mutateAsync({
      id: user.id,
      email: currentUserRecord.email,
      name: currentUserRecord.name,
      department: currentUserRecord.department,
      role: currentUserRecord.role,
      is_active: currentUserRecord.is_active,
      password: data.password,
    });
    passwordForm.reset();
    setPasswordSaved(true);
    setTimeout(() => setPasswordSaved(false), 2500);
  });

  const handleThemeChange = (dark: boolean) => {
    const t = dark ? "dark" : "light";
    setTheme(t);
    applyTheme(t);
  };

  // Decode token expiry for display
  let tokenExpiry: string | null = null;
  if (user?.token) {
    try {
      const payload = JSON.parse(
        atob(user.token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))
      ) as { exp?: number };
      if (payload.exp) {
        tokenExpiry = new Date(payload.exp * 1000).toLocaleString("fr-FR");
      }
    } catch {
      // non-blocking
    }
  }

  const initials = (user?.name ?? user?.email ?? "?")[0].toUpperCase();

  return (
    <div className="max-w-4xl space-y-6">
      <div>
        <h2 className="text-xl font-bold">Paramètres</h2>
        <p className="text-sm text-muted-foreground">
          Gérez votre compte et vos préférences
        </p>
      </div>

      <div className="flex flex-col md:flex-row gap-6">
        {/* Left section nav */}
        <nav className="md:w-44 shrink-0 flex flex-row md:flex-col gap-1 overflow-x-auto md:overflow-visible">
          {SECTIONS.map((s) => (
            <button
              key={s.id}
              onClick={() => setActiveSection(s.id)}
              className={`flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors text-left whitespace-nowrap w-full ${
                activeSection === s.id
                  ? "bg-primary text-primary-foreground"
                  : "text-muted-foreground hover:bg-accent hover:text-accent-foreground"
              }`}
            >
              <s.icon className="h-4 w-4 shrink-0" />
              {s.label}
            </button>
          ))}
        </nav>

        {/* Section content */}
        <div className="flex-1 min-w-0 space-y-4">
          {/* ── Profil ──────────────────────────────────────────────────────── */}
          {activeSection === "profile" && (
            <>
              <div className="rounded-lg border bg-card p-6 space-y-5">
                <h3 className="font-semibold">Informations du profil</h3>

                {/* Avatar + identity */}
                <div className="flex items-center gap-4">
                  <div className="h-14 w-14 rounded-full bg-primary flex items-center justify-center text-primary-foreground text-xl font-bold shrink-0">
                    {initials}
                  </div>
                  <div className="min-w-0">
                    {usersLoading ? (
                      <Skeleton className="h-5 w-32 mb-1" />
                    ) : (
                      <p className="font-medium truncate">
                        {currentUserRecord?.name ?? user?.name ?? user?.email}
                      </p>
                    )}
                    <p className="text-sm text-muted-foreground truncate">{user?.email}</p>
                    <div className="mt-1.5 flex flex-wrap gap-1">
                      {user?.roles.map((r) => (
                        <Badge key={r} variant="secondary" className="capitalize text-xs">
                          {r}
                        </Badge>
                      ))}
                      {currentUserRecord?.department && (
                        <Badge variant="outline" className="text-xs">
                          {currentUserRecord.department}
                        </Badge>
                      )}
                    </div>
                  </div>
                </div>

                <Separator />

                {/* Name edit form */}
                <form onSubmit={handleProfileSave} className="space-y-4">
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                    <div className="space-y-1.5">
                      <Label htmlFor="name">Nom affiché</Label>
                      <Input id="name" {...profileForm.register("name")} />
                      {profileForm.formState.errors.name && (
                        <p className="text-xs text-destructive">
                          {profileForm.formState.errors.name.message}
                        </p>
                      )}
                    </div>
                    <div className="space-y-1.5">
                      <Label>Adresse email</Label>
                      <Input value={user?.email ?? ""} disabled className="opacity-60" />
                    </div>
                  </div>
                  <Button
                    type="submit"
                    disabled={updateUser.isPending || !currentUserRecord}
                    className="w-fit"
                  >
                    {profileSaved ? (
                      <>
                        <Check className="h-4 w-4 mr-2" /> Sauvegardé
                      </>
                    ) : (
                      <>
                        <Save className="h-4 w-4 mr-2" /> Sauvegarder
                      </>
                    )}
                  </Button>
                  {updateUser.error && (
                    <p className="text-xs text-destructive">
                      {updateUser.error instanceof Error
                        ? updateUser.error.message
                        : "Erreur lors de la mise à jour"}
                    </p>
                  )}
                </form>
              </div>

              {/* Password change */}
              <div className="rounded-lg border bg-card p-6 space-y-4">
                <h3 className="font-semibold">Changer le mot de passe</h3>
                <form onSubmit={handlePasswordSave} className="space-y-4">
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                    <div className="space-y-1.5">
                      <Label htmlFor="new-password">Nouveau mot de passe</Label>
                      <div className="relative">
                        <Input
                          id="new-password"
                          type={showPassword ? "text" : "password"}
                          {...passwordForm.register("password")}
                          autoComplete="new-password"
                        />
                        <button
                          type="button"
                          tabIndex={-1}
                          className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                          onClick={() => setShowPassword((v) => !v)}
                        >
                          {showPassword ? (
                            <EyeOff className="h-4 w-4" />
                          ) : (
                            <Eye className="h-4 w-4" />
                          )}
                        </button>
                      </div>
                      {passwordForm.formState.errors.password && (
                        <p className="text-xs text-destructive">
                          {passwordForm.formState.errors.password.message}
                        </p>
                      )}
                    </div>
                    <div className="space-y-1.5">
                      <Label htmlFor="confirm-password">Confirmer le mot de passe</Label>
                      <Input
                        id="confirm-password"
                        type="password"
                        {...passwordForm.register("confirmPassword")}
                        autoComplete="new-password"
                      />
                      {passwordForm.formState.errors.confirmPassword && (
                        <p className="text-xs text-destructive">
                          {passwordForm.formState.errors.confirmPassword.message}
                        </p>
                      )}
                    </div>
                  </div>
                  <Button
                    type="submit"
                    variant="outline"
                    disabled={updateUser.isPending || !currentUserRecord}
                    className="w-fit"
                  >
                    {passwordSaved ? (
                      <>
                        <Check className="h-4 w-4 mr-2" /> Mot de passe mis à jour
                      </>
                    ) : (
                      "Mettre à jour le mot de passe"
                    )}
                  </Button>
                </form>
              </div>
            </>
          )}

          {/* ── Sécurité ────────────────────────────────────────────────────── */}
          {activeSection === "security" && (
            <div className="space-y-4">
              <div className="rounded-lg border bg-card p-6 space-y-4">
                <h3 className="font-semibold">Session active</h3>
                <dl className="space-y-3">
                  <div className="flex justify-between text-sm">
                    <dt className="text-muted-foreground">Identifiant</dt>
                    <dd className="font-mono text-xs">{user?.id ?? "—"}</dd>
                  </div>
                  <Separator />
                  <div className="flex justify-between text-sm">
                    <dt className="text-muted-foreground">Email</dt>
                    <dd>{user?.email ?? "—"}</dd>
                  </div>
                  <Separator />
                  <div className="flex justify-between text-sm">
                    <dt className="text-muted-foreground">Rôle</dt>
                    <dd className="capitalize">{user?.roles[0] ?? "—"}</dd>
                  </div>
                  {currentUserRecord?.department && (
                    <>
                      <Separator />
                      <div className="flex justify-between text-sm">
                        <dt className="text-muted-foreground">Département</dt>
                        <dd>{currentUserRecord.department}</dd>
                      </div>
                    </>
                  )}
                  {tokenExpiry && (
                    <>
                      <Separator />
                      <div className="flex justify-between text-sm">
                        <dt className="text-muted-foreground">Expiration du token</dt>
                        <dd>{tokenExpiry}</dd>
                      </div>
                    </>
                  )}
                </dl>
              </div>

              <div className="rounded-lg border bg-card p-6 space-y-3">
                <h3 className="font-semibold">Méthode d&apos;authentification</h3>
                <div className="flex items-center gap-2 text-sm">
                  <div className="h-2 w-2 rounded-full bg-green-500 shrink-0" />
                  <span>Email + mot de passe · JWT HS256</span>
                </div>
                <p className="text-xs text-muted-foreground">
                  Les tokens sont signés avec HS256 et expirent automatiquement selon la
                  configuration du serveur. À la déconnexion, le token est supprimé du navigateur.
                </p>
              </div>
            </div>
          )}

          {/* ── Notifications ────────────────────────────────────────────────── */}
          {activeSection === "notifications" && (
            <div className="space-y-4">
              {/* Email notifications */}
              <div className="rounded-lg border bg-card p-6 space-y-4">
                <div className="flex items-center gap-2">
                  <Mail className="h-4 w-4 text-primary" />
                  <h3 className="font-semibold">Notifications par email</h3>
                </div>
                <p className="text-xs text-muted-foreground">
                  Recevez une copie de chaque notification (seuil dépassé, alerte 80 %) à l&apos;adresse
                  ci-dessous. Nécessite la configuration SMTP côté serveur
                  (<code className="text-xs bg-muted px-1 rounded">config.yaml → notifications.smtp</code>).
                </p>

                <div className="space-y-1.5">
                  <Label htmlFor="notif-email">Adresse email de notification</Label>
                  <div className="flex gap-2">
                    <Input
                      id="notif-email"
                      type="email"
                      value={notifEmail}
                      onChange={(e) => setNotifEmail(e.target.value)}
                      placeholder="equipe-finance@entreprise.com"
                      className="flex-1"
                    />
                    <Button
                      type="button"
                      variant="outline"
                      onClick={() => {
                        localStorage.setItem("veylant_notif_email", notifEmail);
                        window.dispatchEvent(new Event("veylant:notifications"));
                        setEmailSaved(true);
                        setTimeout(() => setEmailSaved(false), 2500);
                      }}
                    >
                      {emailSaved ? (
                        <>
                          <Check className="h-4 w-4 mr-1.5" /> Sauvegardé
                        </>
                      ) : (
                        <>
                          <Save className="h-4 w-4 mr-1.5" /> Enregistrer
                        </>
                      )}
                    </Button>
                  </div>
                  {notifEmail && (
                    <p className="text-xs text-green-600 dark:text-green-400 flex items-center gap-1 mt-1">
                      <Check className="h-3 w-3" />
                      Email configuré — les notifications seront envoyées à{" "}
                      <strong>{notifEmail}</strong>
                    </p>
                  )}
                  {!notifEmail && (
                    <p className="text-xs text-muted-foreground">
                      Laissez vide pour désactiver les notifications email.
                    </p>
                  )}
                </div>

                {notifEmail && (
                  <div className="flex items-center justify-between pt-1">
                    <p className="text-xs text-muted-foreground">
                      Supprimer l&apos;email configuré
                    </p>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="text-xs text-destructive hover:text-destructive h-7"
                      onClick={() => {
                        setNotifEmail("");
                        localStorage.removeItem("veylant_notif_email");
                        window.dispatchEvent(new Event("veylant:notifications"));
                      }}
                    >
                      Retirer
                    </Button>
                  </div>
                )}
              </div>

              {/* In-app notification toggles */}
              <div className="rounded-lg border bg-card p-6 space-y-5">
                <h3 className="font-semibold">Notifications dans l&apos;application</h3>
                <p className="text-xs text-muted-foreground -mt-2">
                  Ces préférences contrôlent la cloche de notifications dans l&apos;en-tête.
                </p>

                <div className="space-y-4">
                  <div className="flex items-start justify-between gap-4">
                    <div>
                      <p className="text-sm font-medium">Alertes budget</p>
                      <p className="text-xs text-muted-foreground mt-0.5">
                        Notification quand un seuil de dépense est atteint ou dépassé
                      </p>
                    </div>
                    <Switch
                      checked={notifBudget}
                      onCheckedChange={(v) => {
                        setNotifBudget(v);
                        localStorage.setItem("veylant_notif_budget", String(v));
                      }}
                    />
                  </div>
                  <Separator />
                  <div className="flex items-start justify-between gap-4">
                    <div>
                      <p className="text-sm font-medium">Alertes sécurité</p>
                      <p className="text-xs text-muted-foreground mt-0.5">
                        Notifications pour les requêtes de sensibilité critique ou haute
                      </p>
                    </div>
                    <Switch
                      checked={notifSecurity}
                      onCheckedChange={(v) => {
                        setNotifSecurity(v);
                        localStorage.setItem("veylant_notif_security", String(v));
                      }}
                    />
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* ── Apparence ───────────────────────────────────────────────────── */}
          {activeSection === "appearance" && (
            <div className="rounded-lg border bg-card p-6 space-y-5">
              <h3 className="font-semibold">Apparence</h3>

              <div className="space-y-4">
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <p className="text-sm font-medium">Mode sombre</p>
                    <p className="text-xs text-muted-foreground mt-0.5">
                      Basculer vers un thème sombre pour réduire la fatigue visuelle
                    </p>
                  </div>
                  <Switch checked={theme === "dark"} onCheckedChange={handleThemeChange} />
                </div>
                <Separator />
                <div>
                  <p className="text-sm font-medium">Langue de l&apos;interface</p>
                  <p className="text-xs text-muted-foreground mt-0.5">
                    Français (FR) — seule langue disponible en V1
                  </p>
                </div>
                <Separator />
                <div>
                  <p className="text-sm font-medium">Format de date</p>
                  <p className="text-xs text-muted-foreground mt-0.5">
                    JJ/MM/AAAA · HH:mm — locale française
                  </p>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
