"use client";

import { useState, useMemo, useCallback, useEffect } from "react";
import { useSettings } from "@/app/lib/settings";
import {
  listApiKeys,
  createApiKey,
  updateApiKey,
  deleteApiKey,
  type ApiKeyRecord,
  ApiError,
} from "@/app/lib/api";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Badge } from "./ui/badge";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "./ui/dialog";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import { toast } from "sonner";
import {
  AlertCircle,
  BookOpen,
  Copy,
  Eye,
  EyeOff,
  KeyRound,
  Loader2,
  Plus,
  RefreshCw,
  ShieldAlert,
  Trash2,
} from "lucide-react";
import { Switch } from "./ui/switch";

function maskSecret(value: string, visible: boolean): string {
  if (visible) return value;
  if (!value) return "";
  return `${value.slice(0, 4)} ${"*".repeat(4)} ${"*".repeat(4)} ${"*".repeat(4)}`;
}

export default function ApiKeysPage() {
  const { baseUrl, apiKey, localBackupApiKey } = useSettings();
  const effectiveApiKey = apiKey || localBackupApiKey;
  const ctx = useMemo(
    () => ({ baseUrl, apiKey, localBackupApiKey }),
    [baseUrl, apiKey, localBackupApiKey],
  );

  const [keys, setKeys] = useState<ApiKeyRecord[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [createOpen, setCreateOpen] = useState(false);
  const [createName, setCreateName] = useState("");
  const [createDesc, setCreateDesc] = useState("");
  const [createClient, setCreateClient] = useState("");
  const [createLoading, setCreateLoading] = useState(false);

  const [createdSecret, setCreatedSecret] = useState<string | null>(null);
  const [showCreatedSecret, setShowCreatedSecret] = useState(false);
  const [showServiceRole, setShowServiceRole] = useState(false);

  const [deleteTarget, setDeleteTarget] = useState<ApiKeyRecord | null>(null);
  const [deleteLoading, setDeleteLoading] = useState(false);

  const [editTarget, setEditTarget] = useState<ApiKeyRecord | null>(null);
  const [editName, setEditName] = useState("");
  const [editDesc, setEditDesc] = useState("");
  const [editActive, setEditActive] = useState(true);
  const [editLoading, setEditLoading] = useState(false);

  const anonLegacy = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.public.demo";
  const serviceRoleLegacy = "sb_secret_01f4s**************";

  const loadKeys = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await listApiKeys(ctx);
      setKeys(result);
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to load API keys";
      setError(msg);
    } finally {
      setLoading(false);
    }
  }, [ctx]);

  useEffect(() => {
    if (effectiveApiKey) {
      loadKeys();
    } else {
      setLoading(false);
      setKeys([]);
      setError("Set your admin API key in Settings to manage keys");
    }
  }, [effectiveApiKey, loadKeys]);

  const handleCreate = async () => {
    if (!createName.trim()) {
      toast.error("Name is required");
      return;
    }
    setCreateLoading(true);
    try {
      const resp = await createApiKey(ctx, {
        name: createName.trim(),
        description: createDesc.trim() || undefined,
        client_name: createClient.trim() || undefined,
      });
      setCreateName("");
      setCreateDesc("");
      setCreateClient("");
      setCreateOpen(false);
      if (resp?.data?.secret) {
        setCreatedSecret(resp.data.secret);
        setShowCreatedSecret(true);
      }
      toast.success("API key created");
      await loadKeys();
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to create key";
      toast.error("Create failed", { description: msg });
    } finally {
      setCreateLoading(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    const id = deleteTarget.api_keys_id ?? String(deleteTarget.id);
    setDeleteLoading(true);
    try {
      await deleteApiKey(ctx, id);
      toast.success("API key deleted");
      setDeleteTarget(null);
      await loadKeys();
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to delete key";
      toast.error("Delete failed", { description: msg });
    } finally {
      setDeleteLoading(false);
    }
  };

  const openEdit = (key: ApiKeyRecord) => {
    setEditTarget(key);
    setEditName(key.name);
    setEditDesc(key.description ?? "");
    setEditActive(key.active !== false);
  };

  const handleEdit = async () => {
    if (!editTarget) return;
    const id = editTarget.api_keys_id ?? String(editTarget.id);
    setEditLoading(true);
    try {
      await updateApiKey(ctx, id, {
        name: editName.trim() || undefined,
        description: editDesc.trim() || undefined,
        active: editActive,
      });
      toast.success("API key updated");
      setEditTarget(null);
      await loadKeys();
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to update key";
      toast.error("Update failed", { description: msg });
    } finally {
      setEditLoading(false);
    }
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    toast.success("Copied to clipboard");
  };

  return (
    <div className="flex flex-1 min-h-0 overflow-auto">
      <div className="mx-auto w-full max-w-280 px-6 py-8">
        <div className="flex items-start justify-between gap-4 pb-6">
          <div>
            <h1 className="text-3xl font-semibold tracking-tight">API Keys</h1>
            <p className="mt-1 text-sm text-muted-foreground">
              Configure API keys to securely control access to your project.
            </p>
          </div>
          <Button variant="outline" size="sm">
            <BookOpen className="h-3.5 w-3.5" /> Docs
          </Button>
        </div>

        {error && (
          <div className="mb-4 flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3 text-xs text-destructive">
            <AlertCircle className="h-3.5 w-3.5" />
            {error}
          </div>
        )}

        {createdSecret && (
          <div className="mb-4 rounded-lg border border-primary/30 bg-primary/5 p-4">
            <p className="text-xs font-medium text-foreground">
              New key created. Copy this secret now.
            </p>
            <div className="mt-2 flex flex-wrap items-center gap-2">
              <code className="rounded border border-border bg-background px-3 py-1.5 font-mono text-xs text-foreground">
                {showCreatedSecret ? createdSecret : "**********************"}
              </code>
              <Button
                size="sm"
                variant="outline"
                onClick={() => setShowCreatedSecret((prev) => !prev)}
              >
                {showCreatedSecret ? (
                  <EyeOff className="h-3 w-3" />
                ) : (
                  <Eye className="h-3 w-3" />
                )}
                {showCreatedSecret ? "Hide" : "Reveal"}
              </Button>
              <Button
                size="sm"
                variant="outline"
                onClick={() => copyToClipboard(createdSecret)}
              >
                <Copy className="h-3 w-3" /> Copy
              </Button>
            </div>
          </div>
        )}

        <Tabs defaultValue="publishable-secret" className="space-y-0">
          <TabsList className="mb-5 h-10">
            <TabsTrigger value="publishable-secret">
              Publishable and secret API keys
            </TabsTrigger>
            <TabsTrigger value="legacy">
              Legacy anon, service_role API keys
            </TabsTrigger>
          </TabsList>

          <TabsContent value="publishable-secret" className="mt-0 space-y-5">
            <section className="rounded-lg border border-border bg-card p-5">
              <p className="text-sm font-semibold">Create API keys</p>
              <p className="mt-1 text-xs text-muted-foreground">
                Use keys to authenticate requests to your app.
              </p>
              <Button
                size="sm"
                className="mt-4"
                onClick={() => setCreateOpen(true)}
                disabled={!effectiveApiKey}
              >
                <Plus className="h-3 w-3" /> Create new API key
              </Button>
            </section>

            <section className="rounded-lg border border-border bg-card overflow-hidden">
              <div className="flex items-center justify-between border-b border-border px-5 py-4">
                <div>
                  <p className="text-xl font-semibold">Publishable keys</p>
                  <p className="text-sm text-muted-foreground">
                    This key is safe to use in a browser if you enabled Row
                    Level Security.
                  </p>
                </div>
                <div className="flex items-center gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={loadKeys}
                    disabled={loading || !effectiveApiKey}
                  >
                    {loading ? (
                      <Loader2 className="h-3 w-3 animate-spin" />
                    ) : (
                      <RefreshCw className="h-3 w-3" />
                    )}
                    Refresh
                  </Button>
                </div>
              </div>

              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-border bg-muted/30">
                    <th className="px-5 py-2 text-left text-body-sm font-medium text-muted-foreground">
                      NAME
                    </th>
                    <th className="px-5 py-2 text-left text-body-sm font-medium text-muted-foreground">
                      API KEY
                    </th>
                    <th className="px-5 py-2 text-left text-body-sm font-medium text-muted-foreground">
                      SCOPE
                    </th>
                    <th className="px-5 py-2 text-right text-body-sm font-medium text-muted-foreground">
                      ACTIONS
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {!loading && (!Array.isArray(keys) || keys.length === 0) && (
                    <tr>
                      <td
                        className="px-5 py-7 text-sm text-muted-foreground"
                        colSpan={4}
                      >
                        Publishable keys can be safely shared publicly.
                      </td>
                    </tr>
                  )}
                  {(Array.isArray(keys) ? keys : []).map((key) => {
                    const id = key?.api_keys_id ?? String(key?.id);
                    const display =
                      key?.public_id ?? `pk_live_${id?.slice(0, 12)}`;
                    return (
                      <tr
                        key={key?.id}
                        className="border-b border-border/60 last:border-b-0"
                      >
                        <td className="px-5 py-3">
                          <div className="font-medium">{key?.name}</div>
                          {key?.description ? (
                            <p className="text-xs text-muted-foreground">
                              {key?.description}
                            </p>
                          ) : null}
                        </td>
                        <td className="px-5 py-3">
                          <code className="font-mono text-xs text-muted-foreground">
                            {display}
                          </code>
                        </td>
                        <td className="px-5 py-3">
                          <Badge
                            variant={
                              key?.active !== false ? "success" : "destructive"
                            }
                            className="text-caption"
                          >
                            {key?.active !== false ? "active" : "inactive"}
                          </Badge>
                        </td>
                        <td className="px-5 py-3">
                          <div className="flex justify-end gap-2">
                            <Button
                              variant="outline"
                              size="sm"
                              onClick={() => openEdit(key)}
                            >
                              Edit
                            </Button>
                            <Button
                              variant="outline"
                              size="sm"
                              onClick={() => copyToClipboard(display)}
                            >
                              <Copy className="h-3 w-3" /> Copy
                            </Button>
                            <Button
                              variant="outline"
                              size="sm"
                              className="text-destructive"
                              onClick={() => setDeleteTarget(key)}
                            >
                              <Trash2 className="h-3 w-3" /> Remove
                            </Button>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </section>

            <section className="rounded-lg border border-border bg-card overflow-hidden">
              <div className="flex items-center justify-between border-b border-border px-5 py-4">
                <div>
                  <p className="text-xl font-semibold">Secret keys</p>
                  <p className="text-sm text-muted-foreground">
                    These keys allow privileged access to your project APIs.
                  </p>
                </div>
                <Button variant="outline" size="sm" disabled>
                  <Plus className="h-3 w-3" /> New secret key
                </Button>
              </div>
              <div className="px-5 py-8 text-center text-sm text-muted-foreground">
                No secret API keys found. Your project is not accessible via
                secret keys.
              </div>
            </section>
          </TabsContent>

          <TabsContent value="legacy" className="mt-0 space-y-5">
            <section className="rounded-lg border border-border bg-card overflow-hidden">
              <div className="border-b border-border px-5 py-4">
                <div className="flex items-center gap-2">
                  <Badge variant="secondary" className="font-mono text-xs">
                    anon
                  </Badge>
                  <Badge variant="outline" className="font-mono text-xs">
                    public
                  </Badge>
                </div>
                <div className="mt-3 flex flex-wrap items-center gap-2">
                  <code className="rounded border border-border bg-background px-3 py-2 font-mono text-xs text-muted-foreground">
                    {anonLegacy}
                  </code>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => copyToClipboard(anonLegacy)}
                  >
                    <Copy className="h-3 w-3" /> Copy
                  </Button>
                </div>
                <p className="mt-3 text-sm text-muted-foreground">
                  This key is safe to use in a browser if you have enabled Row
                  Level Security.
                </p>
              </div>

              <div className="px-5 py-4">
                <div className="flex items-center gap-2">
                  <Badge variant="secondary" className="font-mono text-xs">
                    service_role
                  </Badge>
                  <Badge variant="destructive" className="font-mono text-xs">
                    secret
                  </Badge>
                </div>
                <div className="mt-3 flex flex-wrap items-center gap-2">
                  <code className="rounded border border-border bg-background px-3 py-2 font-mono text-xs text-muted-foreground">
                    {maskSecret(serviceRoleLegacy, showServiceRole)}
                  </code>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => setShowServiceRole((prev) => !prev)}
                  >
                    {showServiceRole ? (
                      <EyeOff className="h-3 w-3" />
                    ) : (
                      <Eye className="h-3 w-3" />
                    )}
                    {showServiceRole ? "Hide" : "Reveal"}
                  </Button>
                </div>
                <p className="mt-3 text-sm text-muted-foreground">
                  This key can bypass Row Level Security. Never share it
                  publicly.
                </p>
              </div>
            </section>

            <section className="rounded-lg border border-border bg-card p-5">
              <p className="text-sm font-semibold">Disable legacy API keys</p>
              <p className="mt-1 text-sm text-muted-foreground">
                Make sure you no longer use your legacy API keys before
                proceeding.
              </p>
              <Button variant="outline" className="mt-4" disabled>
                <ShieldAlert className="h-3.5 w-3.5" /> Disable JWT-based API
                keys
              </Button>
            </section>
          </TabsContent>
        </Tabs>
      </div>

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create API Key</DialogTitle>
            <DialogDescription>
              The secret will only be shown once after creation.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div>
              <label className="text-xs text-muted-foreground">Name *</label>
              <Input
                value={createName}
                onChange={(e) => setCreateName(e.target.value)}
                placeholder="web"
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-xs text-muted-foreground">
                Description
              </label>
              <Input
                value={createDesc}
                onChange={(e) => setCreateDesc(e.target.value)}
                placeholder="Optional description"
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-xs text-muted-foreground">
                Client name (optional)
              </label>
              <Input
                value={createClient}
                onChange={(e) => setCreateClient(e.target.value)}
                placeholder="reporting"
                className="mt-1 font-mono"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>
              Cancel
            </Button>
            <Button
              onClick={handleCreate}
              disabled={createLoading || !createName.trim()}
            >
              {createLoading ? (
                <Loader2 className="h-3 w-3 animate-spin" />
              ) : (
                <KeyRound className="h-3 w-3" />
              )}
              Create
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={!!editTarget}
        onOpenChange={(open) => !open && setEditTarget(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Edit API Key</DialogTitle>
            <DialogDescription>
              Update key properties. The secret cannot be changed.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div>
              <label className="text-xs text-muted-foreground">Name</label>
              <Input
                value={editName}
                onChange={(e) => setEditName(e.target.value)}
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-xs text-muted-foreground">
                Description
              </label>
              <Input
                value={editDesc}
                onChange={(e) => setEditDesc(e.target.value)}
                className="mt-1"
              />
            </div>
            <Switch
              checked={editActive}
              onCheckedChange={setEditActive}
              size="sm"
              color={editActive ? "success" : "primary"}
              label={editActive ? "Active" : "Inactive"}
              description="Disabled keys reject all requests"
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditTarget(null)}>
              Cancel
            </Button>
            <Button onClick={handleEdit} disabled={editLoading}>
              {editLoading ? (
                <Loader2 className="h-3 w-3 animate-spin" />
              ) : null}
              Save
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={!!deleteTarget}
        onOpenChange={(open) => !open && setDeleteTarget(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete API Key</DialogTitle>
            <DialogDescription>
              Are you sure you want to delete{" "}
              <strong>{deleteTarget?.name}</strong>? This action cannot be
              undone.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Cancel
            </Button>
            <Button
              variant="destructive"
              onClick={handleDelete}
              disabled={deleteLoading}
            >
              {deleteLoading ? (
                <Loader2 className="h-3 w-3 animate-spin" />
              ) : null}
              Delete
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
