import { useEffect, useState } from "react";
import {
  ArrowDown,
  ArrowUp,
  ChevronRight,
  Eye,
  Plus,
  RefreshCcw,
  Save,
  Send,
  Trash2,
  X,
} from "lucide-react";

import {
  createSiteConfigItem,
  deleteSiteConfigItem,
  getProducts,
  getSiteConfig,
  publishSite,
  reorderSiteConfigItems,
  resetGuizhouContent,
  updateSiteConfigItem,
} from "@/api";
import type { Product, SiteConfig, SiteItemPatch, SiteModule } from "@/api";
import { AdminDisclosure } from "@/components/admin/AdminDisclosure";
import { EmptyState } from "@/components/admin/EmptyState";
import { RouteSectionsPanel } from "@/components/admin/route-sections/RouteSectionsPanel";
import { SingleImageUploader } from "@/components/admin/SingleImageUploader";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { NativeSelect } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import {
  compactSiteItemPayload,
  createEmptySiteItemDraft,
  itemImage,
  itemMeta,
  itemName,
  itemSortOrder,
  itemTags,
  moduleEditable,
  moduleItems,
  siteItemPrimaryKey,
} from "@/lib/admin-utils";
import type {
  DirtyChangeHandler,
  EditableSiteItem,
  ModuleId,
  Notify,
  PageId,
  Tab,
} from "@/types/admin";

const NEW_SITE_ITEM_ID = "__new_site_item__";
const moreServicesTargetOptions = [
  { value: "", label: "按默认顺序" },
  { value: "cardBenefits", label: "万趣权益页" },
  { value: "service", label: "服务管家" },
  { value: "destinationPicker", label: "目的地页" },
  { value: "demand", label: "提交需求" },
] as const;

const pageSpecs: {
  id: PageId;
  title: string;
  subtitle: string;
  frontPath: string;
  modules: {
    id: ModuleId;
    label: string;
    hint: string;
    frontPosition: string;
  }[];
}[] = [
  {
    id: "home",
    title: "万趣首页",
    subtitle: "维护用户进入小程序后第一屏到页尾的内容顺序。",
    frontPath: "前台：首页 / bottom tab「万趣」",
    modules: [
      {
        id: "heroSlides",
        label: "顶部轮播",
        hint: "控制首屏大图、活动入口和主视觉顺序。",
        frontPosition: "首页第一屏",
      },
      {
        id: "destinations",
        label: "探索贵州",
        hint: "控制省内目的地宫格、热门标记和搜索入口。",
        frontPosition: "首页「探索贵州」",
      },
      {
        id: "map",
        label: "贵州地图",
        hint: "展示贵州省内的地图信息和地点。",
        frontPosition: "首页「探索贵州」",
      },
      {
        id: "themes",
        label: "主题甄选",
        hint: "控制横向主题卡和搜索跳转。",
        frontPosition: "首页「主题甄选」",
      },
      {
        id: "campaigns",
        label: "特价优惠",
        hint: "维护活动标题、封面和发布状态，供首页特价优惠入口使用。",
        frontPosition: "首页「特价优惠」",
      },
      {
        id: "routeSections",
        label: "精选线路",
        hint: "按运营任务新增精选线路分组，维护标题、副文案、启用状态和关联线路顺序。",
        frontPosition: "首页精选线路",
      },
      {
        id: "hotelGroups",
        label: "特色酒店",
        hint: "维护首页特色酒店卡片标题、描述、封面图、启用状态和排序。",
        frontPosition: "首页「特色酒店」",
      },
      {
        id: "vehicleOptions",
        label: "万趣用车",
        hint: "维护首页用车卡片标题、描述、封面图、启用状态和排序。",
        frontPosition: "首页「万趣用车」",
      },
      {
        id: "ctaBanners",
        label: "更多服务",
        hint: "维护更多服务卡片标题、背景图、启用状态和排序。",
        frontPosition: "首页「更多服务」",
      },
    ],
  },
  {
    id: "destination",
    title: "目的地页",
    subtitle: "按前台目的地页模块核对数据来源和维护入口。",
    frontPath: "前台：bottom tab「目的地」/ 搜索弹层",
    modules: [
      {
        id: "destinationHero",
        label: "顶部主视觉",
        hint: "对应目的地页顶部大图和“贵州小包团目的地”文案。",
        frontPosition: "目的地页顶部主视觉",
      },
      {
        id: "destinationRegions",
        label: "热门区域",
        hint: "对应目的地页“热门区域”快捷入口。",
        frontPosition: "目的地页「热门区域」",
      },
      {
        id: "destinations",
        label: "省内目的地",
        hint: "维护目的地卡片名称、封面、热门状态、启停和展示顺序。",
        frontPosition: "目的地页「省内目的地」",
      },
    ],
  },
  {
    id: "detail",
    title: "商品维护",
    subtitle: "维护用户点击商品卡后的详情页内容和售卖状态。",
    frontPath: "前台：产品卡点击后详情页",
    modules: [
      {
        id: "routeProducts",
        label: "商品库",
        hint: "编辑标题、价格、封面、标签、详情模块和上下架。",
        frontPosition: "详情页、搜索页、首页商品卡",
      },
    ],
  },
  {
    id: "campaign",
    title: "活动专题",
    subtitle: "维护轮播、主题卡和 CTA 指向的活动内容。",
    frontPath: "前台：轮播 / 主题卡 / CTA 跳转",
    modules: [
      {
        id: "heroSlides",
        label: "轮播活动入口",
        hint: "首屏主视觉上的活动入口。",
        frontPosition: "首页轮播",
      },
      {
        id: "themes",
        label: "主题活动入口",
        hint: "主题卡片进入对应活动专题。",
        frontPosition: "主题甄选横滑区",
      },
      {
        id: "ctaBanners",
        label: "更多服务入口",
        hint: "维护更多服务里的活动和需求入口。",
        frontPosition: "首页「更多服务」",
      },
      {
        id: "campaignProducts",
        label: "活动商品池",
        hint: "活动专题内展示的商品来自商品库。",
        frontPosition: "活动专题产品列表",
      },
    ],
  },
  {
    id: "demand",
    title: "需求线索",
    subtitle: "维护用户提交出行需求后的分配和跟进。",
    frontPath: "前台：提交出行需求 / 立即咨询",
    modules: [
      {
        id: "leadFlow",
        label: "线索跟进",
        hint: "查看联系方式、目的地、来源商品并推进状态。",
        frontPosition: "需求表单提交后",
      },
    ],
  },
];

