import { useMutation, useQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
  Copy,
  Edit3,
  Key,
  Plus,
  RefreshCw,
  RotateCcw,
  Save,
  Trash2,
} from "lucide-react";
import * as React from "react";
import { Link } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import { commonStickyTableHeaderClass } from "../../../../common/ui/table";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "../../components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "../../components/ui/dialog";
import { Input } from "../../components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../../components/ui/table";
import {
  type ApiKeySummary,
  deleteApiKey,
  fetchApiKeys,
  rotateApiKeySecret,
  updateApiKeyScopes,
} from "../../lib/adminApi";
import { t } from "../../lib/i18n";
import { cn } from "../../lib/utils";
import { AVAILABLE_API_KEY_SCOPES } from "./apiKeyScopes";

function ApiKeyListPage() {
  const [editingKey, setEditingKey] = React.useState<ApiKeySummary | null>(
    null,
  );
  const [draftScopes, setDraftScopes] = React.useState<string[]>([]);
  const [rotatedSecret, setRotatedSecret] = React.useState<{
    key: ApiKeySummary;
    clientSecret: string;
  } | null>(null);

  const query = useQuery({
    queryKey: ["api-keys", { limit: 50, offset: 0 }],
    queryFn: () => fetchApiKeys(50, 0),
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => deleteApiKey(id),
    onSuccess: () => {
      query.refetch();
    },
  });

  const updateScopesMutation = useMutation({
    mutationFn: ({ id, scopes }: { id: string; scopes: string[] }) =>
      updateApiKeyScopes(id, { scopes }),
    onSuccess: () => {
      setEditingKey(null);
      setDraftScopes([]);
      query.refetch();
    },
  });

  const rotateSecretMutation = useMutation({
    mutationFn: (id: string) => rotateApiKeySecret(id),
    onSuccess: (data) => {
      setRotatedSecret({
        key: data.apiKey,
        clientSecret: data.clientSecret,
      });
      query.refetch();
    },
  });

  const errorMsg = (query.error as AxiosError<{ error?: string }>)?.response
    ?.data?.error;
  const fallbackError =
    !errorMsg && query.isError
      ? t(
          "msg.admin.api_keys.list.fetch_error",
          "API 키 목록 조회에 실패했습니다.",
        )
      : null;

  const items = query.data?.items ?? [];

  const handleDelete = (id: string, name: string) => {
    if (
      !window.confirm(
        t(
          "msg.admin.api_keys.list.delete_confirm",
          'API 키 "{{name}}"를 삭제할까요?',
          { name },
        ),
      )
    ) {
      return;
    }
    deleteMutation.mutate(id);
  };

  const openScopeEditor = (key: ApiKeySummary) => {
    setEditingKey(key);
    setDraftScopes(key.scopes);
  };

  const toggleDraftScope = (scopeId: string) => {
    setDraftScopes((current) =>
      current.includes(scopeId)
        ? current.filter((scope) => scope !== scopeId)
        : [...current, scopeId],
    );
  };

  const saveScopes = () => {
    if (!editingKey || draftScopes.length === 0) return;
    updateScopesMutation.mutate({ id: editingKey.id, scopes: draftScopes });
  };

  const handleRotateSecret = (key: ApiKeySummary) => {
    if (
      !window.confirm(
        t(
          "msg.admin.api_keys.list.rotate_confirm",
          'API 키 "{{name}}"의 Secret을 재발급할까요? 기존 Secret은 더 이상 사용할 수 없습니다.',
          { name: key.name },
        ),
      )
    ) {
      return;
    }
    rotateSecretMutation.mutate(key.id);
  };

  const copyRotatedSecret = () => {
    if (!rotatedSecret) return;
    navigator.clipboard.writeText(rotatedSecret.clientSecret);
  };

  return (
    <div className="space-y-6 flex flex-col h-[calc(100vh-theme(spacing.32))]">
      <PageHeader
        sticky
        titleAs="h2"
        icon={<Key size={20} />}
        title={t("ui.admin.api_keys.list.title", "API 키 관리 (M2M)")}
        description={t(
          "msg.admin.api_keys.list.subtitle",
          "서버 간 통신(Machine-to-Machine)을 위한 API 키를 발급하고 관리합니다.",
        )}
        actions={
          <>
            <Button
              type="button"
              variant="outline"
              onClick={() => query.refetch()}
              disabled={query.isFetching}
            >
              <RefreshCw size={16} />
              {t("ui.common.refresh", "새로고침")}
            </Button>
            <Button asChild>
              <Link to="/api-keys/new">
                <Plus size={16} />
                {t("ui.admin.api_keys.list.add", "API 키 생성")}
              </Link>
            </Button>
          </>
        }
      />

      <Card className="bg-[var(--color-panel)] flex-1 flex flex-col min-h-0 overflow-hidden">
        <CardHeader className="flex flex-row items-center justify-between flex-shrink-0">
          <div>
            <CardTitle className="text-lg font-bold flex items-center gap-2">
              {t("ui.admin.apikeys.registry.title", "API Key Registry")}
            </CardTitle>
            <CardDescription>
              {t(
                "msg.admin.apikeys.registry.count",
                "총 {{count}}개의 활성 키가 등록되어 있습니다.",
                { count: query.data?.items?.length ?? 0 },
              )}
            </CardDescription>
          </div>
        </CardHeader>
        <CardContent className="flex-1 flex flex-col min-h-0 pt-0">
          {(errorMsg || fallbackError) && (
            <div className="mb-4 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive flex-shrink-0">
              {errorMsg ?? fallbackError}
            </div>
          )}

          <div className="flex-1 rounded-md border overflow-hidden flex flex-col">
            <div className="flex-1 overflow-auto relative custom-scrollbar">
              <Table>
                <TableHeader className={commonStickyTableHeaderClass}>
                  <TableRow>
                    <TableHead>
                      {t("ui.admin.api_keys.list.table.name", "NAME")}
                    </TableHead>
                    <TableHead>
                      {t("ui.admin.api_keys.list.table.client_id", "CLIENT ID")}
                    </TableHead>
                    <TableHead>
                      {t("ui.admin.api_keys.list.table.scopes", "SCOPES")}
                    </TableHead>
                    <TableHead>
                      {t("ui.admin.api_keys.list.table.last_used", "LAST USED")}
                    </TableHead>
                    <TableHead className="text-right">
                      {t("ui.admin.api_keys.list.table.actions", "ACTIONS")}
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {query.isLoading && (
                    <TableRow>
                      <TableCell colSpan={5}>
                        {t("msg.common.loading", "로딩 중...")}
                      </TableCell>
                    </TableRow>
                  )}
                  {!query.isLoading && items.length === 0 && (
                    <TableRow>
                      <TableCell colSpan={5}>
                        {t(
                          "msg.admin.api_keys.list.empty",
                          "등록된 API 키가 없습니다.",
                        )}
                      </TableCell>
                    </TableRow>
                  )}
                  {items.map((key) => (
                    <TableRow key={key.id}>
                      <TableCell className="font-semibold">
                        <div className="flex items-center gap-2">
                          <Key
                            size={14}
                            className="text-[var(--color-muted)]"
                          />
                          {key.name}
                        </div>
                      </TableCell>
                      <TableCell>
                        <code>{key.client_id}</code>
                      </TableCell>
                      <TableCell>
                        <div className="flex flex-wrap gap-1">
                          {key.scopes.map((scope) => (
                            <Badge
                              key={scope}
                              variant="muted"
                              className="text-[10px]"
                            >
                              {scope}
                            </Badge>
                          ))}
                        </div>
                      </TableCell>
                      <TableCell>
                        {key.lastUsedAt
                          ? new Date(key.lastUsedAt).toLocaleString("ko-KR")
                          : t("ui.common.never", "Never")}
                      </TableCell>
                      <TableCell className="text-right">
                        <div className="flex flex-wrap justify-end gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => openScopeEditor(key)}
                          >
                            <Edit3 size={14} />
                            {t(
                              "ui.admin.api_keys.list.edit_scopes",
                              "권한 수정",
                            )}
                          </Button>
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => handleRotateSecret(key)}
                            disabled={rotateSecretMutation.isPending}
                          >
                            <RotateCcw size={14} />
                            {t(
                              "ui.admin.api_keys.list.rotate_secret",
                              "Secret 재발급",
                            )}
                          </Button>
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => handleDelete(key.id, key.name)}
                            disabled={deleteMutation.isPending}
                          >
                            <Trash2 size={14} />
                            {t("ui.common.delete", "삭제")}
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </div>
        </CardContent>
      </Card>

      <Dialog
        open={editingKey !== null}
        onOpenChange={() => setEditingKey(null)}
      >
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>
              {t("ui.admin.api_keys.list.edit_scopes", "권한 수정")}
            </DialogTitle>
            <DialogDescription>
              {editingKey
                ? t(
                    "msg.admin.api_keys.list.edit_scopes_desc",
                    "{{clientId}}의 CLIENT_ID는 유지하고 권한만 변경합니다.",
                    { clientId: editingKey.client_id },
                  )
                : null}
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-3 sm:grid-cols-2">
            {AVAILABLE_API_KEY_SCOPES.map((scope) => {
              const isSelected = draftScopes.includes(scope.id);
              return (
                <button
                  key={scope.id}
                  type="button"
                  onClick={() => toggleDraftScope(scope.id)}
                  className={cn(
                    "flex flex-col items-start gap-2 rounded-lg border-2 p-4 text-left transition-all",
                    isSelected
                      ? "border-primary bg-primary/5"
                      : "border-border bg-card hover:border-muted-foreground/30",
                  )}
                >
                  <span className="font-bold text-sm">
                    {t(scope.labelKey, scope.labelFallback)}
                  </span>
                  <span className="text-[11px] text-muted-foreground leading-snug">
                    {t(scope.descKey, scope.descFallback)}
                  </span>
                  <code className="text-[9px] font-mono opacity-60 uppercase tracking-tighter">
                    ID: {scope.id}
                  </code>
                </button>
              );
            })}
          </div>
          {draftScopes.length === 0 && (
            <p className="text-sm text-destructive">
              {t(
                "msg.admin.api_keys.create.scope_required",
                "최소 하나 이상의 권한을 선택해야 합니다.",
              )}
            </p>
          )}
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditingKey(null)}>
              {t("ui.common.cancel", "취소")}
            </Button>
            <Button
              onClick={saveScopes}
              disabled={
                updateScopesMutation.isPending || draftScopes.length === 0
              }
            >
              <Save size={16} />
              {t("ui.admin.api_keys.list.save_scopes", "권한 저장")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={rotatedSecret !== null}
        onOpenChange={() => setRotatedSecret(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {t(
                "ui.admin.api_keys.list.rotate_secret_done",
                "Secret 재발급 완료",
              )}
            </DialogTitle>
            <DialogDescription>
              {t(
                "msg.admin.api_keys.list.rotate_secret_notice",
                "새 Secret은 지금 한 번만 표시됩니다. CLIENT_ID는 변경되지 않았습니다.",
              )}
            </DialogDescription>
          </DialogHeader>
          {rotatedSecret && (
            <div className="space-y-4">
              <div className="space-y-2">
                <p className="text-xs font-bold text-muted-foreground">
                  CLIENT ID
                </p>
                <code className="block rounded-md bg-muted px-3 py-2 text-sm">
                  {rotatedSecret.key.client_id}
                </code>
              </div>
              <div className="space-y-2">
                <p className="text-xs font-bold text-muted-foreground">
                  X-Baron-Key-Secret
                </p>
                <div className="relative">
                  <Input
                    readOnly
                    value={rotatedSecret.clientSecret}
                    className="font-mono pr-12"
                  />
                  <Button
                    variant="ghost"
                    size="icon"
                    className="absolute right-1 top-1/2 -translate-y-1/2"
                    onClick={copyRotatedSecret}
                  >
                    <Copy size={16} />
                  </Button>
                </div>
              </div>
            </div>
          )}
          <DialogFooter>
            <Button onClick={() => setRotatedSecret(null)}>
              {t("ui.common.confirm", "확인")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

export default ApiKeyListPage;
