"use client";

import * as React from "react";
import Link from "next/link";
import { useTransition } from "react";
import { toast } from "sonner";
import { ArrowRight, Check, Copy, Eye, EyeOff, KeyRound, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { formatDateTime } from "@/lib/format";
import { cn } from "@/lib/utils";
import { accountTexts } from "@/lib/i18n/account";
import { generateApiKeyAction } from "@/lib/actions/account";
import { maskApiKey } from "@/lib/validation/account";

export function ApiKeyCard({
  apiKey: initialKey,
  createdAt: initialCreatedAt,
}: {
  apiKey: string | null;
  createdAt: string | null;
}) {
  const [apiKey, setApiKey] = React.useState(initialKey);
  const [createdAt, setCreatedAt] = React.useState(initialCreatedAt);
  const [revealed, setRevealed] = React.useState(false);
  const [copied, setCopied] = React.useState(false);
  const [confirming, setConfirming] = React.useState(false);
  const [pending, startTransition] = useTransition();

  async function copyKey() {
    if (!apiKey) return;
    try {
      await navigator.clipboard.writeText(apiKey);
      setCopied(true);
      toast.success(accountTexts.copied);
      window.setTimeout(() => setCopied(false), 2000);
    } catch {
      toast.error(accountTexts.copyFailed);
    }
  }

  function generate() {
    setConfirming(false);
    startTransition(async () => {
      const result = await generateApiKeyAction();
      if (result?.ok) {
        const data = result.data as { apiKey: string; createdAt: string } | undefined;
        if (data) {
          setApiKey(data.apiKey);
          setCreatedAt(data.createdAt);
          setRevealed(true);
        }
        toast.success(accountTexts.keyGenerated);
      } else {
        toast.error(result && !result.ok ? result.error : accountTexts.errGeneric);
      }
    });
  }

  return (
    <section className="rounded-2xl border bg-card shadow-sm">
      <header className="flex items-start gap-3 border-b p-5">
        <span className="mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
          <KeyRound className="size-[18px]" />
        </span>
        <div className="min-w-0 space-y-0.5">
          <h2 className="font-display text-base font-semibold">{accountTexts.apiTitle}</h2>
          <p className="text-sm leading-relaxed text-muted-foreground">
            {accountTexts.apiHint}
          </p>
        </div>
      </header>

      <div className="space-y-4 p-5">
        <div className="space-y-1.5">
          <p className="text-sm font-medium">{accountTexts.apiKeyLabel}</p>
          {apiKey ? (
            <div className="flex flex-wrap items-center gap-2">
              <code className="min-w-0 flex-1 overflow-x-auto whitespace-nowrap rounded-lg border bg-muted/50 px-3 py-2 font-mono text-sm">
                {revealed ? apiKey : maskApiKey(apiKey)}
              </code>
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={() => setRevealed((v) => !v)}
                aria-label={revealed ? accountTexts.hide : accountTexts.reveal}
              >
                {revealed ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
                <span className="hidden sm:inline">
                  {revealed ? accountTexts.hide : accountTexts.reveal}
                </span>
              </Button>
              <Button type="button" variant="outline" size="sm" onClick={copyKey}>
                {copied ? (
                  <Check className="size-4 text-emerald-500" />
                ) : (
                  <Copy className="size-4" />
                )}
                <span className="hidden sm:inline">{accountTexts.copy}</span>
              </Button>
            </div>
          ) : (
            <p className="rounded-lg border border-dashed px-3 py-3 text-sm text-muted-foreground">
              {accountTexts.apiKeyNone}
            </p>
          )}
          {createdAt ? (
            <p className="text-xs text-muted-foreground">
              {accountTexts.apiKeyCreated}:{" "}
              <span className="font-mono">{formatDateTime(createdAt)}</span>
            </p>
          ) : null}
        </div>

        {confirming ? (
          <div className="space-y-3 rounded-xl border border-amber-300/60 bg-amber-50 p-4 text-xs leading-relaxed text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200">
            <p>{accountTexts.regenerateWarning}</p>
            <div className="flex items-center gap-2">
              <Button type="button" size="sm" onClick={generate} disabled={pending}>
                {pending ? accountTexts.generating : accountTexts.generateKey}
              </Button>
              <Button
                type="button"
                size="sm"
                variant="ghost"
                onClick={() => setConfirming(false)}
                disabled={pending}
              >
                Cancel
              </Button>
            </div>
          </div>
        ) : (
          <div className="flex flex-wrap items-center gap-3">
            <Button
              type="button"
              variant={apiKey ? "outline" : "default"}
              size="sm"
              disabled={pending}
              onClick={() => (apiKey ? setConfirming(true) : generate())}
            >
              <RefreshCw className={cn("size-4", pending && "animate-spin")} />
              {apiKey ? accountTexts.generateKey : accountTexts.generateFirstKey}
            </Button>
            <Link
              href="/api"
              className="inline-flex items-center gap-1 text-xs font-medium text-primary transition-colors hover:text-primary/80"
            >
              {accountTexts.apiDocsLink}
              <ArrowRight className="size-3.5" />
            </Link>
          </div>
        )}
      </div>
    </section>
  );
}

export default ApiKeyCard;
