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

import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import type { CustomWorldLibraryEntry } from '../../../packages/shared/src/contracts/runtime';
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
import type { CreationEntryConfig } from '../../services/creationEntryConfigService';
import type { CustomWorldProfile } from '../../types';
import type {
  PlatformCreationTypeCard,
  PlatformCreationTypeId,
} from '../platform-entry/platformEntryCreationTypes';
import { isPlatformCreationTypeVisible } from '../platform-entry/platformEntryCreationTypes';
import {
  buildCreationWorkShelfItems,
  type CreationWorkShelfItem,
  type CreationWorkShelfMetricId,
} from './creationWorkShelf';
import { CustomWorldCreationStartCard } from './CustomWorldCreationStartCard';
import { CustomWorldWorkCard } from './CustomWorldWorkCard';
import {
  type CustomWorldWorkFilter,
  CustomWorldWorkTabs,
} from './CustomWorldWorkTabs';

// 中文注释：草稿在手机端保持双列，已发布卡片由卡片自身跨两列展示公开指标。
const WORK_GRID_CLASS =
  'grid grid-cols-2 gap-2.5 sm:gap-3 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4';
const WORK_METRIC_CACHE_KEY = 'genarrative.creationHub.publishedMetrics.v1';

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

type CustomWorldCreationHubProps = {
  items: CustomWorldWorkSummary[];
  loading: boolean;
  error: string | null;
  onRetry: () => void;
  createError?: string | null;
  createBusy?: boolean;
  entryConfig: CreationEntryConfig;
  creationTypes: readonly PlatformCreationTypeCard[];
  onCreateType: (type: PlatformCreationTypeId) => void;
  onOpenDraft: (item: CustomWorldWorkSummary) => void;
  onEnterPublished: (profileId: string) => void;
  onDeletePublished?: ((item: CustomWorldWorkSummary) => void) | null;
  deletingWorkId?: string | null;
  rpgLibraryEntries?: CustomWorldLibraryEntry<CustomWorldProfile>[];
  bigFishItems?: BigFishWorkSummary[];
  onOpenBigFishDetail?: (item: BigFishWorkSummary) => void;
  onDeleteBigFish?: ((item: BigFishWorkSummary) => void) | null;
  match3dItems?: Match3DWorkSummary[];
  onOpenMatch3DDetail?: (item: Match3DWorkSummary) => void;
  onDeleteMatch3D?: ((item: Match3DWorkSummary) => void) | null;
  squareHoleItems?: SquareHoleWorkSummary[];
  onOpenSquareHoleDetail?: (item: SquareHoleWorkSummary) => void;
  onDeleteSquareHole?: ((item: SquareHoleWorkSummary) => void) | null;
  puzzleItems?: PuzzleWorkSummary[];
  onOpenPuzzleDetail?: (item: PuzzleWorkSummary) => void;
  onDeletePuzzle?: ((item: PuzzleWorkSummary) => void) | null;
  onClaimPuzzlePointIncentive?: ((item: PuzzleWorkSummary) => void) | null;
  claimingPuzzleProfileId?: string | null;
  visualNovelItems?: VisualNovelWorkSummary[];
  onOpenVisualNovelDetail?: ((item: VisualNovelWorkSummary) => void) | null;
  onDeleteVisualNovel?: ((item: VisualNovelWorkSummary) => void) | null;
  getWorkState?: (
    item: CreationWorkShelfItem,
  ) => { isGenerating?: boolean; hasUnreadUpdate?: boolean } | null;
  onOpenShelfItem?: (item: CreationWorkShelfItem) => void;
  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 时降级为无缓存动画，不影响作品列表使用。
  }
}

