"use client";

/**
 * ModelProfileClient — 模型 profile 頁（owner / 公開雙態）
 *
 * 對齊設計規格 §6 + API 契約 §2（GET /:id/profile）。取代舊的 owner-only detail：
 * 用 `GET /api/models/:id/profile` 取詳情（後端依身份裁剪 + 權限檢查），依 `myAccess`
 * 決定渲染 owner 版或公開 / 共享版。
 *
 * 雙態差異（設計規格 §6.2）：
 *   - owner 版（myAccess==='owner'）：下載（若可）+ 刪除 + 【新增】公開設定 Dialog
 *   - 公開 / 共享版：僅下載（canDownload 為 true 時）；隱藏刪除 / 公開設定；顯示 ModelOwnerBar
 *
 * 錯誤（契約 §2）：無可見性 → 404（防 enumeration）→ 全頁「找不到 / 無權限」EmptyState。
 *
 * 下載沿用既有 FAA delegated download（lib/api/model-download），走同一 endpoint
 * （契約 §3：download 已加共享權限檢查）。
 */

import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ArrowLeft, DownloadIcon, Globe, SearchX, Trash2 } from "lucide-react";
import { toast } from "sonner";

import { ModelOwnerBar } from "@/components/models/model-owner-bar";
import { ModelVisibilityBadge } from "@/components/models/model-visibility-badge";
import { ModelVisibilityDialog } from "@/components/models/model-visibility-dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Skeleton } from "@/components/ui/skeleton";
import { Spinner } from "@/components/ui/spinner";
import {
  getModelDownload,
  ModelDownloadError,
  triggerNavDownload,
} from "@/lib/api/model-download";
import { useT } from "@/lib/i18n/context";
import { useModelSharingStore } from "@/stores/model-sharing-store";
import { useModelStore } from "@/stores/model-store";

