import { ArrowLeft } from 'lucide-react';

import type { CustomWorldGenerationProgress } from '../../packages/shared/src/contracts/runtime';
import type { CustomWorldStructuredAnchorEntry } from '../services/customWorldAgentGenerationProgress';
import {
  GenerationCurrentStepCard,
  GenerationPageBackdrop,
  GenerationProgressHero,
} from './GenerationProgressHero';

interface CustomWorldGenerationViewProps {
  settingText: string;
  anchorEntries?: CustomWorldStructuredAnchorEntry[];
  progress: CustomWorldGenerationProgress | null;
  isGenerating: boolean;
  error?: string | null;
  onBack: () => void;
  onEditSetting: () => void;
  onRetry: () => void;
  onInterrupt?: () => void;
  backLabel?: string;
  settingActionLabel?: string | null;
  retryLabel?: string;
  interruptLabel?: string;
  settingTitle?: string;
  settingDescription?: string | null;
  progressTitle?: string;
  activeBadgeLabel?: string;
  pausedBadgeLabel?: string;
  idleBadgeLabel?: string;
  structuredEmptyText?: string;
  hideBatchModule?: boolean;
}

function formatDuration(ms: number) {
  const safeMs = Math.max(0, Math.round(ms));
  const totalSeconds = Math.ceil(safeMs / 1000);
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;

  if (minutes <= 0) {
    return `${Math.max(1, seconds)} 秒`;
  }

  if (seconds === 0) {
    return `${minutes} 分钟`;
  }

  return `${minutes} 分 ${seconds} 秒`;
}

function getProgressPercentage(progress: CustomWorldGenerationProgress | null) {
  return Math.max(0, Math.min(100, progress?.overallProgress ?? 0));
}

function getStepProgressPercentage(step: {
  completed: number;
  total: number;
  status: string;
}) {
  if (step.status === 'completed') {
    return 100;
  }

  if (step.total <= 0) {
    return 0;
  }

  return Math.max(
    0,
    Math.min(100, Math.round((step.completed / step.total) * 100)),
  );
}

function getStepStatusLabel(step: { status: string }) {
  if (step.status === 'completed') {
    return '完成';
  }

  if (step.status === 'active') {
    return '进行中';
  }

  return '待处理';
}

function resolveCurrentGenerationStep(
  progress: CustomWorldGenerationProgress | null,
) {
  const steps = progress?.steps ?? [];
  return (
    steps.find((step) => step.status === 'active') ??
    steps[progress?.activeStepIndex ?? -1] ??
    steps.find((step) => step.status === 'pending') ??
    steps.at(-1) ??
    null
  );
}

function buildFallbackRenderKey(
  value: string | null | undefined,
  fallback: string,
) {
  const normalizedValue = value?.trim();
  return normalizedValue ? normalizedValue : fallback;
}

