"use client";

import Link from "next/link";
import { useEffect, useState } from "react";

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { CardEyebrow } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { PageHeader } from "@/components/ui/page-header";
import { LibraryEditModal } from "@/features/libraries/components/library-edit-modal";
import { LibraryUploadModal } from "@/features/libraries/components/library-upload-modal";
import { archiveLibraryResource } from "@/features/libraries/manage-resource";
import type { LibraryItemVM, LibraryType } from "@/lib/types/view-models";

type LibraryPageProps = {
  isLoading?: boolean;
  items: LibraryItemVM[];
  libraryType: LibraryType;
  message?: string;
};

type LibraryEnvelope = {
  data?: {
    items?: LibraryItemVM[];
  };
  message?: string;
};

type LibraryMeta = {
  description: string;
  singularLabel: string;
  tabLabel: string;
};

const LIBRARY_META: Record<LibraryType, LibraryMeta> = {
  models: {
    description: "按模特资源管理上传、封面和提单联动素材。",
    singularLabel: "模特",
    tabLabel: "模特",
  },
  scenes: {
    description: "按场景资源管理上传、封面和提单联动素材。",
    singularLabel: "场景",
    tabLabel: "场景",
  },
  garments: {
    description: "按服装资源管理上传、封面和提单联动素材。",
    singularLabel: "服装",
    tabLabel: "服装",
  },
};

const LIBRARY_SECTIONS: Array<{
  href: string;
  label: string;
  libraryType: LibraryType;
}> = [
  { href: "/libraries/models", label: "模特", libraryType: "models" },
  { href: "/libraries/scenes", label: "场景", libraryType: "scenes" },
  { href: "/libraries/garments", label: "服装", libraryType: "garments" },
];

const STATE_TITLE = "资源库状态";
const DEFAULT_MESSAGE = "资源库当前显示真实后端数据。";

function joinClasses(...values: Array<string | false | null | undefined>) {
  return values.filter(Boolean).join(" ");
}

function getResourceRequestId(item: LibraryItemVM) {
  return typeof item.backendId === "number" ? String(item.backendId) : item.id;
}

