import { type ReactNode,useMemo, useState } from 'react';

import { normalizeCustomWorldLandmarks } from '../data/customWorldSceneGraph';
import { Character, CustomWorldProfile } from '../types';
import { getNineSliceStyle, UI_CHROME } from '../uiAssets';
import { CustomWorldEntityCatalog, type ResultTab } from './CustomWorldEntityCatalog';
import { type CustomWorldEditorTarget,CustomWorldEntityEditorModal } from './CustomWorldEntityEditorModal';

interface CustomWorldResultViewProps {
  profile: CustomWorldProfile;
  previewCharacters: Character[];
  isGenerating: boolean;
  progress: number;
  progressLabel: string;
  error: string | null;
  onBack: () => void;
  onEditSetting: () => void;
  onRegenerate: () => void;
  onContinueExpand?: () => void;
  onSave: () => void;
  onProfileChange: (profile: CustomWorldProfile) => void;
}

function SmallButton({
  onClick,
  children,
  tone = 'default',
  disabled = false,
}: {
  onClick: () => void;
  children: ReactNode;
  tone?: 'default' | 'sky';
  disabled?: boolean;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      disabled={disabled}
      className={`rounded-full border px-3 py-2 text-sm transition-colors ${
        tone === 'sky'
          ? 'border-sky-300/20 bg-sky-500/10 text-sky-100 hover:text-white'
          : 'border-white/10 bg-black/20 text-zinc-300 hover:text-white'
      } ${disabled ? 'cursor-not-allowed opacity-45' : ''}`}
    >
      {children}
    </button>
  );
}

function getCreateTargetByTab(activeTab: ResultTab): CustomWorldEditorTarget | null {
  if (activeTab === 'playable') return { kind: 'playable', mode: 'create' };
  if (activeTab === 'story') return { kind: 'story', mode: 'create' };
  if (activeTab === 'landmarks') return { kind: 'landmark', mode: 'create' };
  return null;
}

function getCreateLabelByTab(activeTab: ResultTab) {
  if (activeTab === 'playable') return '新增可扮演角色';
  if (activeTab === 'story') return '新增场景角色';
  if (activeTab === 'landmarks') return '新增场景';
  return '';
}

function removeStoryNpcsFromProfile(
  profile: CustomWorldProfile,
  ids: string[],
) {
  const idSet = new Set(ids);
  const nextStoryNpcs = profile.storyNpcs.filter((npc) => !idSet.has(npc.id));

  return {
    ...profile,
    storyNpcs: nextStoryNpcs,
    landmarks: normalizeCustomWorldLandmarks({
      landmarks: profile.landmarks.map((landmark) => ({
        ...landmark,
        sceneNpcIds: landmark.sceneNpcIds.filter((npcId) => !idSet.has(npcId)),
      })),
      storyNpcs: nextStoryNpcs,
    }),
  } satisfies CustomWorldProfile;
}

function removeLandmarksFromProfile(profile: CustomWorldProfile, ids: string[]) {
  const idSet = new Set(ids);
  const nextLandmarks = profile.landmarks.filter(
    (landmark) => !idSet.has(landmark.id),
  );

  return {
    ...profile,
    landmarks: normalizeCustomWorldLandmarks({
      landmarks: nextLandmarks.map((landmark) => ({
        ...landmark,
        connections: landmark.connections.filter(
          (connection) => !idSet.has(connection.targetLandmarkId),
        ),
      })),
      storyNpcs: profile.storyNpcs,
    }),
  } satisfies CustomWorldProfile;
}

