"use client";

import { useState } from "react";
import useSWR from "swr";
import { motion } from "framer-motion";
import {
  Key,
  Plus,
  Search,
  RefreshCw,
  Pencil,
  Power,
  Trash2,
  Eye,
} from "lucide-react";
import { api } from "@/lib/api";
import { GET_API_KEYS } from "@/lib/api-endpoints";
import { extractApiError } from "@/lib/error";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { TableCard } from "@/components/shared/CustomCards";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { TableBodyStates } from "@/components/shared/TableBodyStates";
import { ConfirmationDialog } from "@/components/shared/ConfirmationDialog";
import { useDeleteConfirmation } from "@/hooks/useDeleteConfirmation";
import { AddApiKeyModal } from "@/components/features/api-keys/AddApiKeyModal";
import { EditApiKeyModal } from "@/components/features/api-keys/EditApiKeyModal";
import { RegenerateApiKeyModal } from "@/components/features/api-keys/RegenerateApiKeyModal";
import { RevealApiKeyDialog } from "@/components/features/api-keys/RevealApiKeyDialog";
import { ApiKey, ApiKeyScope } from "@/lib/types/api-key";
import { toast } from "sonner";

const SCOPE_LABELS: Record<ApiKeyScope, string> = {
  "public:read": "Public Read",
  "internal:write": "Internal Write",
};

function formatDate(iso: string | null): string {
  if (!iso) return "-";
  return new Date(iso).toLocaleString("id-ID", {
    dateStyle: "short",
    timeStyle: "short",
  });
}