export function CustomWorldGenerationView({
  settingText,
  anchorEntries = [],
  progress,
  isGenerating,
  onBack,
  onEditSetting,
  onRetry,
  onInterrupt,
  backLabel = '返回',
  settingActionLabel = '修改设定',
  retryLabel = '重新开始生成',
  interruptLabel = '中断世界生成',
  settingTitle = '玩家设定',
  settingDescription = '这段文本会直接驱动本轮世界框架、角色与场景生成。',
  progressTitle = '生成进度',
  activeBadgeLabel = '世界建设中',
  idleBadgeLabel = '等待操作',
  structuredEmptyText = '正在整理当前设定结构，请稍后。',
  hideBatchModule = false,
}: CustomWorldGenerationViewProps) {
  void hideBatchModule;
  const progressValue = getProgressPercentage(progress);
  const currentStep = resolveCurrentGenerationStep(progress);
  const currentStepProgress = currentStep
    ? getStepProgressPercentage(currentStep)
    : progressValue;
  const currentStepLabel = currentStep?.label ?? progress?.phaseLabel ?? '准备生成';
  const currentStepStatusLabel = currentStep
    ? getStepStatusLabel(currentStep)
    : isGenerating
      ? '进行中'
      : '待处理';
  const hasStructuredAnchors = anchorEntries.length > 0;
  // 允许不同生成场景按需隐藏第二模块的说明和次级返回动作。
  const normalizedSettingActionLabel = settingActionLabel?.trim() ?? '';
  const normalizedSettingDescription = settingDescription?.trim() ?? '';
  const hasSettingActionLabel = normalizedSettingActionLabel.length > 0;
  const hasSettingDescription = normalizedSettingDescription.length > 0;
  const estimatedWaitText =
    progress?.estimatedRemainingMs != null
      ? formatDuration(progress.estimatedRemainingMs)
      : '校准中';
  const elapsedText =
    progress != null ? formatDuration(progress.elapsedMs) : '启动中';

  return (
    <div
      className="relative isolate z-[1] -mx-3 -my-3 flex h-[calc(100%+1.5rem)] min-h-0 flex-col overflow-y-auto overscroll-y-contain bg-transparent px-4 pb-[max(1.25rem,env(safe-area-inset-bottom))] pt-4 text-[#3d1f10] sm:mx-0 sm:my-0 sm:h-full sm:rounded-[2rem] sm:px-5 sm:pt-5"
      style={{ WebkitOverflowScrolling: 'touch' }}
    >
      <GenerationPageBackdrop />
      <div className="relative z-10 mb-6 flex shrink-0 items-center justify-between gap-3 py-2 sm:mb-6">
        <button
          type="button"
          onClick={onBack}
          className="inline-flex items-center gap-2 rounded-full bg-transparent px-0 py-2 text-xs font-black text-[#171411] sm:text-sm"
        >
          <ArrowLeft className="h-5 w-5 shrink-0" strokeWidth={2.6} />
          <span className="break-keep">{backLabel}</span>
        </button>
        <div className="rounded-full border border-[#f05816] bg-white/72 px-3 py-1.5 text-[11px] font-black tracking-[0.08em] text-[#df6118] shadow-[0_12px_30px_rgba(214,77,31,0.08)] backdrop-blur-md sm:px-4 sm:text-xs">
          {isGenerating ? activeBadgeLabel : idleBadgeLabel}
        </div>
      </div>

      <div className="relative z-10 flex flex-none flex-col gap-4">
        <section className="overflow-hidden px-0 pb-2 pt-0 sm:px-0">
          <GenerationProgressHero
            title={progressTitle}
            phaseLabel={progress?.phaseLabel ?? '正在启动世界生成'}
            progressValue={progressValue}
            estimatedWaitText={estimatedWaitText}
            elapsedText={elapsedText}
          />

          <div className="mt-[-0.15rem] px-0 sm:px-0">
            <GenerationCurrentStepCard
              label={currentStepLabel}
              statusLabel={currentStepStatusLabel}
              progressValue={currentStepProgress}
            />
          </div>

          <div className="mt-4 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:justify-end">
            {!isGenerating ? (
              <>
                {hasSettingActionLabel ? (
                  <button
                    type="button"
                    onClick={onEditSetting}
                    className="platform-button platform-button--ghost min-h-0 rounded-full px-4 py-2 text-sm"
                  >
                    {normalizedSettingActionLabel}
                  </button>
                ) : null}
                <button
                  type="button"
                  onClick={onRetry}
                  className="platform-button platform-button--primary w-full sm:w-auto"
                >
                  {retryLabel}
                </button>
              </>
            ) : onInterrupt ? (
              <button
                type="button"
                onClick={onInterrupt}
                className="rounded-full border border-[var(--platform-button-danger-border)] bg-[var(--platform-button-danger-fill)] px-4 py-2 text-sm text-[var(--platform-button-danger-text)] transition-colors hover:text-[var(--platform-text-strong)]"
              >
                {interruptLabel}
              </button>
            ) : null}
          </div>
        </section>

        <section className="overflow-hidden rounded-[1.75rem] border border-[#eadcd1] bg-[rgba(255,250,246,0.92)] px-4 py-4 shadow-[0_20px_56px_rgba(112,57,30,0.08)] backdrop-blur-[5px] sm:px-5 sm:py-5">
          <div className="mb-4 flex items-start justify-between gap-3">
            <div className="min-w-0">
              <div className="text-[13px] font-black tracking-[0.08em] text-[#111111]">
                {settingTitle}
              </div>
              {hasSettingDescription ? (
                <div className="mt-2 text-[13px] leading-6 text-[#7e6656]">
                  {normalizedSettingDescription}
                </div>
              ) : null}
            </div>
            {hasSettingActionLabel ? (
              <button
                type="button"
                onClick={onEditSetting}
                disabled={isGenerating}
                className={`platform-button platform-button--ghost min-h-0 px-3 py-1.5 text-[11px] ${isGenerating ? 'cursor-not-allowed opacity-40' : ''}`}
              >
                {normalizedSettingActionLabel}
              </button>
            ) : null}
          </div>
          {hasStructuredAnchors ? (
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              {anchorEntries.map((entry, index) => (
                <div
                  key={buildFallbackRenderKey(
                    entry.id,
                    `anchor-entry-${index}`,
                  )}
                  className="rounded-[1.15rem] border border-[#ead6c7] bg-white/74 px-4 py-4"
                >
                  <div className="text-[9px] font-bold tracking-[0.12em] text-[#8e6f5d] sm:text-[10px]">
                    {entry.label}
                  </div>
                  <div className="mt-2 whitespace-pre-line text-[13px] leading-7 text-[#111111]">
                    {entry.value}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="whitespace-pre-line rounded-[1.15rem] border border-[#ead6c7] bg-white/74 px-4 py-4 text-[13px] leading-7 text-[#111111] md:max-h-[16rem] md:overflow-y-auto">
              {settingText || structuredEmptyText}
            </div>
          )}
        </section>
      </div>
    </div>
  );
}