export function StructurePage({
  fixedPage,
  onJump,
  onDirtyChange,
  notify,
}: {
  fixedPage?: PageId;
  onJump: (tab: Tab) => void;
  onDirtyChange: DirtyChangeHandler;
  notify: Notify;
}) {
  const [config, setConfig] = useState<SiteConfig | null>(null);
  const [products, setProducts] = useState<Product[]>([]);
  const [pageId, setPageId] = useState<PageId>(fixedPage ?? "home");
  const [moduleId, setModuleId] = useState<ModuleId>("heroSlides");
  const [selectedId, setSelectedId] = useState("");
  const [draft, setDraft] = useState<SiteItemPatch>({});
  const [message, setMessage] = useState("");
  const [editorOpen, setEditorOpen] = useState(false);
  const [saving, setSaving] = useState(false);
  const [routeSectionCreateRequest, setRouteSectionCreateRequest] = useState(0);

  const activePage =
    pageSpecs.find((page) => page.id === (fixedPage ?? pageId)) ?? pageSpecs[0];
  const activeModule =
    activePage.modules.find((module) => module.id === moduleId) ??
    activePage.modules[0];
  const isRouteSectionsModule = moduleId === "routeSections";
  const editableItems =
    config && moduleEditable(moduleId) && !isRouteSectionsModule
      ? moduleItems(config, moduleId)
      : [];
  const isMapModule = moduleId === "map";
  const isCampaignModule = moduleId === "campaigns";
  const isCardContentModule = moduleId === "hotelGroups" || moduleId === "vehicleOptions";
  const canReorderSiteItems =
    moduleEditable(moduleId) && !isRouteSectionsModule && !isMapModule && !isCampaignModule;
  const canCreateSiteItem =
    moduleEditable(moduleId) && !isRouteSectionsModule && (!isMapModule || editableItems.length === 0);
  const showRouteSectionCreateButton = isRouteSectionsModule;
  const isCreatingSiteItem = selectedId === NEW_SITE_ITEM_ID;
  const selectedItem = isCreatingSiteItem
    ? undefined
    : (editableItems.find((item) => item.id === selectedId) ??
      editableItems[0]);
  const showEditorDrawer =
    editorOpen &&
    moduleEditable(moduleId) &&
    !isRouteSectionsModule &&
    (isCreatingSiteItem || Boolean(selectedItem));
  const gridClassName = [
    "maintenance-grid",
    fixedPage ? "focused-page-grid" : "",
  ]
    .filter(Boolean)
    .join(" ");

  const setDraftFromItem = (item: EditableSiteItem) => {
    const imageValue = "image" in item ? item.image || "" : "";
    const coverImageValue =
      "coverImage" in item
        ? item.coverImage || imageValue
        : moduleId === "hotelGroups"
          ? imageValue
          : undefined;
    const activeStatus =
      "status" in item && (item.status === "draft" || item.status === "published")
        ? item.status
        : moduleId === "hotelGroups"
          ? "isActive" in item && item.isActive === false
            ? "draft"
            : "published"
          : undefined;

    setDraft({
      title: "title" in item ? item.title : undefined,
      kicker: "kicker" in item ? item.kicker || "" : undefined,
      name: "name" in item ? item.name : undefined,
      slug: "slug" in item ? item.slug : undefined,
      region: "region" in item ? item.region || "" : undefined,
      label: "label" in item ? item.label : undefined,
      keyword: "keyword" in item ? item.keyword || "" : undefined,
      spots: "spots" in item ? item.spots || "" : undefined,
      alt: "alt" in item ? item.alt : undefined,
      image: imageValue,
      description: "description" in item ? item.description || "" : undefined,
      coverImage: coverImageValue,
      priceAmount: "priceAmount" in item ? item.priceAmount : undefined,
      priceUnit: "priceUnit" in item ? item.priceUnit || (moduleId === "hotelGroups" ? "起/晚" : "起/人") : moduleId === "hotelGroups" ? "起/晚" : undefined,
      tags: "tags" in item && Array.isArray(item.tags) ? item.tags.slice(0, 3) : moduleId === "hotelGroups" ? [] : undefined,
      isHot: "isHot" in item ? item.isHot : undefined,
      isActive: "isActive" in item ? item.isActive : moduleId === "hotelGroups" ? activeStatus === "published" : undefined,
      sortOrder: itemSortOrder(item),
      status: activeStatus,
      startsAt: "startsAt" in item ? item.startsAt || "" : undefined,
      endsAt: "endsAt" in item ? item.endsAt || "" : undefined,
    });
  };

  const load = async (): Promise<SiteConfig> => {
    const [site, productResult] = await Promise.all([
      getSiteConfig(),
      getProducts(),
    ]);
    setConfig(site);
    setProducts(productResult.items);
    const firstModule = activePage.modules[0]?.id ?? "heroSlides";
    setModuleId((current) =>
      activePage.modules.some((module) => module.id === current)
        ? current
        : firstModule,
    );
    if (moduleEditable(firstModule)) {
      const first = moduleItems(site, firstModule)[0];
      if (first && !selectedId) {
        setSelectedId(first.id);
        setDraftFromItem(first);
      }
    }
    return site;
  };

  useEffect(() => {
    load().catch((err) => setMessage(err.message));
  }, []);

  useEffect(() => {
    if (!fixedPage) return;
    setPageId(fixedPage);
    const next =
      pageSpecs.find((page) => page.id === fixedPage)?.modules[0]?.id ??
      "heroSlides";
    setModuleId(next);
    setSelectedId("");
    setEditorOpen(false);
  }, [fixedPage]);

  useEffect(() => {
    if (!config || !moduleEditable(moduleId) || isRouteSectionsModule) {
      setSelectedId("");
      setDraft({});
      setEditorOpen(false);
      return;
    }
    const first = moduleItems(config, moduleId)[0];
    if (!first) {
      setSelectedId("");
      setDraft({});
      setEditorOpen(false);
      return;
    }
    setSelectedId(first.id);
    setDraftFromItem(first);
    setEditorOpen(false);
  }, [moduleId, config]);

  const selectPage = (next: PageId) => {
    setPageId(next);
    const page = pageSpecs.find((item) => item.id === next);
    setModuleId(page?.modules[0]?.id ?? "heroSlides");
    setSelectedId("");
    setMessage("");
    setEditorOpen(false);
    onDirtyChange(false);
  };

  const startCreateSiteItem = () => {
    if (!moduleEditable(moduleId) || isRouteSectionsModule) return;
    setSelectedId(NEW_SITE_ITEM_ID);
    setDraft(createEmptySiteItemDraft(moduleId, editableItems.length));
    setMessage("");
    setEditorOpen(true);
    onDirtyChange(true);
  };

  const selectItem = (item: EditableSiteItem) => {
    setSelectedId(item.id);
    setDraftFromItem(item);
    setMessage("");
    setEditorOpen(true);
    onDirtyChange(false);
  };

  const closeEditorDrawer = () => {
    setEditorOpen(false);
    setMessage("");
    if (isCreatingSiteItem) {
      const first = editableItems[0];
      if (first) {
        setSelectedId(first.id);
        setDraftFromItem(first);
      } else {
        setSelectedId("");
        setDraft({});
      }
      onDirtyChange(false);
    }
  };

  const save = async () => {
    if (
      saving ||
      !config ||
      !moduleEditable(moduleId) ||
      isRouteSectionsModule ||
      (!selectedId && !isCreatingSiteItem)
    )
      return;
    const payload = compactSiteItemPayload(moduleId, draft);
    const primaryKey = siteItemPrimaryKey(moduleId);
    const primaryValue = String(payload[primaryKey] ?? "").trim();

    if (!primaryValue) {
      const messageText =
        moduleId === "map"
          ? "请先上传贵州地图图片。"
          : moduleId === "campaigns"
            ? "请先填写特价优惠标题。"
          : "请先填写当前模块的主标题/名称。";
      notify({ tone: "warning", title: "内容未保存", message: messageText });
      return;
    }
    setSaving(true);
    setMessage("");

    try {
      let saved: EditableSiteItem;
      const existingMapItem =
        moduleId === "map" ? moduleItems(config, "map")[0] : undefined;

      try {
        saved =
          moduleId === "map" && existingMapItem
            ? ((await updateSiteConfigItem(
                moduleId,
                existingMapItem.id,
                payload,
              )) as EditableSiteItem)
            : isCreatingSiteItem
              ? ((await createSiteConfigItem(moduleId, payload)) as EditableSiteItem)
              : ((await updateSiteConfigItem(
                  moduleId,
                  selectedId,
                  payload,
                )) as EditableSiteItem);
      } catch (err) {
        if (moduleId !== "map" || !isCreatingSiteItem) throw err;

        const latestConfig = await getSiteConfig().catch(() => null);
        const latestMapItem = latestConfig
          ? moduleItems(latestConfig, "map")[0]
          : undefined;
        if (!latestMapItem) throw err;

        saved = (await updateSiteConfigItem(
          moduleId,
          latestMapItem.id,
          payload,
        )) as EditableSiteItem;
      }

      setSelectedId(saved.id);
      setDraftFromItem(saved);
      setMessage("");
      onDirtyChange(false);
      notify({
        tone: "success",
        title: isCreatingSiteItem ? "内容已新增" : "内容已保存",
        message: `${activeModule.label} 已同步到维护数据。`,
      });
      await load();
    } catch (err) {
      const messageText = err instanceof Error ? err.message : "保存失败";
      setMessage(messageText);
      notify({ tone: "danger", title: "内容保存失败", message: messageText });
    } finally {
      setSaving(false);
    }
  };

  const removeSiteItem = async (item: EditableSiteItem) => {
    if (!moduleEditable(moduleId) || isRouteSectionsModule) return;
    const confirmed = window.confirm(
      `确认删除「${itemName(item)}」吗？删除后需要后端同步移除对应模块配置。`,
    );
    if (!confirmed) return;

    try {
      await deleteSiteConfigItem(moduleId, item.id);
      setSelectedId("");
      setDraft({});
      setMessage("");
      onDirtyChange(false);
      notify({
        tone: "success",
        title: "内容已删除",
        message: `${activeModule.label} 已移除一项配置。`,
      });
      await load();
    } catch (err) {
      const messageText = err instanceof Error ? err.message : "删除失败";
      setMessage(messageText);
      notify({ tone: "danger", title: "内容删除失败", message: messageText });
    }
  };

  const moveSiteItem = async (item: EditableSiteItem, direction: -1 | 1) => {
    if (!moduleEditable(moduleId) || isRouteSectionsModule) return;
    const currentIndex = editableItems.findIndex(
      (candidate) => candidate.id === item.id,
    );
    const nextIndex = currentIndex + direction;
    if (currentIndex < 0 || nextIndex < 0 || nextIndex >= editableItems.length)
      return;

    const nextIds = editableItems.map((candidate) => candidate.id);
    [nextIds[currentIndex], nextIds[nextIndex]] = [
      nextIds[nextIndex],
      nextIds[currentIndex],
    ];

    try {
      await reorderSiteConfigItems(moduleId, nextIds);
      setMessage("");
      onDirtyChange(false);
      notify({
        tone: "success",
        title: "顺序已更新",
        message: `${activeModule.label} 已按新顺序保存。`,
      });
      await load();
    } catch (err) {
      const messageText = err instanceof Error ? err.message : "排序失败";
      setMessage(messageText);
      notify({ tone: "danger", title: "排序保存失败", message: messageText });
    }
  };

  const publish = async () => {
    const result = await publishSite();
    setMessage("");
    notify({ tone: "success", title: "已生成发布版本", message: result.title });
  };

  const resetToGuizhou = async () => {
    const result = await resetGuizhouContent();
    setMessage("");
    notify({
      tone: "success",
      title: "贵州内容已重置",
      message: "后台配置、商品库和素材引用已切换为贵州省内定制游。",
    });
    setSelectedId("");
    setDraft({});
    onDirtyChange(false);
    await load();
  };

  if (!config) return <EmptyState text={message || "正在读取小程序结构"} />;

  return (
    <section className="work-area structure-workbench">
      <header className="section-head">
        <div>
          <h2>{fixedPage ? activePage.title : "小程序维护地图"}</h2>
          <p>
            {fixedPage
              ? activePage.subtitle
              : "按用户看到的前台页面组织后台，逐层展开到可维护内容。"}
          </p>
        </div>
        <div className="action-row">
          <Button variant="outline" onClick={load}>
            <RefreshCcw size={17} />
            刷新
          </Button>
          <Button className="primary-action compact" onClick={publish}>
            <Send size={17} />
            发布快照
          </Button>
          <Button variant="outline" onClick={resetToGuizhou}>
            <RefreshCcw size={17} />
            重置贵州内容
          </Button>
        </div>
      </header>
      <div className={gridClassName}>
        {!fixedPage ? (
          <aside className="page-rail">
            <h3>前台页面</h3>
            {pageSpecs.map((page) => (
              <Button
                variant="ghost"
                className={activePage.id === page.id ? "active" : ""}
                key={page.id}
                onClick={() => selectPage(page.id)}
              >
                <span>
                  <b>{page.title}</b>
                  <small>{page.frontPath}</small>
                </span>
                <ChevronRight size={16} />
              </Button>
            ))}
          </aside>
        ) : (
          <section className="page-focus-card">
            <span className="focus-kicker">当前维护页面</span>
            <h3>{activePage.title}</h3>
            <p>{activePage.frontPath}</p>
            <small>{activePage.subtitle}</small>
          </section>
        )}
        <section className="module-rail">
          <div className="front-context">
            <Eye size={18} />
            <span>
              <b>{activePage.frontPath}</b>
              <small>{activePage.subtitle}</small>
            </span>
          </div>
          <h3>页面模块</h3>
          {activePage.modules.map((module, index) => (
            <div
              role="button"
              tabIndex={0}
              aria-pressed={activeModule.id === module.id}
              className={`module-rail-item${activeModule.id === module.id ? " active" : ""}`}
              key={module.id}
              onClick={() => setModuleId(module.id)}
              onKeyDown={(event) => {
                if (event.key === "Enter" || event.key === " ") {
                  event.preventDefault();
                  setModuleId(module.id);
                }
              }}
            >
              <em>{index + 1}</em>
              <span>
                <b>{module.label}</b>
                <small>{module.frontPosition}</small>
              </span>
            </div>
          ))}
        </section>
        <section className="item-rail">
          <header className="module-data-head">
            <span>
              <h3>{activeModule.label}</h3>
              <p>{activeModule.hint}</p>
            </span>
            {canCreateSiteItem ? (
              <Button
                className="primary-action compact"
                onClick={startCreateSiteItem}
              >
                <Plus size={16} />
                {isMapModule ? "上传地图" : "新增"}
              </Button>
            ) : showRouteSectionCreateButton ? (
              <Button
                className="primary-action compact"
                onClick={() => setRouteSectionCreateRequest((current) => current + 1)}
              >
                <Plus size={16} />
                新增
              </Button>
            ) : null}
          </header>
          {isRouteSectionsModule ? (
            <RouteSectionsPanel
              routeSections={config.routeSections}
              products={products}
              moduleLabel={activeModule.label}
              onDirtyChange={onDirtyChange}
              notify={notify}
              onReload={load}
              createRequestKey={routeSectionCreateRequest}
            />
          ) : moduleEditable(moduleId) ? (
            <div className="mapped-list">
              {editableItems.map((item, index) => (
                <div className="mapped-list-row" key={item.id}>
                  <Button
                    variant="ghost"
                    className={`mapped-list-main ${selectedItem?.id === item.id ? "selected" : ""}`}
                    onClick={() => selectItem(item)}
                  >
                    {itemImage(item) ? (
                      <img src={itemImage(item)} alt="" />
                    ) : (
                      <span className="image-placeholder" />
                    )}
                    <span>
                      <b>{itemName(item)}</b>
                      <small>
                        {itemMeta(item)}
                        {canReorderSiteItems && typeof itemSortOrder(item) === "number"
                          ? ` · 排序 ${itemSortOrder(item)}`
                          : ""}
                      </small>
                      {itemTags(item).length ? (
                        <span className="mapped-list-tags">
                          {itemTags(item).map((tag) => (
                            <em key={tag}>{tag}</em>
                          ))}
                        </span>
                      ) : null}
                    </span>
                  </Button>
                  <div
                    className="mapped-list-actions"
                    aria-label={`${itemName(item)} 操作`}
                  >
                    {canReorderSiteItems ? (
                      <>
                        <Button
                          variant="ghost"
                          size="icon"
                          disabled={index === 0}
                          onClick={() => moveSiteItem(item, -1)}
                          aria-label={`上移 ${itemName(item)}`}
                        >
                          <ArrowUp size={15} />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          disabled={index === editableItems.length - 1}
                          onClick={() => moveSiteItem(item, 1)}
                          aria-label={`下移 ${itemName(item)}`}
                        >
                          <ArrowDown size={15} />
                        </Button>
                      </>
                    ) : null}
                    <Button
                      variant="ghost"
                      size="icon"
                      onClick={() => removeSiteItem(item)}
                      aria-label={`删除 ${itemName(item)}`}
                    >
                      <Trash2 size={15} />
                    </Button>
                  </div>
                </div>
              ))}
              {!editableItems.length ? (
                <p className="mapped-empty">
                  {isMapModule
                    ? "暂无地图图片，点击上传地图。"
                    : moduleId === "ctaBanners"
                      ? "暂无更多服务卡片，点击新增创建第一项。"
                      : "暂无配置数据，点击新增创建第一项。"}
                </p>
              ) : null}
            </div>
          ) : (
            <ReferencePanel
              moduleId={moduleId}
              products={products}
              onJump={onJump}
            />
          )}
        </section>
      </div>
      {showEditorDrawer && moduleEditable(moduleId) ? (
        <div className="edit-drawer-layer">
          <button
            className="edit-drawer-backdrop"
            type="button"
            aria-label="关闭编辑抽屉"
            onClick={closeEditorDrawer}
          />
          <section
            className="edit-rail edit-drawer"
            role="dialog"
            aria-modal="true"
            aria-labelledby="site-item-editor-title"
          >
            <SiteItemEditor
              moduleId={moduleId}
              moduleLabel={activeModule.label}
              draft={draft}
              isCreating={isCreatingSiteItem}
              saving={saving}
              onDraft={(nextDraft) => {
                setDraft(nextDraft);
                onDirtyChange(true);
              }}
              onSave={save}
              onClose={closeEditorDrawer}
            />
          </section>
        </div>
      ) : null}
    </section>
  );
}