export function CustomWorldCreationHub({
  items,
  loading,
  error,
  onRetry,
  createError = null,
  createBusy = false,
  entryConfig,
  creationTypes,
  onCreateType,
  onOpenDraft,
  onEnterPublished,
  onDeletePublished = null,
  deletingWorkId = null,
  rpgLibraryEntries = [],
  bigFishItems = [],
  onOpenBigFishDetail,
  onDeleteBigFish = null,
  match3dItems = [],
  onOpenMatch3DDetail,
  onDeleteMatch3D = null,
  squareHoleItems = [],
  onOpenSquareHoleDetail,
  onDeleteSquareHole = null,
  puzzleItems = [],
  onOpenPuzzleDetail,
  onDeletePuzzle = null,
  onClaimPuzzlePointIncentive = null,
  claimingPuzzleProfileId = null,
  visualNovelItems = [],
  onOpenVisualNovelDetail = null,
  onDeleteVisualNovel = null,
  getWorkState,
  onOpenShelfItem,
  mode = 'full',
}: CustomWorldCreationHubProps) {
  const [activeFilter, setActiveFilter] =
    useState<CustomWorldWorkFilter>('all');
  const isSquareHoleCreationVisible = isPlatformCreationTypeVisible(
    creationTypes,
    'square-hole',
  );
  const shelfItems = useMemo(
    () =>
      buildCreationWorkShelfItems({
        rpgItems: items,
        rpgLibraryEntries,
        bigFishItems,
        match3dItems,
        squareHoleItems: isSquareHoleCreationVisible ? squareHoleItems : [],
        puzzleItems,
        visualNovelItems,
        canDeleteRpg: Boolean(onDeletePublished),
        canDeleteBigFish: Boolean(onDeleteBigFish),
        canDeleteMatch3D: Boolean(onDeleteMatch3D),
        canDeleteSquareHole:
          isSquareHoleCreationVisible && Boolean(onDeleteSquareHole),
        canDeletePuzzle: Boolean(onDeletePuzzle),
        canDeleteVisualNovel: Boolean(onDeleteVisualNovel),
        onOpenRpgDraft: onOpenDraft,
        onEnterRpgPublished: onEnterPublished,
        onDeleteRpg: onDeletePublished ?? undefined,
        onOpenBigFishDetail,
        onDeleteBigFish: onDeleteBigFish ?? undefined,
        onOpenMatch3DDetail,
        onDeleteMatch3D: onDeleteMatch3D ?? undefined,
        onOpenSquareHoleDetail,
        onDeleteSquareHole: onDeleteSquareHole ?? undefined,
        onOpenPuzzleDetail,
        onDeletePuzzle: onDeletePuzzle ?? undefined,
        onClaimPuzzlePointIncentive: onClaimPuzzlePointIncentive ?? undefined,
        onOpenVisualNovelDetail: onOpenVisualNovelDetail ?? undefined,
        onDeleteVisualNovel: onDeleteVisualNovel ?? undefined,
        getItemState: getWorkState,
      }),
    [
      bigFishItems,
      isSquareHoleCreationVisible,
      items,
      match3dItems,
      onDeleteBigFish,
      onDeleteMatch3D,
      onDeleteSquareHole,
      onDeletePublished,
      onDeletePuzzle,
      onDeleteVisualNovel,
      onClaimPuzzlePointIncentive,
      onOpenBigFishDetail,
      onOpenDraft,
      onOpenMatch3DDetail,
      onOpenPuzzleDetail,
      onOpenSquareHoleDetail,
      onOpenVisualNovelDetail,
      onEnterPublished,
      getWorkState,
      puzzleItems,
      rpgLibraryEntries,
      squareHoleItems,
      visualNovelItems,
    ],
  );
  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],
  );


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

    return item.actions.delete ?? null;
  }

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

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

  return (
    <div className="platform-page-stage platform-remap-surface 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}
            error={createError}
            entryConfig={entryConfig}
            creationTypes={creationTypes}
            onCreateType={onCreateType}
          />
        ) : null}

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

        {showWorkShelf && error ? (
          <div className="platform-banner platform-banner--danger rounded-[1.4rem] px-4 py-4 text-sm leading-7">
            <div>{error}</div>
            <button
              type="button"
              onClick={onRetry}
              className="platform-button platform-button--ghost mt-3 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={() => {
                    onOpenShelfItem?.(item);
                    item.actions.open();
                  }}
                  onDelete={buildDeleteAction(item)}
                  deleteBusy={deletingWorkId === item.id}
                  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 };
