import React, { useState } from 'react';
import { UploadZone } from './components/UploadZone';
import { AnimationPreview } from './components/AnimationPreview';
import { generateSpriteSheet, generateCharacterPortrait, generateDirectionalSpriteSheet, generateGameMap, MapType, generateGameItem, ItemType } from './services/geminiService';
import { sliceSpriteSheet } from './utils/imageUtils';
import { AppState } from './types';
import { Wand2, Zap, LayoutGrid, Loader2, RotateCcw, Image, Type, User, Film, Download, Move, Map, Sword } from 'lucide-react';

const App: React.FC = () => {
  const [appState, setAppState] = useState<AppState>(AppState.IDLE);
  const [originalImage, setOriginalImage] = useState<string | null>(null);
  const [actionPrompt, setActionPrompt] = useState<string>("");
  const [generatedFrames, setGeneratedFrames] = useState<string[]>([]);
  const [fps, setFps] = useState<number>(6); 
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
  
  // Configuration state - Default to 4 for stability
  const [frameCount, setFrameCount] = useState<number>(4);

  // Mode: 'image' = with reference image, 'text' = text-only generation
  const [mode, setMode] = useState<'image' | 'text'>('text');
  const [characterDescription, setCharacterDescription] = useState<string>("");

  // Feature: 'animation', 'portrait', 'directional', 'map', or 'item'
  const [feature, setFeature] = useState<'animation' | 'portrait' | 'directional' | 'map' | 'item'>('animation');
  const [portraitImage, setPortraitImage] = useState<string | null>(null);
  const [portraitStyle, setPortraitStyle] = useState<string>('2D卡通风格');

  // Directional sprite sheet state
  const [directionalSpriteSheet, setDirectionalSpriteSheet] = useState<string | null>(null);
  const [directionalFrames, setDirectionalFrames] = useState<string[][]>([[], [], [], []]);
  const [selectedDirection, setSelectedDirection] = useState<number>(0);
  const [directionalAction, setDirectionalAction] = useState<string>('行走');
  const [directionalFps, setDirectionalFps] = useState<number>(6);

  // Map generation state
  const [mapImage, setMapImage] = useState<string | null>(null);
  const [mapType, setMapType] = useState<MapType>('rpg');
  const [mapDescription, setMapDescription] = useState<string>('');
  const [mapStyle, setMapStyle] = useState<string>('像素风格');

  // Item generation state
  const [itemImage, setItemImage] = useState<string | null>(null);
  const [itemType, setItemType] = useState<ItemType>('weapon');
  const [itemDescription, setItemDescription] = useState<string>('');
  const [itemStyle, setItemStyle] = useState<string>('像素风格');
  const [itemQuantity, setItemQuantity] = useState<'single' | 'set'>('single');

  // Step 1: Handle Image Upload
  const handleImageSelected = (base64: string) => {
    setOriginalImage(base64);
    setAppState(AppState.READY_TO_GENERATE);
    setErrorMsg(null);
    // Pre-fill a default action if empty to encourage user
    if (!actionPrompt) setActionPrompt("闲置动作");
  };

  // Step 2: Generate Animation
  const handleGenerate = async () => {
    if (mode === 'image' && !originalImage) {
        setErrorMsg("请先上传图片");
        return;
    }
    if (mode === 'text' && !characterDescription) {
        setErrorMsg("请输入角色描述");
        return;
    }
    if (!actionPrompt) {
        setErrorMsg("请输入动作描述");
        return;
    }

    setAppState(AppState.GENERATING);
    setErrorMsg(null);
    setGeneratedFrames([]);

    // Calculate rows and cols based on frame count
    // NOTE: This must match the logic in geminiService implicitly via params
    let rows = 2;
    let cols = 2; // Default 4 frames (2x2)
    
    if (frameCount === 4) { rows = 2; cols = 2; }
    if (frameCount === 6) { rows = 2; cols = 3; }
    if (frameCount === 8) { rows = 2; cols = 4; }
    if (frameCount === 9) { rows = 3; cols = 3; }
    if (frameCount === 16) { rows = 4; cols = 4; }

    try {
      const spriteSheetBase64 = await generateSpriteSheet(
        mode === 'image' ? originalImage : null,
        actionPrompt,
        rows,
        cols,
        mode === 'text' ? characterDescription : undefined
      );

      // Slice the grid using Fixed Grid slicing
      const frames = await sliceSpriteSheet(spriteSheetBase64, rows, cols, true);
      
      if (!frames || frames.length === 0) {
        throw new Error("图像处理失败，请重试。");
      }

      setGeneratedFrames(frames);
      setAppState(AppState.COMPLETE);
    } catch (err: any) {
      console.error("Generation Error:", err);
      setErrorMsg(err.message || "生成失败，请尝试不同的提示词。");
      setAppState(AppState.ERROR);
    }
  };

  const handleReset = () => {
      setAppState(AppState.IDLE);
      setGeneratedFrames([]);
      setPortraitImage(null);
      setDirectionalSpriteSheet(null);
      setDirectionalFrames([[], [], [], []]);
      setMapImage(null);
      setItemImage(null);
      setErrorMsg(null);
  };

  // Generate Portrait
  const handleGeneratePortrait = async () => {
    if (!characterDescription) {
      setErrorMsg("请输入角色描述");
      return;
    }

    setAppState(AppState.GENERATING);
    setErrorMsg(null);
    setPortraitImage(null);

    try {
      const portrait = await generateCharacterPortrait(
        characterDescription,
        portraitStyle,
        '3:4'
      );
      setPortraitImage(portrait);
      setAppState(AppState.COMPLETE);
    } catch (err: any) {
      console.error("Portrait Generation Error:", err);
      setErrorMsg(err.message || "立绘生成失败，请重试。");
      setAppState(AppState.ERROR);
    }
  };

  // Download portrait
  const handleDownloadPortrait = () => {
    if (!portraitImage) return;
    const link = document.createElement('a');
    link.href = portraitImage;
    link.download = 'character-portrait.png';
    link.click();
  };

  // Generate Directional Sprite Sheet
  const handleGenerateDirectional = async () => {
    if (mode === 'image' && !originalImage) {
      setErrorMsg("请先上传图片");
      return;
    }
    if (mode === 'text' && !characterDescription) {
      setErrorMsg("请输入角色描述");
      return;
    }

    setAppState(AppState.GENERATING);
    setErrorMsg(null);
    setDirectionalSpriteSheet(null);
    setDirectionalFrames([[], [], [], []]);

    try {
      const spriteSheetBase64 = await generateDirectionalSpriteSheet(
        mode === 'image' ? originalImage : null,
        directionalAction,
        mode === 'text' ? characterDescription : undefined
      );

      setDirectionalSpriteSheet(spriteSheetBase64);

      // Slice into 4 rows (directions), each with 4 frames
      const allFrames = await sliceSpriteSheet(spriteSheetBase64, 4, 4, true);

      // Split into 4 directions
      const dirFrames: string[][] = [
        allFrames.slice(0, 4),   // Down
        allFrames.slice(4, 8),   // Left
        allFrames.slice(8, 12),  // Right
        allFrames.slice(12, 16)  // Up
      ];

      setDirectionalFrames(dirFrames);
      setAppState(AppState.COMPLETE);
    } catch (err: any) {
      console.error("Directional Generation Error:", err);
      setErrorMsg(err.message || "序列帧生成失败，请重试。");
      setAppState(AppState.ERROR);
    }
  };

  // Download directional sprite sheet
  const handleDownloadDirectional = () => {
    if (!directionalSpriteSheet) return;
    const link = document.createElement('a');
    link.href = directionalSpriteSheet;
    link.download = 'directional-sprite-sheet.png';
    link.click();
  };

  const directionLabels = ['向下 (正面)', '向左', '向右', '向上 (背面)'];

  // Generate Map
  const handleGenerateMap = async () => {
    if (!mapDescription) {
      setErrorMsg("请输入地图描述");
      return;
    }

    setAppState(AppState.GENERATING);
    setErrorMsg(null);
    setMapImage(null);

    try {
      const map = await generateGameMap(mapType, mapDescription, mapStyle);
      setMapImage(map);
      setAppState(AppState.COMPLETE);
    } catch (err: any) {
      console.error("Map Generation Error:", err);
      setErrorMsg(err.message || "地图生成失败，请重试。");
      setAppState(AppState.ERROR);
    }
  };

  // Download map
  const handleDownloadMap = () => {
    if (!mapImage) return;
    const link = document.createElement('a');
    link.href = mapImage;
    link.download = `game-map-${mapType}.png`;
    link.click();
  };

  const mapTypeLabels: Record<MapType, string> = {
    rpg: 'RPG 场景',
    tilemap: '瓦片素材',
    platformer: '横版关卡',
    strategy: '战棋地图',
    world: '世界地图'
  };

  const mapStyleOptions = ['像素风格', '卡通风格', '写实风格', '手绘风格'];

  // Generate Item
  const handleGenerateItem = async () => {
    if (!itemDescription) {
      setErrorMsg("请输入道具描述");
      return;
    }

    setAppState(AppState.GENERATING);
    setErrorMsg(null);
    setItemImage(null);

    try {
      const item = await generateGameItem(itemType, itemDescription, itemStyle, itemQuantity);
      setItemImage(item);
      setAppState(AppState.COMPLETE);
    } catch (err: any) {
      console.error("Item Generation Error:", err);
      setErrorMsg(err.message || "道具生成失败，请重试。");
      setAppState(AppState.ERROR);
    }
  };

  // Download item
  const handleDownloadItem = () => {
    if (!itemImage) return;
    const link = document.createElement('a');
    link.href = itemImage;
    link.download = `game-item-${itemType}.png`;
    link.click();
  };

  const itemTypeLabels: Record<ItemType, string> = {
    weapon: '武器',
    armor: '防具',
    potion: '药水/消耗品',
    material: '材料',
    treasure: '宝箱/财宝',
    accessory: '饰品'
  };

  const itemStyleOptions = ['像素风格', '卡通风格', '写实风格', '手绘风格'];

  return (
    <div className="min-h-screen bg-[#F8FAFC] flex flex-col font-sans pb-10">
      {/* Header */}
      <header className="bg-white border-b border-gray-100 sticky top-0 z-10 shadow-sm">
        <div className="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
          <div className="flex items-center gap-2">
            <div className="w-8 h-8 bg-lime-400 rounded-lg flex items-center justify-center shadow-sm">
              <Zap className="text-black fill-current" size={20} />
            </div>
            <span className="font-bold text-xl tracking-tight text-gray-800">ToonMotion</span>
          </div>
          <div className="text-sm text-gray-600 font-medium bg-gray-100 px-3 py-1 rounded-full border border-gray-200">
             Powered by Gemini 2.5
          </div>
        </div>
      </header>

      <main className="flex-1 max-w-6xl mx-auto px-6 py-8 w-full">

        {/* Feature Tabs */}
        <div className="mb-6 flex gap-4 border-b border-gray-200">
          <button
            onClick={() => setFeature('animation')}
            className={`pb-3 px-1 font-medium flex items-center gap-2 border-b-2 transition-all ${
              feature === 'animation'
                ? 'border-lime-500 text-gray-900'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            <Film size={18} /> 动画生成
          </button>
          <button
            onClick={() => setFeature('portrait')}
            className={`pb-3 px-1 font-medium flex items-center gap-2 border-b-2 transition-all ${
              feature === 'portrait'
                ? 'border-lime-500 text-gray-900'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            <User size={18} /> 角色立绘
          </button>
          <button
            onClick={() => setFeature('directional')}
            className={`pb-3 px-1 font-medium flex items-center gap-2 border-b-2 transition-all ${
              feature === 'directional'
                ? 'border-lime-500 text-gray-900'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            <Move size={18} /> 四方向序列帧
          </button>
          <button
            onClick={() => setFeature('map')}
            className={`pb-3 px-1 font-medium flex items-center gap-2 border-b-2 transition-all ${
              feature === 'map'
                ? 'border-lime-500 text-gray-900'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            <Map size={18} /> 游戏地图
          </button>
          <button
            onClick={() => setFeature('item')}
            className={`pb-3 px-1 font-medium flex items-center gap-2 border-b-2 transition-all ${
              feature === 'item'
                ? 'border-lime-500 text-gray-900'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            <Sword size={18} /> 武器道具
          </button>
        </div>

        {/* Intro */}
        <div className="mb-8">
          <h1 className="text-3xl font-bold text-gray-900 mb-2">
            {feature === 'animation' ? '让你的角色动起来' : feature === 'portrait' ? '生成角色立绘' : feature === 'directional' ? '四方向序列帧' : feature === 'map' ? '游戏地图生成' : '武器道具生成'}
          </h1>
          <p className="text-gray-600 max-w-2xl">
            {feature === 'portrait'
              ? '描述你想要的角色，Gemini 将为你生成高质量的角色立绘。'
              : feature === 'directional'
                ? '生成角色的四个方向（上下左右）动画序列帧，适用于 RPG 游戏开发。'
                : feature === 'map'
                  ? '生成各类游戏地图，包括 RPG 场景、瓦片素材、横版关卡、战棋地图和世界地图。'
                  : feature === 'item'
                    ? '生成游戏中的武器、防具、药水、材料等道具图标，支持单个或批量生成。'
                    : mode === 'image'
                      ? '上传静态角色图片，输入动作描述，Gemini 将为你生成逐帧动画。'
                      : '描述你想要的角色和动作，Gemini 将从零开始生成逐帧动画。'}
          </p>
        </div>

        {feature === 'animation' ? (
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">

          {/* Left Column: Input */}
          <div className="lg:col-span-5 space-y-6">

            {/* Mode Switch */}
            <div className="bg-white rounded-2xl p-4 shadow-sm border border-gray-100">
              <div className="flex gap-2">
                <button
                  onClick={() => setMode('text')}
                  className={`flex-1 py-3 px-4 rounded-xl font-medium flex items-center justify-center gap-2 transition-all ${
                    mode === 'text'
                      ? 'bg-lime-400 text-black shadow-md'
                      : 'bg-gray-50 text-gray-600 hover:bg-gray-100'
                  }`}
                >
                  <Type size={18} /> 纯文字生成
                </button>
                <button
                  onClick={() => setMode('image')}
                  className={`flex-1 py-3 px-4 rounded-xl font-medium flex items-center justify-center gap-2 transition-all ${
                    mode === 'image'
                      ? 'bg-lime-400 text-black shadow-md'
                      : 'bg-gray-50 text-gray-600 hover:bg-gray-100'
                  }`}
                >
                  <Image size={18} /> 参考图生成
                </button>
              </div>
            </div>

            {/* Conditional: Upload or Character Description */}
            {mode === 'image' ? (
              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                <div className="flex items-center justify-between mb-4">
                  <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                    上传角色图片
                  </h2>
                </div>

                <UploadZone
                  selectedImage={originalImage}
                  onImageSelected={handleImageSelected}
                  onClear={() => {
                    setOriginalImage(null);
                    setAppState(AppState.IDLE);
                    setGeneratedFrames([]);
                    setErrorMsg(null);
                  }}
                />
              </div>
            ) : (
              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                <div className="flex items-center justify-between mb-4">
                  <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                    角色描述
                  </h2>
                </div>

                <textarea
                  placeholder="例如：一只橙色的小猫，大眼睛，戴着红色围巾"
                  className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-28
                    ${!characterDescription && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                  `}
                  value={characterDescription}
                  onChange={(e) => setCharacterDescription(e.target.value)}
                />

                {/* Quick Character Prompts */}
                <div className="flex gap-2 mt-3 flex-wrap">
                  {['可爱的小猫咪', '像素风格勇士', '圆滚滚的机器人', 'Q版小女孩'].map((p) => (
                    <button
                      key={p}
                      onClick={() => setCharacterDescription(p)}
                      className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                    >
                      {p}
                    </button>
                  ))}
                </div>
              </div>
            )}

            {/* Step 2: Settings Card */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
               <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  动画设置
                </h2>
                {appState === AppState.ERROR && (
                    <button onClick={handleReset} className="text-xs text-gray-500 flex items-center gap-1 hover:text-gray-800">
                        <RotateCcw size={12} /> 重置状态
                    </button>
                )}
              </div>

              <div className="space-y-6">
                {/* Motion Prompt */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-2">
                    动作提示词
                  </label>
                  <div className="relative">
                    <textarea
                      placeholder="例如：奔跑循环, 开心地跳跃, 施法动作"
                      className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-24
                        ${!actionPrompt && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                      `}
                      value={actionPrompt}
                      onChange={(e) => setActionPrompt(e.target.value)}
                    />
                  </div>
                  
                  {/* Quick Prompts */}
                  <div className="flex gap-2 mt-2 flex-wrap">
                    {['奔跑循环', '发送爱心', '攻击动作', '受伤倒地'].map((p) => (
                      <button
                        key={p}
                        onClick={() => setActionPrompt(p)}
                        className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                      >
                        {p}
                      </button>
                    ))}
                  </div>
                </div>

                {/* Frame Count & FPS Row */}
                <div className="grid grid-cols-2 gap-4">
                    <div>
                        <label className="block text-xs font-bold text-gray-500 uppercase mb-2">
                            生成帧数
                        </label>
                        <div className="relative">
                            <select 
                                value={frameCount}
                                onChange={(e) => setFrameCount(Number(e.target.value))}
                                className="w-full bg-gray-50 border border-gray-200 text-gray-700 text-sm rounded-xl focus:ring-lime-500 focus:border-lime-500 block p-2.5 outline-none appearance-none"
                            >
                                <option value={4}>4 帧 (最稳定)</option>
                                <option value={6}>6 帧</option>
                                <option value={8}>8 帧</option>
                                <option value={9}>9 帧</option>
                                <option value={16}>16 帧</option>
                            </select>
                            <LayoutGrid size={16} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none"/>
                        </div>
                    </div>
                    <div>
                         <label className="block text-xs font-bold text-gray-500 uppercase mb-2 flex justify-between">
                            <span>播放速度</span>
                            <span className="text-lime-600">{fps} FPS</span>
                        </label>
                        <input 
                            type="range" 
                            min="1" 
                            max="12" 
                            value={fps} 
                            onChange={(e) => setFps(Number(e.target.value))}
                            className="w-full accent-lime-500 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer mt-2"
                        />
                    </div>
                </div>

                <button
                  onClick={handleGenerate}
                  disabled={appState === AppState.GENERATING}
                  className={`w-full py-4 rounded-xl font-bold text-lg flex items-center justify-center gap-2 mt-2 shadow-md transition-all transform active:scale-[0.99]
                    ${(appState === AppState.GENERATING)
                      ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200' 
                      : 'bg-lime-400 hover:bg-lime-500 text-black hover:shadow-lg hover:shadow-lime-200 border border-lime-400'}`}
                >
                  {appState === AppState.GENERATING ? (
                    <>
                      <Loader2 size={20} className="animate-spin" /> 正在生成...
                    </>
                  ) : (
                    <>
                      <Wand2 size={20} /> 开始生成动画
                    </>
                  )}
                </button>

                {errorMsg && (
                  <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 mt-2 animate-pulse">
                    {errorMsg}
                  </div>
                )}
              </div>
            </div>

          </div>

          {/* Right Column: Result */}
          <div className="lg:col-span-7 space-y-6">
             <div className="sticky top-24">
                <div className="flex items-center justify-between mb-4">
                    <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                    生成结果
                    </h2>
                </div>

                <AnimationPreview
                  frames={generatedFrames}
                  fps={fps}
                  isLoading={appState === AppState.GENERATING}
                />
             </div>
          </div>

        </div>
        ) : feature === 'portrait' ? (
        /* Portrait Feature UI */
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
          {/* Left Column: Input */}
          <div className="lg:col-span-5 space-y-6">
            {/* Character Description */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  角色描述
                </h2>
              </div>

              <textarea
                placeholder="例如：一位身穿蓝色铠甲的女骑士，金色长发，手持银色长剑，英姿飒爽"
                className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-32
                  ${!characterDescription && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                `}
                value={characterDescription}
                onChange={(e) => setCharacterDescription(e.target.value)}
              />

              {/* Quick Character Prompts */}
              <div className="flex gap-2 mt-3 flex-wrap">
                {['蓝发魔法少女', '可爱的精灵', '帅气的剑士', '萌系兽耳娘'].map((p) => (
                  <button
                    key={p}
                    onClick={() => setCharacterDescription(p)}
                    className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                  >
                    {p}
                  </button>
                ))}
              </div>
            </div>

            {/* Style Selection */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  画风选择
                </h2>
              </div>

              <div className="grid grid-cols-2 gap-2">
                {['2D卡通风格', '日系动漫风格', '像素风格', 'Q版可爱风格'].map((style) => (
                  <button
                    key={style}
                    onClick={() => setPortraitStyle(style)}
                    className={`py-3 px-4 rounded-xl font-medium text-sm transition-all ${
                      portraitStyle === style
                        ? 'bg-lime-400 text-black shadow-md'
                        : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                    }`}
                  >
                    {style}
                  </button>
                ))}
              </div>

              <button
                onClick={handleGeneratePortrait}
                disabled={appState === AppState.GENERATING || !characterDescription}
                className={`w-full py-4 rounded-xl font-bold text-lg flex items-center justify-center gap-2 mt-6 shadow-md transition-all transform active:scale-[0.99]
                  ${(appState === AppState.GENERATING || !characterDescription)
                    ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200'
                    : 'bg-lime-400 hover:bg-lime-500 text-black hover:shadow-lg hover:shadow-lime-200 border border-lime-400'}`}
              >
                {appState === AppState.GENERATING ? (
                  <>
                    <Loader2 size={20} className="animate-spin" /> 正在生成...
                  </>
                ) : (
                  <>
                    <Wand2 size={20} /> 生成立绘
                  </>
                )}
              </button>

              {errorMsg && (
                <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 mt-4 animate-pulse">
                  {errorMsg}
                </div>
              )}
            </div>
          </div>

          {/* Right Column: Portrait Result */}
          <div className="lg:col-span-7 space-y-6">
            <div className="sticky top-24">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  生成结果
                </h2>
                {portraitImage && (
                  <button
                    onClick={handleDownloadPortrait}
                    className="flex items-center gap-1 text-sm text-lime-600 hover:text-lime-700 font-medium"
                  >
                    <Download size={16} /> 下载立绘
                  </button>
                )}
              </div>

              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 min-h-[400px] flex items-center justify-center">
                {appState === AppState.GENERATING ? (
                  <div className="text-center text-gray-400">
                    <Loader2 size={48} className="animate-spin mx-auto mb-4" />
                    <p>正在生成立绘...</p>
                  </div>
                ) : portraitImage ? (
                  <img
                    src={portraitImage}
                    alt="Generated Portrait"
                    className="max-w-full max-h-[500px] rounded-xl shadow-lg"
                  />
                ) : (
                  <div className="text-center text-gray-400">
                    <User size={48} className="mx-auto mb-4 opacity-50" />
                    <p>立绘将在这里显示</p>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
        ) : feature === 'directional' ? (
        /* Directional Sprite Sheet Feature UI */
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
          {/* Left Column: Input */}
          <div className="lg:col-span-5 space-y-6">
            {/* Mode Switch */}
            <div className="bg-white rounded-2xl p-4 shadow-sm border border-gray-100">
              <div className="flex gap-2">
                <button
                  onClick={() => setMode('text')}
                  className={`flex-1 py-3 px-4 rounded-xl font-medium flex items-center justify-center gap-2 transition-all ${
                    mode === 'text'
                      ? 'bg-lime-400 text-black shadow-md'
                      : 'bg-gray-50 text-gray-600 hover:bg-gray-100'
                  }`}
                >
                  <Type size={18} /> 纯文字生成
                </button>
                <button
                  onClick={() => setMode('image')}
                  className={`flex-1 py-3 px-4 rounded-xl font-medium flex items-center justify-center gap-2 transition-all ${
                    mode === 'image'
                      ? 'bg-lime-400 text-black shadow-md'
                      : 'bg-gray-50 text-gray-600 hover:bg-gray-100'
                  }`}
                >
                  <Image size={18} /> 参考图生成
                </button>
              </div>
            </div>

            {/* Conditional: Upload or Character Description */}
            {mode === 'image' ? (
              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                <div className="flex items-center justify-between mb-4">
                  <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                    上传角色图片
                  </h2>
                </div>
                <UploadZone
                  selectedImage={originalImage}
                  onImageSelected={handleImageSelected}
                  onClear={() => {
                    setOriginalImage(null);
                    setAppState(AppState.IDLE);
                    setDirectionalSpriteSheet(null);
                    setDirectionalFrames([[], [], [], []]);
                    setErrorMsg(null);
                  }}
                />
              </div>
            ) : (
              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                <div className="flex items-center justify-between mb-4">
                  <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                    角色描述
                  </h2>
                </div>
                <textarea
                  placeholder="例如：一只橙色的小猫，大眼睛，戴着红色围巾"
                  className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-28
                    ${!characterDescription && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                  `}
                  value={characterDescription}
                  onChange={(e) => setCharacterDescription(e.target.value)}
                />
                <div className="flex gap-2 mt-3 flex-wrap">
                  {['像素风格勇士', 'Q版小女孩', '可爱的小猫咪', '圆滚滚的机器人'].map((p) => (
                    <button
                      key={p}
                      onClick={() => setCharacterDescription(p)}
                      className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                    >
                      {p}
                    </button>
                  ))}
                </div>
              </div>
            )}

            {/* Action Settings */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  动作设置
                </h2>
                {appState === AppState.ERROR && (
                  <button onClick={handleReset} className="text-xs text-gray-500 flex items-center gap-1 hover:text-gray-800">
                    <RotateCcw size={12} /> 重置状态
                  </button>
                )}
              </div>

              <div className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-2">动作类型</label>
                  <div className="grid grid-cols-2 gap-2">
                    {['行走', '奔跑', '攻击', '闲置'].map((action) => (
                      <button
                        key={action}
                        onClick={() => setDirectionalAction(action)}
                        className={`py-2 px-4 rounded-xl font-medium text-sm transition-all ${
                          directionalAction === action
                            ? 'bg-lime-400 text-black shadow-md'
                            : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                        }`}
                      >
                        {action}
                      </button>
                    ))}
                  </div>
                </div>

                <div>
                  <label className="block text-xs font-bold text-gray-500 uppercase mb-2 flex justify-between">
                    <span>预览速度</span>
                    <span className="text-lime-600">{directionalFps} FPS</span>
                  </label>
                  <input
                    type="range"
                    min="1"
                    max="12"
                    value={directionalFps}
                    onChange={(e) => setDirectionalFps(Number(e.target.value))}
                    className="w-full accent-lime-500 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
                  />
                </div>

                <button
                  onClick={handleGenerateDirectional}
                  disabled={appState === AppState.GENERATING}
                  className={`w-full py-4 rounded-xl font-bold text-lg flex items-center justify-center gap-2 mt-2 shadow-md transition-all transform active:scale-[0.99]
                    ${(appState === AppState.GENERATING)
                      ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200'
                      : 'bg-lime-400 hover:bg-lime-500 text-black hover:shadow-lg hover:shadow-lime-200 border border-lime-400'}`}
                >
                  {appState === AppState.GENERATING ? (
                    <>
                      <Loader2 size={20} className="animate-spin" /> 正在生成...
                    </>
                  ) : (
                    <>
                      <Wand2 size={20} /> 生成四方向序列帧
                    </>
                  )}
                </button>

                {errorMsg && (
                  <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 mt-2 animate-pulse">
                    {errorMsg}
                  </div>
                )}
              </div>
            </div>
          </div>

          {/* Right Column: Result */}
          <div className="lg:col-span-7 space-y-6">
            <div className="sticky top-24">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  生成结果
                </h2>
                {directionalSpriteSheet && (
                  <button
                    onClick={handleDownloadDirectional}
                    className="flex items-center gap-1 text-sm text-lime-600 hover:text-lime-700 font-medium"
                  >
                    <Download size={16} /> 下载序列帧
                  </button>
                )}
              </div>

              {/* Direction Tabs */}
              {directionalFrames[0].length > 0 && (
                <div className="flex gap-2 mb-4">
                  {directionLabels.map((label, idx) => (
                    <button
                      key={idx}
                      onClick={() => setSelectedDirection(idx)}
                      className={`flex-1 py-2 px-3 rounded-lg font-medium text-sm transition-all ${
                        selectedDirection === idx
                          ? 'bg-lime-400 text-black shadow-md'
                          : 'bg-white text-gray-600 hover:bg-gray-50 border border-gray-200'
                      }`}
                    >
                      {label}
                    </button>
                  ))}
                </div>
              )}

              {/* Preview */}
              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                {appState === AppState.GENERATING ? (
                  <div className="text-center text-gray-400 py-20">
                    <Loader2 size={48} className="animate-spin mx-auto mb-4" />
                    <p>正在生成四方向序列帧...</p>
                  </div>
                ) : directionalFrames[0].length > 0 ? (
                  <div className="space-y-4">
                    <div className="text-center text-sm text-gray-500 mb-2">
                      {directionLabels[selectedDirection]} - 动画预览
                    </div>
                    <AnimationPreview
                      frames={directionalFrames[selectedDirection]}
                      fps={directionalFps}
                      isLoading={false}
                    />
                  </div>
                ) : (
                  <div className="text-center text-gray-400 py-20">
                    <Move size={48} className="mx-auto mb-4 opacity-50" />
                    <p>四方向序列帧将在这里显示</p>
                  </div>
                )}
              </div>

              {/* Full Sprite Sheet Preview */}
              {directionalSpriteSheet && (
                <div className="mt-4 bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
                  <h3 className="font-semibold text-gray-800 mb-3">完整序列帧</h3>
                  <img
                    src={directionalSpriteSheet}
                    alt="Full Sprite Sheet"
                    className="w-full rounded-lg border border-gray-200"
                  />
                </div>
              )}
            </div>
          </div>
        </div>
        ) : feature === 'map' ? (
        /* Map Generation Feature UI */
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
          {/* Left Column: Input */}
          <div className="lg:col-span-5 space-y-6">
            {/* Map Type Selection */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  地图类型
                </h2>
              </div>
              <div className="grid grid-cols-2 gap-2">
                {(Object.keys(mapTypeLabels) as MapType[]).map((type) => (
                  <button
                    key={type}
                    onClick={() => setMapType(type)}
                    className={`py-3 px-4 rounded-xl font-medium text-sm transition-all ${
                      mapType === type
                        ? 'bg-lime-400 text-black shadow-md'
                        : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                    }`}
                  >
                    {mapTypeLabels[type]}
                  </button>
                ))}
              </div>
            </div>

            {/* Map Description */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  场景描述
                </h2>
              </div>
              <textarea
                placeholder="例如：森林中的小村庄，有河流穿过，远处有山脉"
                className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-28
                  ${!mapDescription && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                `}
                value={mapDescription}
                onChange={(e) => setMapDescription(e.target.value)}
              />
              <div className="flex gap-2 mt-3 flex-wrap">
                {['森林村庄', '沙漠遗迹', '雪山城堡', '海边港口', '地下洞穴'].map((p) => (
                  <button
                    key={p}
                    onClick={() => setMapDescription(p)}
                    className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                  >
                    {p}
                  </button>
                ))}
              </div>
            </div>

            {/* Style Selection */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  画风选择
                </h2>
                {appState === AppState.ERROR && (
                  <button onClick={handleReset} className="text-xs text-gray-500 flex items-center gap-1 hover:text-gray-800">
                    <RotateCcw size={12} /> 重置状态
                  </button>
                )}
              </div>
              <div className="grid grid-cols-2 gap-2">
                {mapStyleOptions.map((style) => (
                  <button
                    key={style}
                    onClick={() => setMapStyle(style)}
                    className={`py-2 px-4 rounded-xl font-medium text-sm transition-all ${
                      mapStyle === style
                        ? 'bg-lime-400 text-black shadow-md'
                        : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                    }`}
                  >
                    {style}
                  </button>
                ))}
              </div>

              <button
                onClick={handleGenerateMap}
                disabled={appState === AppState.GENERATING || !mapDescription}
                className={`w-full py-4 rounded-xl font-bold text-lg flex items-center justify-center gap-2 mt-6 shadow-md transition-all transform active:scale-[0.99]
                  ${(appState === AppState.GENERATING || !mapDescription)
                    ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200'
                    : 'bg-lime-400 hover:bg-lime-500 text-black hover:shadow-lg hover:shadow-lime-200 border border-lime-400'}`}
              >
                {appState === AppState.GENERATING ? (
                  <>
                    <Loader2 size={20} className="animate-spin" /> 正在生成...
                  </>
                ) : (
                  <>
                    <Wand2 size={20} /> 生成地图
                  </>
                )}
              </button>

              {errorMsg && (
                <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 mt-4 animate-pulse">
                  {errorMsg}
                </div>
              )}
            </div>
          </div>

          {/* Right Column: Map Result */}
          <div className="lg:col-span-7 space-y-6">
            <div className="sticky top-24">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  生成结果
                </h2>
                {mapImage && (
                  <button
                    onClick={handleDownloadMap}
                    className="flex items-center gap-1 text-sm text-lime-600 hover:text-lime-700 font-medium"
                  >
                    <Download size={16} /> 下载地图
                  </button>
                )}
              </div>

              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 min-h-[400px] flex items-center justify-center">
                {appState === AppState.GENERATING ? (
                  <div className="text-center text-gray-400">
                    <Loader2 size={48} className="animate-spin mx-auto mb-4" />
                    <p>正在生成{mapTypeLabels[mapType]}...</p>
                  </div>
                ) : mapImage ? (
                  <img
                    src={mapImage}
                    alt="Generated Map"
                    className="max-w-full max-h-[600px] rounded-xl shadow-lg"
                  />
                ) : (
                  <div className="text-center text-gray-400">
                    <Map size={48} className="mx-auto mb-4 opacity-50" />
                    <p>地图将在这里显示</p>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
        ) : (
        /* Item Generation Feature UI */
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
          {/* Left Column: Input */}
          <div className="lg:col-span-5 space-y-6">
            {/* Item Type Selection */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  道具类型
                </h2>
              </div>
              <div className="grid grid-cols-2 gap-2">
                {(Object.keys(itemTypeLabels) as ItemType[]).map((type) => (
                  <button
                    key={type}
                    onClick={() => setItemType(type)}
                    className={`py-3 px-4 rounded-xl font-medium text-sm transition-all ${
                      itemType === type
                        ? 'bg-lime-400 text-black shadow-md'
                        : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                    }`}
                  >
                    {itemTypeLabels[type]}
                  </button>
                ))}
              </div>
            </div>

            {/* Item Description */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  道具描述
                </h2>
              </div>
              <textarea
                placeholder="例如：火焰之剑，发出红色光芒，剑身刻有古老符文"
                className={`w-full border rounded-xl px-4 py-3 outline-none transition-all shadow-sm resize-none h-28
                  ${!itemDescription && errorMsg ? 'border-red-300 focus:ring-red-200' : 'border-gray-200 focus:ring-2 focus:ring-lime-400 focus:border-lime-400'}
                `}
                value={itemDescription}
                onChange={(e) => setItemDescription(e.target.value)}
              />
              <div className="flex gap-2 mt-3 flex-wrap">
                {['传说之剑', '治疗药水', '魔法宝石', '黄金宝箱', '皮革护甲'].map((p) => (
                  <button
                    key={p}
                    onClick={() => setItemDescription(p)}
                    className="px-3 py-1.5 bg-gray-50 hover:bg-gray-100 border border-gray-200 rounded-lg text-xs font-medium text-gray-600 transition-colors"
                  >
                    {p}
                  </button>
                ))}
              </div>
            </div>

            {/* Style & Quantity Selection */}
            <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  生成设置
                </h2>
                {appState === AppState.ERROR && (
                  <button onClick={handleReset} className="text-xs text-gray-500 flex items-center gap-1 hover:text-gray-800">
                    <RotateCcw size={12} /> 重置状态
                  </button>
                )}
              </div>

              <div className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-2">画风选择</label>
                  <div className="grid grid-cols-2 gap-2">
                    {itemStyleOptions.map((style) => (
                      <button
                        key={style}
                        onClick={() => setItemStyle(style)}
                        className={`py-2 px-4 rounded-xl font-medium text-sm transition-all ${
                          itemStyle === style
                            ? 'bg-lime-400 text-black shadow-md'
                            : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                        }`}
                      >
                        {style}
                      </button>
                    ))}
                  </div>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-2">生成数量</label>
                  <div className="grid grid-cols-2 gap-2">
                    <button
                      onClick={() => setItemQuantity('single')}
                      className={`py-2 px-4 rounded-xl font-medium text-sm transition-all ${
                        itemQuantity === 'single'
                          ? 'bg-lime-400 text-black shadow-md'
                          : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                      }`}
                    >
                      单个道具
                    </button>
                    <button
                      onClick={() => setItemQuantity('set')}
                      className={`py-2 px-4 rounded-xl font-medium text-sm transition-all ${
                        itemQuantity === 'set'
                          ? 'bg-lime-400 text-black shadow-md'
                          : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                      }`}
                    >
                      批量生成 (6个)
                    </button>
                  </div>
                </div>
              </div>

              <button
                onClick={handleGenerateItem}
                disabled={appState === AppState.GENERATING || !itemDescription}
                className={`w-full py-4 rounded-xl font-bold text-lg flex items-center justify-center gap-2 mt-6 shadow-md transition-all transform active:scale-[0.99]
                  ${(appState === AppState.GENERATING || !itemDescription)
                    ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200'
                    : 'bg-lime-400 hover:bg-lime-500 text-black hover:shadow-lg hover:shadow-lime-200 border border-lime-400'}`}
              >
                {appState === AppState.GENERATING ? (
                  <>
                    <Loader2 size={20} className="animate-spin" /> 正在生成...
                  </>
                ) : (
                  <>
                    <Wand2 size={20} /> 生成道具
                  </>
                )}
              </button>

              {errorMsg && (
                <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 mt-4 animate-pulse">
                  {errorMsg}
                </div>
              )}
            </div>
          </div>

          {/* Right Column: Item Result */}
          <div className="lg:col-span-7 space-y-6">
            <div className="sticky top-24">
              <div className="flex items-center justify-between mb-4">
                <h2 className="font-semibold flex items-center gap-2 text-gray-800 text-lg">
                  生成结果
                </h2>
                {itemImage && (
                  <button
                    onClick={handleDownloadItem}
                    className="flex items-center gap-1 text-sm text-lime-600 hover:text-lime-700 font-medium"
                  >
                    <Download size={16} /> 下载道具
                  </button>
                )}
              </div>

              <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 min-h-[400px] flex items-center justify-center">
                {appState === AppState.GENERATING ? (
                  <div className="text-center text-gray-400">
                    <Loader2 size={48} className="animate-spin mx-auto mb-4" />
                    <p>正在生成{itemTypeLabels[itemType]}...</p>
                  </div>
                ) : itemImage ? (
                  <img
                    src={itemImage}
                    alt="Generated Item"
                    className="max-w-full max-h-[600px] rounded-xl shadow-lg"
                  />
                ) : (
                  <div className="text-center text-gray-400">
                    <Sword size={48} className="mx-auto mb-4 opacity-50" />
                    <p>道具将在这里显示</p>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
        )}
      </main>
    </div>
  );
};

export default App;