"use client";

import { useState, useMemo } from "react";
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Table,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
} from "@/components/ui/table";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Tooltip,
  TooltipTrigger,
  TooltipContent,
} from "@/components/ui/tooltip";
import { Progress } from "@/components/ui/progress";
import { Input } from "@/components/ui/input";
import { Search, KeyRound, Loader2, Filter, Lock } from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { useToast } from "@/components/ui/toast";
import type { AdminUser, PlanType } from "./types";
import { PLAN_LABELS, PLAN_TIERS } from "./types";

interface UserTableProps {
  users: AdminUser[];
  isLoading: boolean;
  onTierChange: (userId: string, plan: PlanType) => Promise<void>;
  onRevokeKeys: (userId: string, keyIds: string[]) => Promise<void>;
  onResetPassword: (userId: string, newPassword: string) => Promise<void>;
  isUpdating: boolean;
  isRevoking: boolean;
  isResettingPassword: boolean;
}

type TierFilter = "all" | "free" | "pro";

const statusConfig: Record<string, { label: string; dotClass: string; textClass: string }> = {
  active: {
    label: "Actif",
    dotClass: "bg-[oklch(0.59_0.16_145)]",
    textClass: "text-[oklch(0.45_0.12_145)]",
  },
  suspended: {
    label: "Suspendu",
    dotClass: "bg-destructive",
    textClass: "text-destructive",
  },
  pending: {
    label: "En attente",
    dotClass: "bg-[oklch(0.75_0.18_55)]",
    textClass: "text-[oklch(0.55_0.16_55)]",
  },
  cancelled: {
    label: "Annulé",
    dotClass: "bg-muted-foreground",
    textClass: "text-muted-foreground",
  },
};

function formatDate(dateString: string): string {
  try {
    const date = new Date(dateString);
    return date.toLocaleDateString(undefined, {
      day: "2-digit",
      month: "short",
      year: "numeric",
    });
  } catch {
    return dateString;
  }
}

