// 加载动画组件 - 大猫头 + 波浪猫爪

import { useEffect, useState } from 'react';
import { useI18n } from '../i18n';

// ============================================================================
// 类型 & 配置
// ============================================================================

type Stage = 'analyzing' | 'generating' | 'refining' | 'rendering' | 'still-rendering';

interface LoadingSpinnerProps {
  stage: Stage;
  jobId?: string;
  onCancel?: () => void;
}

const STAGE_CONFIG = {
  analyzing:         { key: 'loading.analyzing', start: 0, target: 20 },
  generating:        { key: 'loading.generating', start: 20, target: 66 },
  refining:          { key: 'loading.refining', start: 66, target: 85 },
  rendering:         { key: 'loading.rendering', start: 85, target: 97 },
  'still-rendering': { key: 'loading.stillRendering', start: 85, target: 97 },
} as const;

// ============================================================================
// 进度算法 - 阶段目标值 + 持续增长安慰机制
// ============================================================================

function usePerceivedProgress(stage: Stage): number {
  const [progress, setProgress] = useState(0);
  const [prevStage, setPrevStage] = useState(stage);
  const [stageStartProgress, setStageStartProgress] = useState(0);
  const [enteredAt, setEnteredAt] = useState(Date.now());

  // 阶段变化时记录起点，确保进度单调递增不回退
  useEffect(() => {
    if (stage !== prevStage) {
      setPrevStage(stage);
      setEnteredAt(Date.now());
      setStageStartProgress((current) => Math.max(current, progress, STAGE_CONFIG[stage].start));
    }
  }, [stage, prevStage, progress]);

  // 按阶段目标值推进：前快后慢 + 长耗时每4秒+1%
  useEffect(() => {
    const id = setInterval(() => {
      const elapsed = (Date.now() - enteredAt) / 1000;
      const { target } = STAGE_CONFIG[stage];
      const start = Math.max(stageStartProgress, STAGE_CONFIG[stage].start);
      const range = Math.max(0, target - start);

      // 前段快速接近目标（不一次冲到顶）
      const quickGain = range * 0.72 * (1 - Math.exp(-elapsed / 5));

      // 长耗时阶段：超过10秒后每4秒+1%，避免“卡死感”
      const comfortGain = elapsed > 10 ? Math.floor((elapsed - 10) / 4) : 0;

      const next = Math.min(target, start + quickGain + comfortGain);
      setProgress((current) => Math.max(current, next));
    }, 120);

    return () => clearInterval(id);
  }, [stage, enteredAt, stageStartProgress]);

  // processing 阶段最高展示 97%，完成后由结果态切换
  return Math.min(97, progress);
}

// ============================================================================
// 子组件
// ============================================================================

/** 大猫头 SVG */
function CatHead() {
  return (
    <svg width={100} height={100} viewBox="0 0 140 140" className="drop-shadow-lg">
      <g transform="translate(70, 70)">
        <path
          d="M -70 40 C -80 0, -80 -30, -50 -60 L -20 -30 L 20 -30 L 50 -60 C 80 -30, 80 0, 70 40 C 60 70, -60 70, -70 40 Z"
          fill="#455a64"
        />
        <circle cx="-35" cy="-5" r="18" fill="#fff" />
        <circle cx="35" cy="-5" r="18" fill="#fff" />
        <circle cx="-38" cy="-5" r="6" fill="#455a64" />
        <circle cx="32" cy="-5" r="6" fill="#455a64" />
      </g>
    </svg>
  );
}

/** 浮动猫头 */
function FloatingCat() {
  const [y, setY] = useState(0);

  useEffect(() => {
    let t = 0;
    let id: number;
    const animate = () => {
      t += 0.02;
      setY(Math.sin(t) * 5);
      id = requestAnimationFrame(animate);
    };
    id = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(id);
  }, []);

  return (
    <div style={{ transform: `translateY(${y}px)` }}>
      <CatHead />
    </div>
  );
}

/** 单个猫爪印 - 带波浪动画 */
function WavingPaw({ index, total }: { index: number; total: number }) {
  const [scale, setScale] = useState(1);
  const [y, setY] = useState(0);
  const [opacity, setOpacity] = useState(0.25);

  useEffect(() => {
    let t = 0;
    const phase = (index / total) * Math.PI * 2; // 错开相位
    let id: number;

    const animate = () => {
      t += 0.04;

      // 波浪上下起伏
      const wave = Math.sin(t + phase) * 4;
      setY(wave);

      // 大小脉动 (1.0 ~ 1.3)
      const pulse = 1 + Math.sin(t + phase) * 0.15;
      setScale(pulse);

      // 透明度变化 (0.3 ~ 0.8)
      const alpha = 0.55 + Math.sin(t + phase) * 0.25;
      setOpacity(alpha);

      id = requestAnimationFrame(animate);
    };

    id = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(id);
  }, [index, total]);

  return (
    <div
      style={{
        transform: `translateY(${y}px) scale(${scale})`,
        opacity,
        transition: 'opacity 0.1s',
      }}
    >
      <svg width="24" height="24" viewBox="0 0 24 24">
        <ellipse cx="12" cy="15" rx="5" ry="4" className="fill-text-secondary" />
        <circle cx="7" cy="9" r="2.2" className="fill-text-secondary" />
        <circle cx="12" cy="7" r="2.2" className="fill-text-secondary" />
        <circle cx="17" cy="9" r="2.2" className="fill-text-secondary" />
      </svg>
    </div>
  );
}

/** 波浪猫爪行 */
function WavingPaws() {
  const count = 7;

  return (
    <div className="flex items-center justify-center gap-2">
      {Array.from({ length: count }, (_, i) => (
        <WavingPaw key={i} index={i} total={count} />
      ))}
    </div>
  );
}

// ============================================================================
// 主组件
// ============================================================================

export function LoadingSpinner({ stage, jobId, onCancel }: LoadingSpinnerProps) {
  const { t } = useI18n();
  const progress = usePerceivedProgress(stage);
  const { key } = STAGE_CONFIG[stage];

  return (
    <div className="flex flex-col items-center justify-center py-6">
      {/* 大猫头 */}
      <FloatingCat />

      {/* 波浪猫爪 */}
      <div className="mt-3">
        <WavingPaws />
      </div>

      {/* 状态文字 + 百分比 */}
      <div className="mt-4 text-center">
        <p className="text-base text-text-primary/80">{t(key)}</p>
        <p className="text-sm text-text-secondary/60 tabular-nums mt-1">
          {Math.round(progress)}%
        </p>
      </div>

      {/* Job ID + 取消 */}
      <div className="flex items-center gap-3 mt-3">
        {jobId && (
          <span className="text-xs text-text-secondary/40 font-mono">
            {jobId.slice(0, 8)}
          </span>
        )}
        {onCancel && (
          <button
            onClick={onCancel}
            className="text-xs text-text-secondary/40 hover:text-red-500 transition-colors"
          >
            {t('common.cancel')}
          </button>
        )}
      </div>
    </div>
  );
}