function CampaignTagEditor({
  tags,
  onChange,
}: {
  tags: string[];
  onChange: (tags: string[]) => void;
}) {
  const normalizedTags = tags.slice(0, 3);
  const updateTag = (index: number, value: string) => {
    onChange(
      normalizedTags.map((tag, tagIndex) =>
        tagIndex === index ? value : tag,
      ),
    );
  };
  const removeTag = (index: number) => {
    onChange(normalizedTags.filter((_, tagIndex) => tagIndex !== index));
  };
  const addTag = () => {
    if (normalizedTags.length >= 3) return;
    onChange([...normalizedTags, ""]);
  };

  return (
    <div className="tag-editor compact-tag-editor">
      {normalizedTags.map((tag, index) => (
        <label className="tag-input-row" key={`${index}-${tag}`}>
          标签 {index + 1}
          <span>
            <Input
              value={tag}
              onChange={(event) => updateTag(index, event.target.value)}
            />
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className="icon-action danger-icon"
              onClick={() => removeTag(index)}
              aria-label={`删除标签 ${index + 1}`}
            >
              <X size={16} />
            </Button>
          </span>
        </label>
      ))}
      <Button
        type="button"
        variant="outline"
        className="inline-action"
        onClick={addTag}
        disabled={normalizedTags.length >= 3}
      >
        <Plus size={16} />
        添加标签
      </Button>
      <p className="field-help">最多维护 3 个标签，保存时会自动去掉空标签。</p>
    </div>
  );
}