export function UserTable({
  users,
  isLoading,
  onTierChange,
  onRevokeKeys,
  onResetPassword,
  isUpdating,
  isRevoking,
  isResettingPassword,
}: UserTableProps) {
  const toast = useToast();
  const [searchQuery, setSearchQuery] = useState("");
  const [tierFilter, setTierFilter] = useState<TierFilter>("all");
  const [revokedUsers, setRevokedUsers] = useState<Set<string>>(new Set());
  const [errorUserId, setErrorUserId] = useState<string | null>(null);
  const [pwdDialogUser, setPwdDialogUser] = useState<AdminUser | null>(null);
  const [newPwd, setNewPwd] = useState("");
  const [confirmPwd, setConfirmPwd] = useState("");

  const filteredUsers = useMemo(() => {
    let result = users;

    if (tierFilter !== "all") {
      result = result.filter((user) => PLAN_TIERS[user.plan] === tierFilter);
    }

    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase();
      result = result.filter((user) => user.email.toLowerCase().includes(query));
    }

    return result;
  }, [users, searchQuery, tierFilter]);

  const handleTierChange = async (userId: string, plan: PlanType) => {
    setErrorUserId(null);
    try {
      await onTierChange(userId, plan);
    } catch {
      setErrorUserId(userId);
    }
  };

  const handleRevokeKeys = async (userId: string, keyIds: string[]) => {
    setErrorUserId(null);
    try {
      await onRevokeKeys(userId, keyIds);
      setRevokedUsers((prev) => {
        const next = new Set(prev);
        next.add(userId);
        return next;
      });
      setTimeout(() => {
        setRevokedUsers((prev) => {
          const next = new Set(prev);
          next.delete(userId);
          return next;
        });
      }, 2000);
    } catch {
      setErrorUserId(userId);
    }
  };

  const activeCount = users.filter((u) => u.subscription_status === "active").length;
  const proCount = users.filter((u) => PLAN_TIERS[u.plan] === "pro").length;
  const freeCount = users.filter((u) => PLAN_TIERS[u.plan] === "free").length;

  if (isLoading) {
    return (
      <Card>
        <CardContent className="py-12">
          <div className="flex flex-col items-center justify-center gap-3">
            <Loader2 className="size-8 animate-spin text-muted-foreground" />
            <span className="text-sm text-muted-foreground">Chargement des utilisateurs...</span>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader className="pb-3">
        <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
          <div>
            <CardTitle className="text-base">Gestion des Utilisateurs</CardTitle>
            <CardDescription className="text-xs mt-1">
              {users.length} total
              <span className="mx-1.5 text-border">|</span>
              {activeCount} actifs
              <span className="mx-1.5 text-border">|</span>
              {proCount} pro
            </CardDescription>
          </div>
          <div className="flex flex-col gap-2 md:flex-row md:items-center">
            <div className="flex items-center gap-2">
              <Filter className="size-3.5 text-muted-foreground" />
              <Select value={tierFilter} onValueChange={(val: TierFilter) => setTierFilter(val)}>
                <SelectTrigger className="h-8 w-[100px] text-xs">
                  <SelectValue placeholder="Tier" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all" className="text-xs">Tous</SelectItem>
                  <SelectItem value="free" className="text-xs">Free</SelectItem>
                  <SelectItem value="pro" className="text-xs">Pro</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="relative w-full md:w-64">
              <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
              <Input
                placeholder="Rechercher par email..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                className="h-8 ps-8 text-xs"
              />
            </div>
          </div>
        </div>
      </CardHeader>

      <CardContent className="px-0 pb-0">
        <div className="border-t border-border overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow className="hover:bg-transparent">
                <TableHead className="h-8 ps-6 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Email
                </TableHead>
                <TableHead className="h-8 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Statut
                </TableHead>
                <TableHead className="h-8 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Stockage
                </TableHead>
                <TableHead className="h-8 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Plan
                </TableHead>
                <TableHead className="h-8 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Usage
                </TableHead>
                <TableHead className="h-8 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Clés
                </TableHead>
                <TableHead className="h-8 pe-6 text-end text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                  Actions
                </TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filteredUsers.map((user) => {
                const sConfig = statusConfig[user.subscription_status] || statusConfig.pending;
                const maxDocs = user.plan_limits?.docs_per_month || 100;
                const usagePercent = Math.min((user.docs_translated_this_month / maxDocs) * 100, 100);
                const isOverQuota = user.docs_translated_this_month > maxDocs;
                const justRevoked = revokedUsers.has(user.id);
                const hasError = errorUserId === user.id;
                const apiKeyIds = user.api_key_ids || [];

                return (
                  <TableRow key={user.id} className={`group ${hasError ? "bg-destructive/5" : ""}`}>
                    <TableCell className="ps-6 py-2">
                      <div className="flex flex-col gap-0.5">
                        <span className="text-xs font-medium text-foreground">
                          {user.email}
                        </span>
                        <span className="text-[10px] text-muted-foreground">
                          Créé le {formatDate(user.created_at)}
                        </span>
                      </div>
                    </TableCell>

                    <TableCell className="py-2">
                      <div className="flex items-center gap-1.5">
                        <span className={`size-1.5 rounded-full ${sConfig.dotClass}`} />
                        <span className={`text-xs font-medium ${sConfig.textClass}`}>
                          {sConfig.label}
                        </span>
                      </div>
                    </TableCell>

                    <TableCell className="py-2">
                      <Badge
                        variant="outline"
                        className={`text-[9px] font-normal ${
                          user.storage === "json_file"
                            ? "border-amber-500/40 text-amber-600"
                            : "border-muted-foreground/30 text-muted-foreground"
                        }`}
                        title={
                          user.storage === "json_file"
                            ? "Compte uniquement dans data/users.json (legacy)"
                            : "Compte en base SQLite / PostgreSQL"
                        }
                      >
                        {user.storage === "json_file" ? "JSON" : "Base"}
                      </Badge>
                    </TableCell>

                    <TableCell className="py-2">
                      <Select
                        value={user.plan}
                        onValueChange={(val: PlanType) => handleTierChange(user.id, val)}
                        disabled={isUpdating}
                      >
                        <SelectTrigger
                          size="sm"
                          className={`h-7 w-[90px] text-xs font-semibold uppercase tracking-wider ${
                            PLAN_TIERS[user.plan] === "pro"
                              ? "border-[oklch(0.59_0.16_145)/30] bg-[oklch(0.59_0.16_145)/10] text-[oklch(0.45_0.12_145)]"
                              : "border-border text-muted-foreground"
                          }`}
                        >
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="free" className="text-xs">Free</SelectItem>
                          <SelectItem value="starter" className="text-xs">Starter</SelectItem>
                          <SelectItem value="pro" className="text-xs">Pro</SelectItem>
                          <SelectItem value="business" className="text-xs">Business</SelectItem>
                          <SelectItem value="enterprise" className="text-xs">Enterprise</SelectItem>
                        </SelectContent>
                      </Select>
                    </TableCell>

                    <TableCell className="py-2">
                      <div className="flex w-28 flex-col gap-1">
                        <div className="flex items-center justify-between">
                          <span
                            className={`text-[10px] font-medium tabular-nums ${
                              isOverQuota ? "text-destructive" : "text-muted-foreground"
                            }`}
                          >
                            {user.docs_translated_this_month} / {maxDocs}
                          </span>
                          {isOverQuota && (
                            <Badge
                              variant="outline"
                              className="h-4 border-destructive/30 bg-destructive/5 px-1 text-[9px] text-destructive"
                            >
                              Dépassement
                            </Badge>
                          )}
                        </div>
                        <Progress
                          value={usagePercent}
                          className={`h-1 bg-muted ${
                            isOverQuota
                              ? "[&>[data-slot=progress-indicator]]:bg-destructive"
                              : usagePercent > 80
                                ? "[&>[data-slot=progress-indicator]]:bg-[oklch(0.75_0.18_55)]"
                                : "[&>[data-slot=progress-indicator]]:bg-[oklch(0.59_0.16_145)]"
                          }`}
                        />
                      </div>
                    </TableCell>

                    <TableCell className="py-2">
                      <span className="text-xs tabular-nums text-muted-foreground">
                        {user.api_keys_count ?? 0}
                      </span>
                    </TableCell>

                    <TableCell className="pe-6 py-2 text-end">
                      <div className="flex justify-end gap-1.5">
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button
                              variant="outline"
                              size="sm"
                              className="h-7 gap-1 px-2 text-[10px] border-primary/30 text-primary hover:bg-primary/10"
                              onClick={() => {
                                setPwdDialogUser(user);
                                setNewPwd("");
                                setConfirmPwd("");
                              }}
                              disabled={isResettingPassword}
                            >
                              <Lock className="size-3" />
                              MDP
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent className="text-xs">
                            Définir un nouveau mot de passe (sans e-mail)
                          </TooltipContent>
                        </Tooltip>
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button
                              variant="outline"
                              size="sm"
                              className={`h-7 gap-1 px-2 text-[10px] ${
                                justRevoked
                                  ? "border-[oklch(0.59_0.16_145/0.3)] text-[oklch(0.45_0.12_145)]"
                                  : hasError
                                    ? "border-destructive text-destructive"
                                    : "border-destructive/30 text-destructive hover:bg-destructive/10 hover:text-destructive"
                              }`}
                              onClick={() => handleRevokeKeys(user.id, apiKeyIds)}
                              disabled={apiKeyIds.length === 0 || isRevoking || justRevoked}
                            >
                              <KeyRound className="size-3" />
                              {justRevoked ? "Révoquées" : "Révoquer"}
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent className="text-xs">
                            {apiKeyIds.length === 0
                              ? "Aucune clé active"
                              : `Révoquer ${apiKeyIds.length} clé${apiKeyIds.length > 1 ? "s" : ""} active${apiKeyIds.length > 1 ? "s" : ""}`}
                          </TooltipContent>
                        </Tooltip>
                      </div>
                    </TableCell>
                  </TableRow>
                );
              })}

              {filteredUsers.length === 0 && (
                <TableRow>
                  <TableCell
                    colSpan={7}
                    className="py-8 text-center text-xs text-muted-foreground"
                  >
                    {searchQuery || tierFilter !== "all"
                      ? "Aucun utilisateur ne correspond à vos filtres."
                      : "Aucun utilisateur trouvé."}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>

        <div className="flex items-center justify-between border-t border-border px-6 py-2">
          <span className="text-[10px] text-muted-foreground">
            Affichage de {filteredUsers.length} sur {users.length} utilisateurs
          </span>
          {tierFilter !== "all" && (
            <Badge variant="outline" className="text-[10px]">
              Filtre: {tierFilter === "pro" ? "Pro" : "Free"} ({tierFilter === "pro" ? proCount : freeCount})
            </Badge>
          )}
        </div>
      </CardContent>

      <Dialog open={!!pwdDialogUser} onOpenChange={(o) => !o && setPwdDialogUser(null)}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Nouveau mot de passe</DialogTitle>
            <p className="text-xs text-muted-foreground">
              {pwdDialogUser?.email} — minimum 8 caractères.
            </p>
          </DialogHeader>
          <div className="grid gap-3 py-2">
            <div className="space-y-1.5">
              <label className="text-xs text-muted-foreground">Nouveau mot de passe</label>
              <Input
                type="password"
                autoComplete="new-password"
                value={newPwd}
                onChange={(e) => setNewPwd(e.target.value)}
                className="h-9 text-sm"
              />
            </div>
            <div className="space-y-1.5">
              <label className="text-xs text-muted-foreground">Confirmation</label>
              <Input
                type="password"
                autoComplete="new-password"
                value={confirmPwd}
                onChange={(e) => setConfirmPwd(e.target.value)}
                className="h-9 text-sm"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setPwdDialogUser(null)}>
              Annuler
            </Button>
            <Button
              size="sm"
              disabled={isResettingPassword || newPwd.length < 8}
              onClick={async () => {
                if (!pwdDialogUser) return;
                if (newPwd !== confirmPwd) {
                  toast.error({ title: "Les mots de passe ne correspondent pas" });
                  return;
                }
                try {
                  await onResetPassword(pwdDialogUser.id, newPwd);
                  toast.success({ title: "Mot de passe mis à jour" });
                  setPwdDialogUser(null);
                  setNewPwd("");
                  setConfirmPwd("");
                } catch (e) {
                  toast.error({
                    title: "Échec",
                    description: e instanceof Error ? e.message : "Erreur",
                  });
                }
              }}
            >
              {isResettingPassword ? <Loader2 className="size-4 animate-spin" /> : "Enregistrer"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