export function CustomWorldResultView({
  profile,
  previewCharacters,
  isGenerating,
  progress,
  progressLabel,
  error,
  onBack,
  onEditSetting,
  onRegenerate: triggerRegenerate,
  onContinueExpand,
  onSave,
  onProfileChange,
}: CustomWorldResultViewProps) {
  const [editorTarget, setEditorTarget] = useState<CustomWorldEditorTarget | null>(null);
  const [activeTab, setActiveTab] = useState<ResultTab>('world');

  const createTarget = useMemo(() => getCreateTargetByTab(activeTab), [activeTab]);
  const createLabel = useMemo(() => getCreateLabelByTab(activeTab), [activeTab]);
  const onRegenerate = () => {
    if (isGenerating) return;

    const confirmed = window.confirm(
      `确认重新生成“${profile.name}”吗？\n\n重新生成会重新生成当前世界中的所有信息，包括你修改和新增的所有内容。`,
    );
    if (!confirmed) return;

    triggerRegenerate();
  };

  const handleDeleteStoryNpcs = (ids: string[]) => {
    if (ids.length === 0) return;
    onProfileChange(removeStoryNpcsFromProfile(profile, ids));
  };

  const handleDeleteLandmarks = (ids: string[]) => {
    if (ids.length === 0) return;
    onProfileChange(removeLandmarksFromProfile(profile, ids));
  };

  return (
    <div className="flex h-full min-h-0 flex-col">
      <div className="mb-4 flex justify-start">
        <button
          type="button"
          onClick={onBack}
          disabled={isGenerating}
          className={`self-start rounded-full border border-white/10 bg-black/18 px-3 py-1.5 text-[11px] text-zinc-300 transition-colors hover:text-white ${isGenerating ? 'opacity-45' : ''}`}
        >
          返回
        </button>
      </div>

      <div className="min-h-0 flex-1 overflow-hidden">
        <CustomWorldEntityCatalog
          profile={profile}
          previewCharacters={previewCharacters}
          activeTab={activeTab}
          onActiveTabChange={setActiveTab}
          onEditTarget={setEditorTarget}
          onProfileChange={onProfileChange}
          onDeleteStoryNpcs={handleDeleteStoryNpcs}
          onDeleteLandmarks={handleDeleteLandmarks}
          createActionLabel={createLabel}
          onCreateAction={createTarget ? () => setEditorTarget(createTarget) : undefined}
        />
      </div>

      {isGenerating && (
        <div className="mt-3 rounded-2xl border border-sky-400/18 bg-sky-500/10 px-4 py-4">
          <div className="flex items-center justify-between gap-3">
            <div className="text-sm font-semibold text-white">{progressLabel}</div>
            <div className="text-xs text-sky-100">{Math.round(progress)}%</div>
          </div>
          <div className="mt-3 h-3 overflow-hidden rounded-full border border-white/10 bg-black/35">
            <div
              className="h-full bg-[linear-gradient(90deg,#38bdf8_0%,#67e8f9_48%,#fef08a_100%)] transition-[width] duration-300"
              style={{ width: `${Math.max(0, Math.min(100, progress))}%` }}
            />
          </div>
        </div>
      )}

      {error ? (
        <div className="mt-3 rounded-2xl border border-rose-400/18 bg-rose-500/10 px-4 py-3 text-sm leading-6 text-rose-100">
          {error}
        </div>
      ) : null}

      <div className="mt-4 flex flex-col gap-3">
        {profile.generationStatus === 'key_only' ? (
          <div className="rounded-2xl border border-amber-300/16 bg-amber-500/10 px-4 py-3 text-sm leading-6 text-amber-100">
            当前世界处于快速预览模式，只生成了关键对象。继续补全后，系统会生成长尾场景角色与完整场景网络。
          </div>
        ) : null}
        <div className="flex items-center justify-end gap-3">
          <SmallButton onClick={onEditSetting}>修改设定</SmallButton>
          <SmallButton onClick={onRegenerate} tone="sky">重新生成</SmallButton>
          {profile.generationStatus === 'key_only' && onContinueExpand ? (
            <SmallButton onClick={onContinueExpand} tone="sky" disabled={isGenerating}>
              继续补全世界
            </SmallButton>
          ) : null}
          <button
            type="button"
            onClick={onSave}
            disabled={isGenerating}
            className={`pixel-nine-slice pixel-pressable text-left ${isGenerating ? 'opacity-55' : ''}`}
            style={getNineSliceStyle(UI_CHROME.choiceButton, { paddingX: 16, paddingY: 10 })}
          >
            <div className="flex items-center justify-between gap-4">
              <span className="text-sm font-semibold text-white">保存并进入世界</span>
              <span className="text-white/60">→</span>
            </div>
          </button>
        </div>
      </div>

      <CustomWorldEntityEditorModal
        profile={profile}
        target={editorTarget}
        onClose={() => setEditorTarget(null)}
        onProfileChange={onProfileChange}
      />
    </div>
  );
}
