"use client";

/**
 * ModelCard — 模型卡片（雲端版）
 *
 * 來源：`local-tool/frontend/src/components/models/model-card.tsx`（雲端版精簡）
 *
 * 改動：
 *   - 欄位對齊 api-spec §4 的 Model（targetChip / fileSize / source / status / createdAt）
 *     不再用 local-tool 的 accuracy / fps / supportedHardware（那些是內建 preset 的附加 metadata）
 *   - 狀態 Badge 對齊 flow-model-upload §5.4（uploading / scanning / ready / rejected）
 *   - 比較模式（Checkbox）保留，但預設關閉（雛形不做 comparison）
 *   - Phase 0.9：可下載的 model（converted + ready）顯示「下載」按鈕，走 FAA delegated download。
 *     整張卡片包在 <Link> 裡 → 下載按鈕需 preventDefault + stopPropagation 避免觸發導航。
 */

import { DownloadIcon } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Spinner } from "@/components/ui/spinner";
import { useT } from "@/lib/i18n/context";
import { cn } from "@/lib/utils";
import {
  isModelDownloadable,
  useModelStore,
  type ModelStatus,
  type ModelSummary,
} from "@/stores/model-store";

interface ModelCardProps {
  model: ModelSummary;
}

/** 狀態 Badge variant 映射（對齊 flow-model-upload §5.4） */
const STATUS_VARIANT: Record<ModelStatus, { variant: "default" | "secondary" | "destructive" | "outline"; key: string }> = {
  uploading: { variant: "secondary", key: "models.status.uploading" },
  scanning: { variant: "secondary", key: "models.status.scanning" },
  ready: { variant: "default", key: "models.status.ready" },
  rejected: { variant: "destructive", key: "models.status.rejected" },
};

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
}

export function ModelCard({ model }: ModelCardProps) {
  const t = useT();
  const statusMeta = STATUS_VARIANT[model.status];

  const downloadModel = useModelStore((s) => s.downloadModel);
  // per-card loading：只在「下載中的是這張卡」時顯示 spinner。
  const isDownloading = useModelStore((s) => s.downloadingId === model.id);
  // 任一卡片下載中時，其他卡片的下載按鈕 disable（store 同時只允許一個下載）。
  const isAnyDownloading = useModelStore((s) => s.downloadingId !== null);
  const [localBusy, setLocalBusy] = useState(false);

  const downloadable = isModelDownloadable(model);

  const handleDownload = async (e: React.MouseEvent) => {
    // 整張卡片是 <Link> → 阻止冒泡到外層導航。
    e.preventDefault();
    e.stopPropagation();
    if (localBusy || isAnyDownloading) return;

    setLocalBusy(true);
    const result = await downloadModel(model);
    setLocalBusy(false);

    if (result.ok) {
      toast.success(t("models.download.toast.start"), {
        description: t("models.download.toast.hint"),
      });
    } else {
      // 用 backend code 對應 i18n；找不到對應 key 時 t() 回 key 本身，仍退化到 unknown。
      const key = `models.download.error.${result.code}`;
      const desc = t(key);
      toast.error(t("models.download.error.title"), {
        description: desc === key ? t("models.download.error.unknown") : desc,
      });
    }
  };

  return (
    <Link href={`/models/${model.id}`} data-testid="model-card">
      <Card
        className={cn(
          "hover:bg-accent/40 h-full cursor-pointer transition-shadow hover:shadow-md",
        )}
      >
        <CardHeader className="pb-3">
          <div className="flex items-start justify-between gap-2">
            <CardTitle className="text-base leading-tight">{model.name}</CardTitle>
            <Badge variant={statusMeta.variant} className="shrink-0 text-xs">
              {t(statusMeta.key)}
            </Badge>
          </div>
          <div className="flex flex-wrap gap-1">
            <Badge variant="outline" className="text-xs">
              {model.targetChip.toUpperCase()}
            </Badge>
            {model.source === "preset" && (
              <Badge variant="secondary" className="text-xs">
                {t("models.source.preset")}
              </Badge>
            )}
            {model.source === "converted" && (
              <Badge variant="secondary" className="text-xs">
                {t("models.source.converted")}
              </Badge>
            )}
            {model.category && (
              <Badge variant="outline" className="text-xs">
                {model.category}
              </Badge>
            )}
          </div>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-2 gap-2 text-sm">
            <div>
              <p className="text-muted-foreground">{t("models.size")}</p>
              <p className="font-medium">{formatFileSize(model.fileSize)}</p>
            </div>
            <div>
              <p className="text-muted-foreground">{t("models.createdAt")}</p>
              <p className="font-medium">
                {model.createdAt
                  ? new Date(model.createdAt).toLocaleDateString()
                  : "—"}
              </p>
            </div>
          </div>
          {downloadable && (
            <div className="mt-3 flex justify-end">
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={handleDownload}
                disabled={isAnyDownloading || localBusy}
                aria-label={t("models.action.download.aria")}
                data-testid="model-card-download"
              >
                {isDownloading || localBusy ? (
                  <>
                    <Spinner size="sm" label={t("models.action.downloading")} />
                    {t("models.action.downloading")}
                  </>
                ) : (
                  <>
                    <DownloadIcon aria-hidden />
                    {t("models.action.download")}
                  </>
                )}
              </Button>
            </div>
          )}
        </CardContent>
      </Card>
    </Link>
  );
}