function formatFileSize(bytes: number): string {
  if (!bytes) return "—";
  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`;
}

function formatInputShape(shape: number[]): string {
  return shape.join(" × ");
}

const CLASSES_PREVIEW_LIMIT = 8;

interface ModelProfileClientProps {
  id: string;
}

export function ModelProfileClient({ id }: ModelProfileClientProps) {
  const t = useT();
  const router = useRouter();

  const profile = useModelSharingStore((s) => s.profile);
  const isLoading = useModelSharingStore((s) => s.isProfileLoading);
  const profileError = useModelSharingStore((s) => s.profileError);
  const loadProfile = useModelSharingStore((s) => s.loadProfile);
  const clearProfile = useModelSharingStore((s) => s.clearProfile);

  // 刪除沿用既有 model-store（owner-only DELETE /api/models/:id）。
  const deleteModel = useModelStore((s) => s.deleteModel);

  const [deleting, setDeleting] = useState(false);
  const [downloadBusy, setDownloadBusy] = useState(false);
  const [visibilityDialogOpen, setVisibilityDialogOpen] = useState(false);

  useEffect(() => {
    if (id) void loadProfile(id);
    return () => clearProfile();
  }, [id, loadProfile, clearProfile]);

  const isOwner = profile?.myAccess === "owner";

  async function handleDownload() {
    if (!profile || downloadBusy) return;
    setDownloadBusy(true);
    try {
      const grant = await getModelDownload(profile.id);
      triggerNavDownload(grant.downloadUrl);
      toast.success(t("models.download.toast.start"), {
        description: t("models.download.toast.hint"),
      });
    } catch (err) {
      const code = err instanceof ModelDownloadError ? err.code : "unknown";
      const key = `models.download.error.${code}`;
      const desc = t(key);
      toast.error(t("models.download.error.title"), {
        description: desc === key ? t("models.download.error.unknown") : desc,
      });
    } finally {
      setDownloadBusy(false);
    }
  }

  async function handleDelete() {
    setDeleting(true);
    const ok = await deleteModel(id);
    setDeleting(false);
    if (ok) {
      toast.success(t("common.save"));
      router.push("/models");
    } else {
      toast.error(t("common.error"));
    }
  }

  const backButton = (
    <Link href="/models/library">
      <Button variant="ghost" size="sm">
        <ArrowLeft aria-hidden className="mr-2 size-4" />
        {t("common.back")}
      </Button>
    </Link>
  );

  // 載入中
  if (isLoading && !profile) {
    return (
      <div className="mx-auto max-w-4xl space-y-4 px-6 py-8">
        <Skeleton className="h-8 w-48" />
        <Skeleton className="h-4 w-96" />
        <Skeleton className="h-48 rounded-lg" />
      </div>
    );
  }

  // 無權限 / 找不到（契約：無可見性回 404，合併「找不到 / 無權限」）。
  if (profileError || !profile) {
    return (
      <div className="mx-auto max-w-4xl space-y-4 px-6 py-8">
        {backButton}
        <EmptyState
          icon={SearchX}
          title={t("models.profile.notFound.title")}
          description={t("models.profile.notFound.description")}
          action={{
            label: t("models.profile.backToLibrary"),
            onClick: () => router.push("/models/library"),
          }}
        />
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-4xl space-y-6 px-6 py-8">
      {backButton}

      <div className="flex flex-wrap items-start justify-between gap-3">
        <div className="space-y-2">
          <h1 className="text-2xl font-bold">{profile.name}</h1>
          <div className="flex flex-wrap gap-2">
            <Badge variant="outline">{profile.targetChip.toUpperCase()}</Badge>
            <Badge variant={profile.status === "ready" ? "default" : "secondary"}>
              {t(`models.status.${profile.status === "ready" ? "ready" : "scanning"}`)}
            </Badge>
            {profile.source !== "uploaded" && (
              <Badge variant="secondary">{t(`models.source.${profile.source}`)}</Badge>
            )}
            {/* owner 看到自己的 visibility；非 owner 看到共享標示。 */}
            <ModelVisibilityBadge
              visibility={profile.visibility}
              sharedWithMe={!isOwner}
            />
          </div>
        </div>

        <div className="flex items-center gap-2">
          {profile.canDownload && (
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={handleDownload}
              disabled={downloadBusy}
              aria-label={t("models.action.download.aria")}
              data-testid="profile-download"
            >
              {downloadBusy ? (
                <>
                  <Spinner size="sm" label={t("models.action.downloading")} />
                  {t("models.action.downloading")}
                </>
              ) : (
                <>
                  <DownloadIcon aria-hidden className="mr-2 size-4" />
                  {t("models.action.download")}
                </>
              )}
            </Button>
          )}

          {/* owner-only 操作：公開設定 + 刪除 */}
          {isOwner && (
            <>
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={() => setVisibilityDialogOpen(true)}
                data-testid="profile-visibility"
              >
                <Globe aria-hidden className="mr-2 size-4" />
                {t("models.visibility.title")}
              </Button>
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button variant="outline" size="sm" disabled={deleting}>
                    <Trash2 aria-hidden className="mr-2 size-4" />
                    {t("common.delete")}
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>{t("common.confirm")}</AlertDialogTitle>
                    <AlertDialogDescription>{profile.name}</AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>{t("common.cancel")}</AlertDialogCancel>
                    <AlertDialogAction onClick={handleDelete} disabled={deleting}>
                      {t("common.delete")}
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
            </>
          )}
        </div>
      </div>

      {/* 非 owner：擁有者資訊列。 */}
      {!isOwner && (
        <ModelOwnerBar ownerName={profile.owner.name} sharedAt={profile.updatedAt} />
      )}

      <Card>
        <CardHeader>
          <CardTitle className="text-base">{t("models.detail.description")}</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          {profile.description ? (
            <p className="text-sm">{profile.description}</p>
          ) : (
            <p className="text-muted-foreground text-sm">—</p>
          )}
          <div className="grid grid-cols-2 gap-3 pt-3 text-sm">
            <InfoRow label={t("models.size")} value={formatFileSize(profile.fileSize)} />
            <InfoRow
              label={t("models.createdAt")}
              value={profile.createdAt ? new Date(profile.createdAt).toLocaleString() : "—"}
            />
            {profile.framework && (
              <InfoRow
                label={t("models.detail.framework")}
                value={<span className="font-mono text-xs">{profile.framework}</span>}
              />
            )}
            {profile.inputShape && profile.inputShape.length > 0 && (
              <InfoRow
                label={t("models.detail.inputShape")}
                value={
                  <span className="font-mono text-xs">
                    {formatInputShape(profile.inputShape)}
                  </span>
                }
              />
            )}
          </div>

          {profile.classes && profile.classes.length > 0 && (
            <div className="space-y-2 border-t pt-3 text-sm">
              <div className="flex items-center justify-between gap-2">
                <span className="text-muted-foreground">{t("models.detail.classes")}</span>
                <span className="text-muted-foreground text-xs">
                  {profile.classes.length} {t("models.detail.classesCountSuffix")}
                </span>
              </div>
              <div className="flex flex-wrap gap-1.5">
                {profile.classes.slice(0, CLASSES_PREVIEW_LIMIT).map((c, i) => (
                  <Badge key={`${i}-${c}`} variant="secondary" className="font-normal">
                    {c}
                  </Badge>
                ))}
                {profile.classes.length > CLASSES_PREVIEW_LIMIT && (
                  <Badge variant="outline" className="font-normal">
                    +{profile.classes.length - CLASSES_PREVIEW_LIMIT}
                  </Badge>
                )}
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {isOwner && (
        <ModelVisibilityDialog
          modelId={profile.id}
          modelName={profile.name}
          currentVisibility={profile.visibility}
          open={visibilityDialogOpen}
          onOpenChange={setVisibilityDialogOpen}
        />
      )}
    </div>
  );
}

function InfoRow({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div className="flex items-start justify-between gap-2">
      <span className="text-muted-foreground">{label}</span>
      <span className="text-right">{value}</span>
    </div>
  );
}