function ReferencePanel({
  moduleId,
  products,
  onJump,
}: {
  moduleId: ModuleId;
  products: Product[];
  onJump: (tab: Tab) => void;
}) {
  if (moduleId === "leadFlow") {
    return (
      <div className="reference-panel">
        <p>
          这个模块由客户需求列表维护，重点是状态流转、服务管家跟进和来源追踪。
        </p>
        <Button
          className="primary-action compact"
          onClick={() => onJump("leads")}
        >
          进入需求线索
        </Button>
      </div>
    );
  }

  return (
    <div className="reference-panel">
      <p>
        这个模块引用商品库。编辑商品后，首页商品卡、搜索结果和详情页会同步使用同一份数据。
      </p>
      <div className="mini-product-stack">
        {products.slice(0, 4).map((product) => (
          <span key={product.id}>
            <img src={product.coverImage || ""} alt="" />
            <b>{product.title}</b>
          </span>
        ))}
      </div>
      <Button
        className="primary-action compact"
        onClick={() => onJump("products")}
      >
        进入商品维护
      </Button>
    </div>
  );
}

function SiteItemEditor({
  moduleId,
  moduleLabel,
  draft,
  isCreating,
  saving,
  onDraft,
  onSave,
  onClose,
}: {
  moduleId: SiteModule;
  moduleLabel: string;
  draft: SiteItemPatch;
  isCreating: boolean;
  saving: boolean;
  onDraft: (draft: SiteItemPatch) => void;
  onSave: () => void;
  onClose: () => void;
}) {
  const primaryKey = siteItemPrimaryKey(moduleId);
  const primaryLabel = (() => {
    if (moduleId === "heroSlides") return "轮播标题";
    if (moduleId === "destinations") return "目的地名称";
    if (moduleId === "destinationHero") return "主视觉标题";
    if (moduleId === "destinationRegions") return "区域名称";
    if (moduleId === "map") return "地图图片";
    if (moduleId === "themes") return "主题名称";
    if (moduleId === "campaigns") return "活动标题";
    if (moduleId === "hotelGroups") return "酒店标题";
    if (moduleId === "vehicleOptions") return "用车标题";
    if (moduleId === "ctaBanners") return "服务标题";
    return "入口文案";
  })();
  const editorTitle = `${isCreating ? "新增" : "编辑"}${moduleLabel}`;
  const isImageOnlyModule = moduleId === "map";
  const isCampaignModule = moduleId === "campaigns";
  const isHotelModule = moduleId === "hotelGroups";
  const isDestinationHeroModule = moduleId === "destinationHero";
  const isDestinationRegionModule = moduleId === "destinationRegions";
  const isTextOnlyModule = isDestinationRegionModule;
  const usesOfferConfig = isCampaignModule || isHotelModule;
  const isMoreServicesModule = moduleId === "ctaBanners";
  const isCardContentModule = moduleId === "vehicleOptions";
  const editorHint = isImageOnlyModule
    ? isCreating
      ? `上传后会作为「${moduleLabel}」唯一展示图片`
      : `保存后会替换「${moduleLabel}」前台展示图片`
    : usesOfferConfig
      ? isCampaignModule
        ? isCreating
          ? `创建后会进入「${moduleLabel}」的活动列表`
          : `保存后会影响「${moduleLabel}」活动入口`
        : isCreating
          ? `创建后会进入「${moduleLabel}」的数据列表`
          : `保存后会影响「${moduleLabel}」首页卡片`
    : isMoreServicesModule
      ? isCreating
        ? "创建后会进入首页「更多服务」卡片列表"
        : "保存后会影响首页「更多服务」卡片"
    : isCreating
      ? `创建后会进入「${moduleLabel}」的数据列表`
      : `保存后会影响「${moduleLabel}」前台模块`;

  return (
    <div className="mapped-editor">
      <header className="editor-head">
        <span>
          <h3 id="site-item-editor-title">{editorTitle}</h3>
          <small>{editorHint}</small>
        </span>
        <Button
          variant="ghost"
          size="icon"
          onClick={onClose}
          aria-label="关闭编辑抽屉"
        >
          <X size={18} />
        </Button>
      </header>
      <div className="admin-disclosure-stack">
        {!isImageOnlyModule ? (
          <AdminDisclosure title="展示内容">
            {usesOfferConfig ? (
              <>
                <label>
                  {primaryLabel}
                  <Input
                    value={draft.title ?? ""}
                    onChange={(event) =>
                      onDraft({ ...draft, title: event.target.value })
                    }
                  />
                </label>
                <label>
                  {isHotelModule ? "酒店描述" : "活动描述"}
                  <Textarea
                    value={draft.description ?? ""}
                    onChange={(event) =>
                      onDraft({ ...draft, description: event.target.value })
                    }
                    rows={3}
                  />
                </label>
              </>
            ) : (
              <>
                <label>
                  {primaryLabel}
                  <Input
                    value={String(draft[primaryKey] ?? "")}
                    onChange={(event) =>
                      onDraft({ ...draft, [primaryKey]: event.target.value })
                    }
                  />
                </label>
                {moduleId === "heroSlides" || isDestinationHeroModule ? (
                  <label>
                    {isDestinationHeroModule ? "上方小标题" : "副标题"}
                    <Input
                      value={draft.kicker ?? ""}
                      onChange={(event) =>
                        onDraft({ ...draft, kicker: event.target.value })
                      }
                    />
                  </label>
                ) : null}
                {isDestinationRegionModule ? (
                  <>
                    <label>
                      搜索关键词
                      <Input
                        value={draft.keyword ?? ""}
                        onChange={(event) =>
                          onDraft({ ...draft, keyword: event.target.value })
                        }
                        placeholder="为空时使用区域名称"
                      />
                    </label>
                    <label>
                      景点摘要
                      <Textarea
                        value={draft.spots ?? ""}
                        onChange={(event) =>
                          onDraft({ ...draft, spots: event.target.value })
                        }
                        rows={3}
                      />
                    </label>
                  </>
                ) : null}
                {isCardContentModule ? (
                  <label>
                    卡片描述
                    <Textarea
                      value={draft.description ?? ""}
                      onChange={(event) =>
                        onDraft({ ...draft, description: event.target.value })
                      }
                      rows={3}
                    />
                  </label>
                ) : null}
              </>
            )}
          </AdminDisclosure>
        ) : null}
        {isMoreServicesModule ? (
          <AdminDisclosure title="跳转配置">
            <div className="form-grid compact-grid">
              <label>
                跳转类型
                <NativeSelect
                  value={draft.targetType ?? ""}
                  onChange={(event) =>
                    onDraft({ ...draft, targetType: event.target.value })
                  }
                >
                  {moreServicesTargetOptions.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </NativeSelect>
              </label>
              <label>
                目标参数
                <Input
                  value={draft.targetValue ?? ""}
                  onChange={(event) =>
                    onDraft({ ...draft, targetValue: event.target.value })
                  }
                  placeholder="可选，如需求页目的地"
                />
              </label>
            </div>
          </AdminDisclosure>
        ) : null}
        {usesOfferConfig ? (
          <AdminDisclosure title="价格信息">
            <div className="form-grid compact-grid">
              <label>
                价格
                <Input
                  type="number"
                  value={draft.priceAmount ?? ""}
                  onChange={(event) =>
                    onDraft({
                      ...draft,
                      priceAmount: event.target.value
                        ? Number(event.target.value)
                        : null,
                    })
                  }
                />
              </label>
              <label>
                价格单位
                <Input
                  value={draft.priceUnit ?? (isHotelModule ? "起/晚" : "起/人")}
                  onChange={(event) =>
                    onDraft({ ...draft, priceUnit: event.target.value })
                  }
                />
              </label>
            </div>
          </AdminDisclosure>
        ) : null}
        {usesOfferConfig ? (
          <AdminDisclosure title={isHotelModule ? "酒店标签" : "活动标签"}>
            <CampaignTagEditor
              tags={draft.tags ?? []}
              onChange={(tags) => onDraft({ ...draft, tags })}
            />
          </AdminDisclosure>
        ) : null}
        {!isTextOnlyModule ? (
          <AdminDisclosure title={isImageOnlyModule ? primaryLabel : usesOfferConfig ? isHotelModule ? "酒店封面图" : "活动封面图" : isDestinationHeroModule ? "主视觉图片" : isMoreServicesModule ? "服务卡片背景图" : "资源图片"}>
            <SingleImageUploader
              value={usesOfferConfig ? draft.coverImage ?? draft.image : draft.image}
              onChange={(image) =>
                onDraft(
                  isCampaignModule
                    ? { ...draft, coverImage: image }
                    : isHotelModule
                      ? { ...draft, coverImage: image, image }
                      : { ...draft, image },
                )
              }
              group={moduleId}
            />
          </AdminDisclosure>
        ) : null}
        <AdminDisclosure title={isImageOnlyModule || usesOfferConfig ? "显示状态" : "排序与状态"}>
          {usesOfferConfig ? (
            <label className="switch-line">
              <Switch
                checked={draft.status === "published" || (isHotelModule && !draft.status && Boolean(draft.isActive))}
                onCheckedChange={(checked) =>
                  onDraft(
                    isHotelModule
                      ? { ...draft, status: checked ? "published" : "draft", isActive: checked }
                      : { ...draft, status: checked ? "published" : "draft" },
                  )
                }
              />
              前台启用
            </label>
          ) : (
            <>
              {!isImageOnlyModule ? (
                <label>
                  排序值
                  <Input
                    type="number"
                    value={draft.sortOrder ?? 0}
                    onChange={(event) =>
                      onDraft({ ...draft, sortOrder: Number(event.target.value) })
                    }
                  />
                </label>
              ) : null}
              {moduleId === "destinations" ? (
                <label className="switch-line">
                  <Switch
                    checked={Boolean(draft.isHot)}
                    onCheckedChange={(checked) =>
                      onDraft({ ...draft, isHot: checked })
                    }
                  />
                  设为热门
                </label>
              ) : null}
              <label className="switch-line">
                <Switch
                  checked={Boolean(draft.isActive)}
                  onCheckedChange={(checked) =>
                    onDraft({ ...draft, isActive: checked })
                  }
                />
                前台启用
              </label>
            </>
          )}
        </AdminDisclosure>
      </div>
      <footer className="drawer-editor-footer">
        <Button variant="outline" onClick={onClose} disabled={saving}>
          取消
        </Button>
        <Button
          className="primary-action compact"
          onClick={onSave}
          disabled={saving}
        >
          <Save size={17} />
          {saving ? "保存中" : isCreating ? "创建" : "保存"}
        </Button>
      </footer>
    </div>
  );
}
