import { useEffect, useMemo, useState } from 'react';

import { resolveSelectionStageFromPath } from '../../routing/appPageRoutes';
import type { CreationEntryConfig } from '../../services/creationEntryConfigService';
import type { PublishShareModalPayload } from '../common/publishShareModalModel';
import type {
  PlatformCreationTypeCard,
  PlatformCreationTypeId,
} from '../platform-entry/platformEntryCreationTypes';
import {
  type CreationWorkShelfItem,
  type CreationWorkShelfMetricId,
  getCreationWorkShelfItemTime,
} from './creationWorkShelf';
import {
  CustomWorldCreationStartCard,
} from './CustomWorldCreationStartCard';
import { CustomWorldWorkCard } from './CustomWorldWorkCard';
import {
  type CustomWorldWorkFilter,
  CustomWorldWorkTabs,
} from './CustomWorldWorkTabs';

const WORK_GRID_CLASS =
  'creation-work-list grid min-w-0 gap-3 sm:gap-3.5 xl:gap-4';
const WORK_METRIC_CACHE_KEY = 'genarrative.creationHub.publishedMetrics.v1';
const RECENT_CREATION_WINDOW_DAYS = 7;
const RECENT_CREATION_WINDOW_MS =
  RECENT_CREATION_WINDOW_DAYS * 24 * 60 * 60 * 1000;

type WorkMetricSnapshot = Record<
  string,
  Partial<Record<CreationWorkShelfMetricId, number>>
>;

type CustomWorldCreationHubProps = {
  shelfItems: CreationWorkShelfItem[];
  loading: boolean;
  error: string | null;
  onRetry: () => void;
  createBusy?: boolean;
  entryConfig: CreationEntryConfig;
  creationTypes: readonly PlatformCreationTypeCard[];
  onCreateType: (type: PlatformCreationTypeId) => void;
  deletingWorkId?: string | null;
  claimingPuzzleProfileId?: string | null;
  onOpenShelfItem?: (item: CreationWorkShelfItem) => void;
  onShareWork?: ((payload: PublishShareModalPayload) => void) | null;
  // 中文注释：底部加号入口可传入后端作品架摘要，用于推导最近使用过的模板。
  recentWorkItems?: CreationWorkShelfItem[];
  mode?: 'full' | 'start-only' | 'works-only';
};

function EmptyState({ title }: { title: string }) {
  return (
    <div className="platform-subpanel flex min-h-[14rem] flex-col items-center justify-center rounded-[1.6rem] px-6 py-8 text-center">
      <div className="text-lg font-semibold text-[var(--platform-text-strong)]">
        {title}
      </div>
    </div>
  );
}

function buildWorkMetricCacheItemKey(item: CreationWorkShelfItem) {
  return `${item.kind}:${item.id}`;
}

function readWorkMetricSnapshot(): WorkMetricSnapshot {
  if (typeof window === 'undefined') {
    return {};
  }

  try {
    const rawSnapshot = window.sessionStorage.getItem(WORK_METRIC_CACHE_KEY);
    if (!rawSnapshot) {
      return {};
    }

    const parsed = JSON.parse(rawSnapshot) as WorkMetricSnapshot;
    return parsed && typeof parsed === 'object' ? parsed : {};
  } catch {
    return {};
  }
}

function writeWorkMetricSnapshot(items: CreationWorkShelfItem[]) {
  if (typeof window === 'undefined') {
    return;
  }

  const snapshot: WorkMetricSnapshot = {};
  for (const item of items) {
    if (item.status !== 'published' || item.metrics.length === 0) {
      continue;
    }

    snapshot[buildWorkMetricCacheItemKey(item)] = Object.fromEntries(
      item.metrics.map((metric) => [metric.id, metric.value]),
    );
  }

  // 中文注释：缓存只作为下一次进入创作页的数字动画起点，真实展示值仍以接口返回为准。
  if (Object.keys(snapshot).length === 0) {
    return;
  }

  try {
    window.sessionStorage.setItem(
      WORK_METRIC_CACHE_KEY,
      JSON.stringify(snapshot),
    );
  } catch {
    // 中文注释：浏览器禁用 sessionStorage 时降级为无缓存动画，不影响作品列表使用。
  }
}