export function LibraryPage({
  isLoading = false,
  items,
  libraryType,
  message = DEFAULT_MESSAGE,
}: LibraryPageProps) {
  const meta = LIBRARY_META[libraryType];
  const [archivingItem, setArchivingItem] = useState<LibraryItemVM | null>(null);
  const [editingItem, setEditingItem] = useState<LibraryItemVM | null>(null);
  const [isArchiving, setIsArchiving] = useState(false);
  const [isUploadOpen, setIsUploadOpen] = useState(false);
  const [visibleItems, setVisibleItems] = useState(items);
  const [statusMessage, setStatusMessage] = useState(message);

  useEffect(() => {
    setVisibleItems(items);
  }, [items]);

  useEffect(() => {
    setStatusMessage(message);
  }, [message]);

  function handleUploaded(item: LibraryItemVM) {
    setVisibleItems((current) => [
      item,
      ...current.filter((candidate) => candidate.id !== item.id),
    ]);
    setStatusMessage("资源上传成功，已写入正式资源库。");
    setIsUploadOpen(false);
  }

  function handleSaved(item: LibraryItemVM) {
    setVisibleItems((current) =>
      current.map((candidate) => (candidate.id === item.id ? item : candidate)),
    );
    setStatusMessage("资源更新成功，封面与元数据已同步。");
    setEditingItem(null);
  }

  async function handleArchive(item: LibraryItemVM) {
    setIsArchiving(true);

    try {
      const archivedId = await archiveLibraryResource({
        libraryType,
        resourceId: getResourceRequestId(item),
      });
      setVisibleItems((current) =>
        current.filter((candidate) => candidate.id !== archivedId),
      );
      setStatusMessage(`资源「${item.name}」已移入归档。`);
      setArchivingItem(null);
    } catch (archiveError) {
      setStatusMessage(
        archiveError instanceof Error
          ? archiveError.message
          : "资源删除失败，请稍后重试。",
      );
    } finally {
      setIsArchiving(false);
    }
  }

  return (
    <section className="space-y-8">
      <PageHeader
        eyebrow="Resource library"
        title="资源库"
        description={meta.description}
        meta={`${meta.tabLabel}管理视图`}
      />

      <nav
        aria-label="Library sections"
        className="flex flex-wrap gap-3 rounded-[28px] border border-[var(--border-soft)] bg-[rgba(255,250,242,0.88)] p-2 shadow-[var(--shadow-card)]"
      >
        {LIBRARY_SECTIONS.map((section) => {
          const isCurrent = section.libraryType === libraryType;

          return (
            <Link
              key={section.libraryType}
              href={section.href}
              aria-current={isCurrent ? "page" : undefined}
              className={joinClasses(
                "inline-flex min-h-11 items-center rounded-[20px] px-4 py-2 text-sm font-medium transition",
                isCurrent
                  ? "bg-[var(--accent-primary)] text-[var(--accent-ink)] shadow-[0_12px_30px_rgba(110,127,82,0.22)]"
                  : "text-[var(--ink-muted)] hover:bg-[var(--surface-muted)] hover:text-[var(--ink-strong)]",
              )}
            >
              {section.label}
            </Link>
          );
        })}
      </nav>

      <div className="rounded-[28px] border border-[rgba(145,104,46,0.2)] bg-[rgba(202,164,97,0.12)] px-6 py-5">
        <p className="text-lg font-semibold tracking-[-0.02em] text-[#7a5323]">
          {STATE_TITLE}
        </p>
        <p className="mt-2 text-sm leading-7 text-[#7a5323]">{statusMessage}</p>
      </div>

      <div
        data-testid="library-masonry"
        className="columns-1 gap-5 md:columns-2 xl:columns-3 2xl:columns-4"
      >
        <div className="mb-5 break-inside-avoid">
          <div className="rounded-[28px] border border-dashed border-[var(--border-strong)] bg-[linear-gradient(180deg,rgba(255,250,242,0.96),rgba(246,237,224,0.92))] p-5 shadow-[var(--shadow-card)]">
            <div className="space-y-4">
              <div className="space-y-2">
                <CardEyebrow>{meta.tabLabel} upload</CardEyebrow>
                <div className="space-y-2">
                  <h2 className="text-lg font-semibold tracking-[-0.02em] text-[var(--ink-strong)]">
                    上传{meta.singularLabel}资源
                  </h2>
                  <p className="text-sm leading-6 text-[var(--ink-muted)]">
                    当前页签决定资源类型，只需要上传原图，缩略图会自动生成。
                  </p>
                </div>
              </div>
              <Button
                className="min-h-11 w-full justify-center"
                size="lg"
                onClick={() => setIsUploadOpen(true)}
              >
                打开上传弹窗
              </Button>
            </div>
          </div>
        </div>

        {isLoading ? (
          <div className="mb-5 break-inside-avoid rounded-[28px] border border-dashed border-[var(--border-strong)] bg-[var(--surface-muted)] px-5 py-6 text-sm text-[var(--ink-muted)]">
            正在加载资源库数据…
          </div>
        ) : null}

        {!isLoading && !visibleItems.length ? (
          <div className="mb-5 break-inside-avoid rounded-[28px] border border-[var(--border-soft)] bg-[var(--surface)] p-5 shadow-[var(--shadow-card)]">
            <EmptyState
              eyebrow="Library empty"
              title={`暂无${meta.singularLabel}资源`}
              description="当前库还没有资源条目，先从首卡入口上传第一批素材。"
            />
          </div>
        ) : null}

        {!isLoading
          ? visibleItems.map((item) => (
              <article
                key={item.id}
                className="mb-5 break-inside-avoid rounded-[28px] border border-[var(--border-soft)] bg-[var(--surface)] p-4 shadow-[var(--shadow-card)]"
              >
                <div className="space-y-4">
                  <div className="rounded-[22px] border border-[rgba(74,64,53,0.08)] bg-[linear-gradient(160deg,rgba(255,249,240,0.95),rgba(230,217,199,0.82))] p-4">
                    <div className="relative aspect-[4/5] overflow-hidden rounded-[18px] bg-[radial-gradient(circle_at_top,rgba(255,255,255,0.88),rgba(218,197,170,0.48))]">
                      {item.previewUri ? (
                        // previewUri may come from mock:// fixtures during tests, so keep a plain img here.
                        // eslint-disable-next-line @next/next/no-img-element
                        <img
                          alt={`${item.name} 预览图`}
                          className="h-full w-full object-cover"
                          src={item.previewUri}
                        />
                      ) : null}
                      {/* <div className="absolute inset-x-0 bottom-0 flex items-end p-4">
                        <div className="rounded-[18px] bg-[rgba(74,64,53,0.72)] px-3 py-2 text-sm font-medium text-[#fffaf5]">
                          {meta.singularLabel}预览
                        </div>
                      </div> */}
                    </div>
                  </div>

                  <div className="space-y-3">
                    <div className="space-y-1">
                      <p className="text-base font-semibold tracking-[-0.02em] text-[var(--ink-strong)]">
                        {item.name}
                      </p>
                      <p className="text-sm leading-6 text-[var(--ink-muted)]">
                        {item.description}
                      </p>
                    </div>

                    {item.tags.length ? (
                      <div className="flex flex-wrap gap-2">
                        {item.tags.map((tag) => (
                          <span
                            key={tag}
                            className="rounded-full bg-[rgba(110,98,84,0.08)] px-2.5 py-1 font-[var(--font-mono)] text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)]"
                          >
                            {tag}
                          </span>
                        ))}
                      </div>
                    ) : null}

                    {/* <code className="block rounded-[18px] bg-[rgba(74,64,53,0.08)] px-3 py-3 text-xs leading-6 text-[var(--ink-muted)]">
                      {item.previewUri}
                    </code> */}

                    <div className="grid gap-2 sm:grid-cols-2">
                      <Button
                        size="sm"
                        variant="secondary"
                        onClick={() => setEditingItem(item)}
                      >
                        编辑
                      </Button>
                      <Button
                        size="sm"
                        variant="danger"
                        onClick={() => {
                          setArchivingItem(item);
                        }}
                      >
                        删除
                      </Button>
                    </div>
                  </div>
                </div>
              </article>
            ))
          : null}
      </div>

      <LibraryUploadModal
        libraryType={libraryType}
        open={isUploadOpen}
        onClose={() => setIsUploadOpen(false)}
        onUploaded={handleUploaded}
      />
      <LibraryEditModal
        item={editingItem}
        libraryType={libraryType}
        open={editingItem !== null}
        onClose={() => setEditingItem(null)}
        onSaved={handleSaved}
      />
      <AlertDialog
        open={archivingItem !== null}
        onOpenChange={(open) => {
          if (!open && !isArchiving) {
            setArchivingItem(null);
          }
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{`确认删除${meta.singularLabel}资源`}</AlertDialogTitle>
            <AlertDialogDescription>
              {archivingItem
                ? `删除后，这条资源会被移入归档，不再出现在当前列表中。当前资源：${archivingItem.name}`
                : "删除后，这条资源会被移入归档，不再出现在当前列表中。"}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isArchiving}>取消</AlertDialogCancel>
            <AlertDialogAction
              disabled={!archivingItem || isArchiving}
              onClick={(event) => {
                event.preventDefault();

                if (!archivingItem || isArchiving) {
                  return;
                }

                void handleArchive(archivingItem);
              }}
            >
              {isArchiving ? "删除中..." : "确认删除"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </section>
  );
}

export function LibraryPageScreen({ libraryType }: { libraryType: LibraryType }) {
  const [items, setItems] = useState<LibraryItemVM[]>([]);
  const [message, setMessage] = useState(DEFAULT_MESSAGE);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    let active = true;

    async function loadLibrary() {
      setIsLoading(true);

      try {
        const response = await fetch(`/api/libraries/${libraryType}`);
        const payload = (await response.json()) as LibraryEnvelope;

        if (!active) {
          return;
        }

        setItems(payload.data?.items ?? []);
        setMessage(payload.message ?? DEFAULT_MESSAGE);
      } catch {
        if (!active) {
          return;
        }

        setItems([]);
        setMessage("资源库数据加载失败，请稍后重试。");
      } finally {
        if (active) {
          setIsLoading(false);
        }
      }
    }

    void loadLibrary();

    return () => {
      active = false;
    };
  }, [libraryType]);

  return (
    <LibraryPage
      isLoading={isLoading}
      items={items}
      libraryType={libraryType}
      message={message}
    />
  );
}