export default function ApiKeysPage() {
  const [searchQuery, setSearchQuery] = useState("");
  const [showAddModal, setShowAddModal] = useState(false);
  const [editingKey, setEditingKey] = useState<ApiKey | null>(null);
  const [regeneratingKey, setRegeneratingKey] = useState<ApiKey | null>(null);
  const [togglingKey, setTogglingKey] = useState<ApiKey | null>(null);
  const [isToggling, setIsToggling] = useState(false);
  const [toggleError, setToggleError] = useState<string | null>(null);
  const [revealingKey, setRevealingKey] = useState<ApiKey | null>(null);

  const { data, isLoading, mutate } = useSWR<{
    data: ApiKey[];
  }>(GET_API_KEYS(1, 100, searchQuery));
  const apiKeys = data?.data ?? [];

  const deleteConfirmation = useDeleteConfirmation({
    onDelete: async (id) => {
      await api.delete(`/api-keys/${id}`);
      mutate();
    },
    successMessage: "API key berhasil dihapus!",
    errorMessage: "Gagal menghapus API key.",
  });

  const filtered = apiKeys.filter((k) =>
    k.name.toLowerCase().includes(searchQuery.toLowerCase())
  );

  const handleToggleActive = async () => {
    if (!togglingKey) return;
    setIsToggling(true);
    setToggleError(null);
    try {
      await api.put(`/api-keys/${togglingKey.id}`, {
        is_active: !togglingKey.is_active,
      });
      toast.success(
        togglingKey.is_active
          ? `API key "${togglingKey.name}" dinonaktifkan.`
          : `API key "${togglingKey.name}" diaktifkan.`
      );
      mutate();
      setTogglingKey(null);
    } catch (err: any) {
      setToggleError(extractApiError(err, "Gagal mengubah status API key."));
    } finally {
      setIsToggling(false);
    }
  };

  return (
    <div className="space-y-6">
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
        <div>
          <h1 className="text-2xl font-bold text-gray-900 flex items-center gap-2">
            <Key className="w-6 h-6" />
            Manajemen API Key
          </h1>
          <p className="text-gray-500 text-sm">
            Kelola API key untuk klien eksternal (muscab, hipmi_web, integrasi).
            Hanya Superadmin yang bisa mengakses halaman ini.
          </p>
        </div>
        <Button
          className="gap-2 w-full md:w-auto"
          onClick={() => setShowAddModal(true)}
        >
          <Plus className="w-4 h-4" /> Tambah API Key
        </Button>
      </div>

      <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }}>
        <TableCard className="p-6">
          <div className="flex justify-between items-center mb-6">
            <div className="relative w-full md:w-80">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground w-4 h-4" />
              <Input
                placeholder="Cari nama API key..."
                className="pl-9 bg-slate-50 focus-visible:ring-primary"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
              />
            </div>
          </div>

          <div className="overflow-x-auto">
            <Table>
              <TableHeader className="bg-slate-50">
                <TableRow>
                  <TableHead>Nama</TableHead>
                  <TableHead>Key (masked)</TableHead>
                  <TableHead>Scope</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Terakhir Dipakai</TableHead>
                  <TableHead>Dibuat</TableHead>
                  <TableHead className="text-right">Aksi</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                <TableBodyStates
                  isLoading={isLoading}
                  isEmpty={filtered.length === 0}
                  colSpan={7}
                  emptyMessage="Tidak ada API key ditemukan."
                />

                {!isLoading &&
                  filtered.map((key) => (
                    <TableRow key={key.id}>
                      <TableCell className="font-medium text-foreground">
                        {key.name}
                      </TableCell>
                      <TableCell>
                        <code className="text-xs px-2 py-1 bg-slate-50 border border-slate-200 rounded font-mono">
                          {key.key_prefix}…
                        </code>
                      </TableCell>
                      <TableCell>
                        <div className="flex flex-wrap gap-1">
                          {key.scopes.map((scope) => (
                            <Badge
                              key={scope}
                              variant="secondary"
                              className="font-mono text-[10px]"
                            >
                              {SCOPE_LABELS[scope]}
                            </Badge>
                          ))}
                        </div>
                      </TableCell>
                      <TableCell>
                        {key.is_active ? (
                          <span className="px-2.5 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-700">
                            Aktif
                          </span>
                        ) : (
                          <span className="px-2.5 py-1 text-xs font-semibold rounded-full bg-slate-100 text-slate-600">
                            Nonaktif
                          </span>
                        )}
                      </TableCell>
                      <TableCell className="text-xs text-muted-foreground">
                        {formatDate(key.last_used_at)}
                      </TableCell>
                      <TableCell className="text-xs text-muted-foreground">
                        {formatDate(key.created_at)}
                      </TableCell>
                      <TableCell className="text-right">
                        <div className="flex justify-end gap-1">
                          <Button
                            variant="ghost"
                            size="icon"
                            title="Lihat key (tercatat di audit log)"
                            onClick={() => setRevealingKey(key)}
                            disabled={!key.is_active}
                          >
                            <Eye className="w-4 h-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            title="Regenerate key"
                            onClick={() => setRegeneratingKey(key)}
                            disabled={!key.is_active}
                          >
                            <RefreshCw className="w-4 h-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            title="Edit"
                            onClick={() => setEditingKey(key)}
                          >
                            <Pencil className="w-4 h-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            title={key.is_active ? "Nonaktifkan" : "Aktifkan"}
                            onClick={() => setTogglingKey(key)}
                          >
                            <Power
                              className={`w-4 h-4 ${
                                key.is_active ? "text-amber-600" : "text-green-600"
                              }`}
                            />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="text-destructive hover:text-destructive hover:bg-destructive/10"
                            title="Hapus"
                            onClick={() => deleteConfirmation.openDelete(key.id)}
                          >
                            <Trash2 className="w-4 h-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
              </TableBody>
            </Table>
          </div>
        </TableCard>
      </motion.div>

      <AddApiKeyModal
        open={showAddModal}
        onOpenChange={setShowAddModal}
        onSaved={() => mutate()}
        existingNames={apiKeys.map((k) => k.name)}
      />

      <EditApiKeyModal
        open={!!editingKey}
        onOpenChange={(next) => !next && setEditingKey(null)}
        apiKey={editingKey}
        onSaved={() => mutate()}
        existingNames={apiKeys.map((k) => k.name)}
      />

      <RegenerateApiKeyModal
        open={!!regeneratingKey}
        onOpenChange={(next) => !next && setRegeneratingKey(null)}
        apiKey={regeneratingKey}
        onSaved={() => mutate()}
      />

      <ConfirmationDialog
        open={deleteConfirmation.isOpen}
        onOpenChange={deleteConfirmation.setIsOpen}
        title="Hapus API Key"
        description="Apakah Anda yakin ingin menghapus API key ini? Tindakan ini tidak dapat dibatalkan. Klien yang masih menggunakan key ini akan langsung mendapat error 401."
        confirmText="Hapus"
        variant="danger"
        isLoading={deleteConfirmation.isDeleting}
        error={deleteConfirmation.error}
        onConfirm={deleteConfirmation.confirmDelete}
      />

      <ConfirmationDialog
        open={!!togglingKey}
        onOpenChange={(next) => {
          if (!next) {
            setTogglingKey(null);
            setToggleError(null);
          }
        }}
        title={togglingKey?.is_active ? "Nonaktifkan API Key" : "Aktifkan API Key"}
        description={
          togglingKey?.is_active
            ? `API key "${togglingKey?.name}" akan dinonaktifkan. Klien yang menggunakan key ini akan mendapat error 401 sampai diaktifkan kembali.`
            : `API key "${togglingKey?.name}" akan diaktifkan kembali dan dapat digunakan klien.`
        }
        confirmText={togglingKey?.is_active ? "Nonaktifkan" : "Aktifkan"}
        variant={togglingKey?.is_active ? "danger" : "default"}
        isLoading={isToggling}
        error={toggleError}
        onConfirm={handleToggleActive}
      />

      <RevealApiKeyDialog
        open={!!revealingKey}
        onOpenChange={(next) => !next && setRevealingKey(null)}
        apiKey={revealingKey}
      />
    </div>
  );
}