function resolveShelfShareStage(
  sharePath: string,
): PublishShareModalPayload['stage'] | null {
  let pathname = '';
  try {
    pathname = new URL(sharePath, 'https://genarrative.local').pathname;
  } catch {
    pathname = sharePath.split(/[?#]/u)[0] ?? '';
  }

  const stage = resolveSelectionStageFromPath(pathname);
  return stage === 'platform' ? null : stage;
}

function buildCreationWorkShelfSharePayload(
  item: CreationWorkShelfItem,
): PublishShareModalPayload | null {
  const publicWorkCode = item.publicWorkCode?.trim();
  const sharePath = item.sharePath?.trim();
  if (!publicWorkCode || !sharePath) {
    return null;
  }

  const stage = resolveShelfShareStage(sharePath);
  if (!stage) {
    return null;
  }

  return {
    title: item.title,
    publicWorkCode,
    stage,
  };
}

/** 渲染底部加号创作入口页与草稿作品架，最近创作复用最近使用过的模板入口。 */
export function CustomWorldCreationHub({
  shelfItems,
  loading,
  error,
  onRetry,
  createBusy = false,
  entryConfig,
  creationTypes,
  onCreateType,
  deletingWorkId = null,
  claimingPuzzleProfileId = null,
  onOpenShelfItem,
  onShareWork = null,
  recentWorkItems: recentWorkSourceItems,
  mode = 'full',
}: CustomWorldCreationHubProps) {
  const [activeFilter, setActiveFilter] =
    useState<CustomWorldWorkFilter>('all');
  const [metricSnapshot] = useState<WorkMetricSnapshot>(() =>
    readWorkMetricSnapshot(),
  );
  useEffect(() => {
    writeWorkMetricSnapshot(shelfItems);
  }, [shelfItems]);
  const draftCount = shelfItems.filter(
    (entry) => entry.status === 'draft',
  ).length;
  const publishedCount = shelfItems.filter(
    (entry) => entry.status === 'published',
  ).length;
  const filteredItems = useMemo(
    () =>
      shelfItems.filter((entry) =>
        activeFilter === 'all' ? true : entry.status === activeFilter,
      ),
    [activeFilter, shelfItems],
  );
  // 中文注释：最近创作只取 7 天内作品架摘要，再推导模板 ID 复用模板入口卡片。
  const recentCreationCutoffMs = Date.now() - RECENT_CREATION_WINDOW_MS;
  const recentWorkItems =
    mode === 'start-only'
      ? (recentWorkSourceItems ?? shelfItems)
          .filter(
            (item) =>
              getCreationWorkShelfItemTime(item.updatedAt) >=
              recentCreationCutoffMs,
          )
          .slice(0, 4)
      : [];
  const recentCreationTypeIds = [
    ...new Set(recentWorkItems.map((item) => item.kind)),
  ];

  function handleOpenShelfItem(item: CreationWorkShelfItem) {
    onOpenShelfItem?.(item);
    // 中文注释：玩法差异由 Work Shelf Adapter 承载，Hub 只负责响应卡片点击。
    item.actions.open();
  }

  function buildDeleteAction(item: CreationWorkShelfItem) {
    if (!item.canDelete) {
      return null;
    }

    return item.actions.delete ?? null;
  }

  function buildShareAction(item: CreationWorkShelfItem) {
    const payload = buildCreationWorkShelfSharePayload(item);
    if (!payload) {
      return null;
    }

    return () => {
      onShareWork?.(payload);
    };
  }

  function buildPointIncentiveAction(item: CreationWorkShelfItem) {
    return item.actions.claimPointIncentive ?? null;
  }

  const showStartCard = mode !== 'works-only';
  const showWorkShelf = mode !== 'start-only';

  return (
    <div className="platform-remap-surface w-full space-y-4 px-3 pb-4 pt-3 sm:px-4 sm:pt-4 xl:px-5 xl:pb-5 xl:pt-5">
      <div className="space-y-4 xl:space-y-3">
        {showStartCard ? (
          <CustomWorldCreationStartCard
            busy={createBusy}
            entryConfig={entryConfig}
            creationTypes={creationTypes}
            recentCreationTypeIds={recentCreationTypeIds}
            recentWindowDays={RECENT_CREATION_WINDOW_DAYS}
            onCreateType={onCreateType}
          />
        ) : null}

        {showWorkShelf ? (
          <CustomWorldWorkTabs
            activeFilter={activeFilter}
            draftCount={draftCount}
            publishedCount={publishedCount}
            onChange={setActiveFilter}
          />
        ) : null}

        {showWorkShelf && error ? (
          <div className="flex justify-end">
            <button
              type="button"
              onClick={onRetry}
              className="platform-button platform-button--ghost min-h-0 rounded-full px-4 py-2 text-sm"
            >
              重试
            </button>
          </div>
        ) : null}

        {showWorkShelf ? (
          loading ? (
            <div className={WORK_GRID_CLASS}>
              {Array.from({ length: 3 }).map((_, index) => (
                <div
                  key={`skeleton-${index}`}
                  className="platform-subpanel min-h-[10.5rem] rounded-[1.2rem] p-3 sm:min-h-[12rem] sm:rounded-[1.6rem] sm:p-5"
                >
                  <div className="h-4 w-20 rounded-full bg-[var(--platform-track-fill)]" />
                  <div className="mt-5 h-6 w-24 rounded-full bg-[var(--platform-track-fill)] sm:mt-6 sm:h-8 sm:w-36" />
                  <div className="mt-3 h-3 w-full rounded-full bg-[var(--platform-track-fill)] sm:mt-4 sm:h-4" />
                  <div className="mt-2 h-4 w-4/5 rounded-full bg-[var(--platform-track-fill)]" />
                  <div className="mt-6 flex flex-col gap-2 sm:mt-8 sm:flex-row">
                    <div className="h-6 w-16 rounded-full bg-[var(--platform-track-fill)] sm:h-7 sm:w-20" />
                    <div className="h-6 w-16 rounded-full bg-[var(--platform-track-fill)] sm:h-7 sm:w-20" />
                  </div>
                </div>
              ))}
            </div>
          ) : filteredItems.length > 0 ? (
            <div className={WORK_GRID_CLASS}>
              {filteredItems.map((item) => (
                <CustomWorldWorkCard
                  key={`${item.kind}-${item.id}`}
                  item={item}
                  previousMetricValues={
                    metricSnapshot[buildWorkMetricCacheItemKey(item)]
                  }
                  onOpen={() => {
                    handleOpenShelfItem(item);
                  }}
                  onDelete={buildDeleteAction(item)}
                  deleteBusy={deletingWorkId === item.id}
                  onShare={buildShareAction(item)}
                  onClaimPointIncentive={buildPointIncentiveAction(item)}
                  pointIncentiveBusy={
                    item.source.kind === 'puzzle' &&
                    claimingPuzzleProfileId === item.source.item.profileId
                  }
                />
              ))}
            </div>
          ) : shelfItems.length === 0 ? (
            <EmptyState title="还没有作品" />
          ) : (
            <EmptyState title="当前筛选下没有内容" />
          )
        ) : null}
      </div>
    </div>
  );
}

export type { CustomWorldWorkFilter };
