
import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Modal } from '../Modal';
import { AdminConfig, NFT, GameCharacter, WeaponType, DecorativeFishType, BubbleSize, SavedReply } from '../../types';
import { generateImageWithGemini, GeminiImageResponse } from '../../geminiApi'; 
import { SoundEvent } from '../../sounds'; 
import { COOLDOWN_RED_ARROW_DEFENSE, RED_ARROW_PROJECTILE_SPEED, RED_ARROW_PROJECTILE_DAMAGE, PLAYER_SPEED, RED_ARROW_DEFAULT_SHOT_COUNT, RED_ARROW_PROJECTILE_IMAGE_URL, DOGE_WHALE_ESCAPE_PLAYER_IMAGE_URL, DOGE_WHALE_ESCAPE_WALL_IMAGE_URL, DOGE_WHALE_ESCAPE_GOAL_IMAGE_URL, DOGE_WHALE_ESCAPE_MINE_IMAGE_URL, DOGE_WHALE_ESCAPE_BOMB_IMAGE_URL, DOGE_WHALE_ESCAPE_JELLYFISH_IMAGE_URL, DOGE_WHALE_ESCAPE_CROCODILE_IMAGE_URL, DOGE_WHALE_ESCAPE_ALGAE_IMAGE_URL, DOGE_WHALE_ESCAPE_CURRENT_N_IMAGE_URL, DOGE_WHALE_ESCAPE_CURRENT_S_IMAGE_URL, DOGE_WHALE_ESCAPE_CURRENT_E_IMAGE_URL, DOGE_WHALE_ESCAPE_CURRENT_W_IMAGE_URL, DOGE_WHALE_ESCAPE_SNAKE_IMAGE_URL, DOGE_WHALE_ESCAPE_LIFEUP_IMAGE_URL } from '../../constants';
import { GoogleGenAI, GenerateContentResponse } from "@google/genai";
import { generateId } from '../../utils';


interface AdminPanelModalProps {
  isOpen: boolean;
  onClose: () => void;
  adminConfig: AdminConfig;
  runtimeNftDefinitions: Record<string, NFT>;
  runtimeGameCharacters: Record<string, GameCharacter>;
  onUpdateAdminConfig: (newConfig: Partial<AdminConfig>) => void;
  onUpdateNftImage: (nftId: string, newImageUrl: string) => void;
  onUpdateCharacterAttributes: (characterId: string, updates: Partial<GameCharacter>) => void;
  showNotification: (message: string, type?: 'success' | 'error' | 'info' | 'warning' | 'special') => void;
  isMaximizable?: boolean;
  isMaximized?: boolean;
  onToggleMaximize?: () => void;
  onLogout: () => void; // New prop for logout
}

type AdminTab = 'aiGenerator' | 'nfts' | 'characters' | 'staking' | 'assets' | 'gameplay' | 'sounds' | 'effectsVisuals' | 'aiChat' | 'knowledgeBase' | 'dogeEscapeAssets';

type SoundUrlKey = Extract<keyof AdminConfig, `sound${string}Url`>;
type AdminConfigImageKey = Extract<keyof AdminConfig, `${string}Image${string}` | `${string}ImageUrl`>;


const convertFileToBase64 = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = error => reject(error);
  });
};

interface CharacterAttributeInputs {
    name: string;
    imageURL: string;
    imageBase64?: string | null;
    defaultWeaponType?: WeaponType;
    autoFireHealthThreshold?: number;
    baseHealth?: number;
    baseSpeed?: number; 
}

const formatWeaponTypeName = (enumKey: string) => {
    return enumKey.replace(/([A-Z])/g, ' $1').trim().replace(/_/g, ' ');
};

const formatSoundEventName = (event: SoundEvent): string => {
  return event
    .split('_')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

interface AIChatMessage {
  id: string;
  sender: 'user' | 'ai' | 'error';
  text: string;
  lang?: string; // Language of the user's query
}

const languageOptions = [
  { name: 'English', code: 'en' },
  { name: 'Spanish', code: 'es' },
  { name: 'French', code: 'fr' },
  { name: 'German', code: 'de' },
  { name: 'Japanese', code: 'ja' },
  { name: 'Chinese', code: 'zh' },
  { name: 'Korean', code: 'ko' },
];

const dogeEscapeAssetConfigKeys: Array<{key: AdminConfigImageKey, displayName: string, defaultUrl: string}> = [
    { key: 'dogeEscapePlayerImageUrl', displayName: 'Doge Escape Player', defaultUrl: DOGE_WHALE_ESCAPE_PLAYER_IMAGE_URL },
    { key: 'dogeEscapeWallImageUrl', displayName: 'Doge Escape Wall', defaultUrl: DOGE_WHALE_ESCAPE_WALL_IMAGE_URL },
    { key: 'dogeEscapeGoalImageUrl', displayName: 'Doge Escape Goal', defaultUrl: DOGE_WHALE_ESCAPE_GOAL_IMAGE_URL },
    { key: 'dogeEscapeMineImageUrl', displayName: 'Doge Escape Mine', defaultUrl: DOGE_WHALE_ESCAPE_MINE_IMAGE_URL },
    { key: 'dogeEscapeBombImageUrl', displayName: 'Doge Escape Bomb', defaultUrl: DOGE_WHALE_ESCAPE_BOMB_IMAGE_URL },
    { key: 'dogeEscapeJellyfishImageUrl', displayName: 'Doge Escape Jellyfish', defaultUrl: DOGE_WHALE_ESCAPE_JELLYFISH_IMAGE_URL },
    { key: 'dogeEscapeCrocodileImageUrl', displayName: 'Doge Escape Crocodile', defaultUrl: DOGE_WHALE_ESCAPE_CROCODILE_IMAGE_URL },
    { key: 'dogeEscapeAlgaeImageUrl', displayName: 'Doge Escape Toxic Algae', defaultUrl: DOGE_WHALE_ESCAPE_ALGAE_IMAGE_URL },
    { key: 'dogeEscapeCurrentNImageUrl', displayName: 'Doge Escape Current (North)', defaultUrl: DOGE_WHALE_ESCAPE_CURRENT_N_IMAGE_URL },
    { key: 'dogeEscapeCurrentSImageUrl', displayName: 'Doge Escape Current (South)', defaultUrl: DOGE_WHALE_ESCAPE_CURRENT_S_IMAGE_URL },
    { key: 'dogeEscapeCurrentEImageUrl', displayName: 'Doge Escape Current (East)', defaultUrl: DOGE_WHALE_ESCAPE_CURRENT_E_IMAGE_URL },
    { key: 'dogeEscapeCurrentWImageUrl', displayName: 'Doge Escape Current (West)', defaultUrl: DOGE_WHALE_ESCAPE_CURRENT_W_IMAGE_URL },
    { key: 'dogeEscapeSnakeImageUrl', displayName: 'Doge Escape Snake', defaultUrl: DOGE_WHALE_ESCAPE_SNAKE_IMAGE_URL },
    { key: 'dogeEscapeLifeUpImageUrl', displayName: 'Doge Escape Life-Up', defaultUrl: DOGE_WHALE_ESCAPE_LIFEUP_IMAGE_URL },
];


export const AdminPanelModal: React.FC<AdminPanelModalProps> = ({
  isOpen,
  onClose,
  adminConfig,
  runtimeNftDefinitions,
  runtimeGameCharacters,
  onUpdateAdminConfig,
  onUpdateNftImage,
  onUpdateCharacterAttributes,
  showNotification,
  isMaximizable,
  isMaximized,
  onToggleMaximize,
  onLogout, // Destructure new prop
}) => {
  const [activeTab, setActiveTab] = useState<AdminTab>('aiChat');
  const [localAdminConfig, setLocalAdminConfig] = useState<AdminConfig>(adminConfig);

  const [nftImageInputs, setNftImageInputs] = useState<Record<string, string>>({}); 
  const [pendingNftImageChanges, setPendingNftImageChanges] = useState<Record<string, string | null>>({}); 

  const [characterAttributeInputs, setCharacterAttributeInputs] = useState<Record<string, CharacterAttributeInputs>>({});

  const [aiPrompts, setAiPrompts] = useState<Record<string, string>>({}); 
  const [aiGeneratedImagePreviews, setAiGeneratedImagePreviews] = useState<Record<string, string | null>>({}); 
  const [isGenerating, setIsGenerating] = useState<Record<string, boolean>>({}); 
  const [superAiAgentEnabled, setSuperAiAgentEnabled] = useState<boolean>(true);

  const [aiSuggestionDimensions, setAiSuggestionDimensions] = useState<string>('');
  const [aiSuggestionDirection, setAiSuggestionDirection] = useState<string>('any');
  const [aiSuggestionStyle, setAiSuggestionStyle] = useState<string>('any');
  const [aiSuggestionBackground, setAiSuggestionBackground] = useState<string>('any');

  const [adminAssetUrlInputs, setAdminAssetUrlInputs] = useState<Record<AdminConfigImageKey, string>>({} as Record<AdminConfigImageKey, string>); 
  const [pendingAdminAssetBase64, setPendingAdminAssetBase64] = useState<Partial<Record<AdminConfigImageKey, string | null>>>({}); 

  const [pendingSoundUploads, setPendingSoundUploads] = useState<Partial<Record<SoundUrlKey, string>>>({});

  // AI Chat Bot State
  const [aiChatMessages, setAiChatMessages] = useState<AIChatMessage[]>([]);
  const [currentAiQuery, setCurrentAiQuery] = useState('');
  const [selectedAiLanguage, setSelectedAiLanguage] = useState(languageOptions[0].code); // Default to English code
  const [isAiResponding, setIsAiResponding] = useState(false);
  const aiChatLogRef = useRef<HTMLDivElement>(null);
  const geminiAi = useMemo(() => new GoogleGenAI({ apiKey: process.env.API_KEY! }), []);

  // Knowledge Base State
  const [newReplyTopic, setNewReplyTopic] = useState<string>('');
  const [newReplyAnswer, setNewReplyAnswer] = useState<string>('');


  useEffect(() => {
    if (isOpen) {
        const newLocalAdminConfig = JSON.parse(JSON.stringify(adminConfig));
        if (!newLocalAdminConfig.savedReplies) { // Initialize if undefined
            newLocalAdminConfig.savedReplies = [];
        }
        setLocalAdminConfig(newLocalAdminConfig);

        const initialNftImageInputs: Record<string, string> = {};
        const initialPendingNftChanges: Record<string, string | null> = {};
        Object.keys(runtimeNftDefinitions).forEach(nftId => {
            const img = runtimeNftDefinitions[nftId].image;
            initialNftImageInputs[nftId] = img.startsWith('data:image') ? '' : img;
            initialPendingNftChanges[nftId] = img.startsWith('data:image') ? img : null;
        });
        setNftImageInputs(initialNftImageInputs);
        setPendingNftImageChanges(initialPendingNftChanges);

        const initialCharAttrInputs: Record<string, CharacterAttributeInputs> = {};
        Object.keys(runtimeGameCharacters).forEach(charId => {
            const char = runtimeGameCharacters[charId];
            initialCharAttrInputs[charId] = {
                name: char.name,
                imageURL: char.image.startsWith('data:image') ? '' : char.image,
                imageBase64: char.image.startsWith('data:image') ? char.image : null,
                defaultWeaponType: char.defaultWeaponType || WeaponType.StandardBullet,
                autoFireHealthThreshold: char.autoFireHealthThreshold || 0,
                baseHealth: char.baseHealth || (char.type === 'player' ? 100 : (char.type === 'enemy' ? 25 : 100)),
                baseSpeed: char.baseSpeed || (char.type === 'enemy' ? 1 : PLAYER_SPEED),
            };
        });
        setCharacterAttributeInputs(initialCharAttrInputs);

        const currentAdminAssetUrlInputs: Record<AdminConfigImageKey, string> = {} as Record<AdminConfigImageKey, string>;
        const currentPendingAdminAssetBase64: Partial<Record<AdminConfigImageKey, string | null>> = {};

        (Object.keys(newLocalAdminConfig) as Array<keyof AdminConfig>).forEach(key => {
            if ((key.toLowerCase().includes('image') || key.toLowerCase().includes('imageurl')) && typeof newLocalAdminConfig[key] === 'string') {
                const imgVal = newLocalAdminConfig[key] as string;
                if (imgVal.startsWith('data:image')) {
                    currentPendingAdminAssetBase64[key as AdminConfigImageKey] = imgVal;
                    currentAdminAssetUrlInputs[key as AdminConfigImageKey] = '';
                } else {
                    currentAdminAssetUrlInputs[key as AdminConfigImageKey] = imgVal;
                    currentPendingAdminAssetBase64[key as AdminConfigImageKey] = null;
                }
            }
        });
        setAdminAssetUrlInputs(currentAdminAssetUrlInputs);
        setPendingAdminAssetBase64(currentPendingAdminAssetBase64);

        setAiPrompts({});
        setAiGeneratedImagePreviews({});
        setIsGenerating({});
        setPendingSoundUploads({});
        
        // Reset AI Chat state
        setAiChatMessages([]);
        setCurrentAiQuery('');
        setIsAiResponding(false);

        // Reset Knowledge Base input fields
        setNewReplyTopic('');
        setNewReplyAnswer('');
    }
  }, [isOpen, adminConfig, runtimeNftDefinitions, runtimeGameCharacters]);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
    const { name, value, type } = e.target;
    const checked = (e.target as HTMLInputElement).checked;
    setLocalAdminConfig(prev => ({
      ...prev,
      [name]: type === 'checkbox' ? checked : type === 'number' ? parseFloat(value) : value,
    }));
  };

  const handleNftImageUrlChange = (nftId: string, value: string) => {
    setNftImageInputs(prev => ({ ...prev, [nftId]: value }));
    setPendingNftImageChanges(prev => ({...prev, [nftId]: null})); 
  };
  const handleNftImageFileUpload = async (nftId: string, file: File | null) => {
    if (file) {
      try {
        const base64String = await convertFileToBase64(file);
        setPendingNftImageChanges(prev => ({...prev, [nftId]: base64String}));
        setNftImageInputs(prev => ({ ...prev, [nftId]: '' })); 
        showNotification(`Image ready for NFT: ${runtimeNftDefinitions[nftId]?.name}. Click 'Apply Custom Image'.`, 'info');
      } catch (error) { console.error("Error converting NFT image:", error); showNotification('Failed to load image file.', 'error');}
    }
  };
  const handleApplyCustomNftImage = (nftId: string) => {
    const pendingBase64 = pendingNftImageChanges[nftId];
    const urlInput = nftImageInputs[nftId];
    if (pendingBase64) {
        onUpdateNftImage(nftId, pendingBase64);
    } else if (urlInput && urlInput.trim() !== '') {
        onUpdateNftImage(nftId, urlInput);
    } else {
        showNotification('No new image (URL or file) to apply.', 'warning');
    }
  };


  const handleCharacterAttributeChange = (characterId: string, field: keyof CharacterAttributeInputs, value: string | number | WeaponType | undefined) => {
    setCharacterAttributeInputs(prev => ({
        ...prev,
        [characterId]: {
            ...(prev[characterId] || {} as CharacterAttributeInputs),
            [field]: value,
            ...(field === 'imageURL' && { imageBase64: null }) 
        }
    }));
  };

  const handleCharacterSelectChange = (characterId: string, field: keyof CharacterAttributeInputs, value: string) => {
    const weaponTypeEnumValue = WeaponType[value as keyof typeof WeaponType];
    handleCharacterAttributeChange(characterId, field, weaponTypeEnumValue || WeaponType.StandardBullet);
  };

  const handleCharacterImageFileUpload = async (characterId: string, file: File | null) => {
    if (file) {
      try {
        const base64String = await convertFileToBase64(file);
        setCharacterAttributeInputs(prev => ({
            ...prev,
            [characterId]: {
                ...(prev[characterId] || {} as CharacterAttributeInputs),
                imageBase64: base64String,
                imageURL: '' 
            }
        }));
        showNotification(`Image ready for Character: ${runtimeGameCharacters[characterId]?.name}. Click 'Apply Custom Image'.`, 'info');
      } catch (error) { console.error("Error converting character image:", error); showNotification('Failed to load image file.', 'error');}
    }
  };

  const handleApplyCustomCharacterImage = (characterId: string) => {
    const currentInputs = characterAttributeInputs[characterId];
    if (!currentInputs) return;
    if (currentInputs.imageBase64) {
        onUpdateCharacterAttributes(characterId, { image: currentInputs.imageBase64 });
    } else if (currentInputs.imageURL && currentInputs.imageURL.trim() !== '') {
        onUpdateCharacterAttributes(characterId, { image: currentInputs.imageURL });
    } else {
        showNotification('No new image (URL or file) to apply for character.', 'warning');
    }
  };


  const handleApplyCharacterNonImageChanges = (characterId: string) => {
    const currentInputs = characterAttributeInputs[characterId];
    if (!currentInputs) return;
    const updates: Partial<GameCharacter> = {};
    const originalChar = runtimeGameCharacters[characterId];

    if (currentInputs.name !== originalChar.name) updates.name = currentInputs.name;
    if (currentInputs.baseHealth !== originalChar.baseHealth && typeof currentInputs.baseHealth === 'number') updates.baseHealth = currentInputs.baseHealth;
    if (currentInputs.baseSpeed !== originalChar.baseSpeed && typeof currentInputs.baseSpeed === 'number') updates.baseSpeed = currentInputs.baseSpeed;

    if (originalChar.type === 'player') {
        if (currentInputs.defaultWeaponType !== (originalChar.defaultWeaponType || WeaponType.StandardBullet)) updates.defaultWeaponType = currentInputs.defaultWeaponType;
        const newThreshold = Number(currentInputs.autoFireHealthThreshold);
        if (newThreshold !== (originalChar.autoFireHealthThreshold || 0) && !isNaN(newThreshold)) updates.autoFireHealthThreshold = Math.max(0, Math.min(100, newThreshold));
    }
    if (Object.keys(updates).length > 0) onUpdateCharacterAttributes(characterId, updates);
    else showNotification('No non-image attributes changed.', 'info');
  };


  const handleAdminConfigAssetUrlChange = (configKey: AdminConfigImageKey, value: string) => {
    setAdminAssetUrlInputs(prev => ({ ...prev, [configKey]: value }));
    setPendingAdminAssetBase64(prev => ({ ...prev, [configKey]: null })); 
    setLocalAdminConfig(prev => ({ ...prev, [configKey]: value })); 
  };

  const handleAdminConfigAssetFileUpload = async (configKey: AdminConfigImageKey, file: File | null) => {
    if (file) {
      try {
        const base64String = await convertFileToBase64(file);
        setPendingAdminAssetBase64(prev => ({ ...prev, [configKey]: base64String }));
        setAdminAssetUrlInputs(prev => ({ ...prev, [configKey]: '' })); 
        setLocalAdminConfig(prev => ({ ...prev, [configKey]: base64String })); 
        showNotification(`Image ready for ${configKey}. Save all admin changes to finalize.`, 'info');
      } catch (error) { console.error(`Error converting ${configKey} image:`, error); showNotification('Failed to load image file.', 'error'); }
    }
  };
  
  const handleApplyCustomAdminConfigAssetImage = (configKey: AdminConfigImageKey) => {
    const pendingBase64 = pendingAdminAssetBase64[configKey];
    const urlInput = adminAssetUrlInputs[configKey];
    let applied = false;
    if (pendingBase64) {
        setLocalAdminConfig(prev => ({ ...prev, [configKey]: pendingBase64 }));
        applied = true;
    } else if (urlInput && urlInput.trim() !== '') {
        setLocalAdminConfig(prev => ({ ...prev, [configKey]: urlInput }));
        applied = true;
    }
    if (applied) showNotification(`Preview updated for ${configKey}. Save all admin changes to finalize.`, 'info');
    else showNotification(`No new image (URL or file) to apply for ${configKey}.`, 'warning');
  };


  const handleSoundFileUpload = async (eventKey: SoundEvent, file: File | null) => {
    if (file) {
        try {
            const base64String = await convertFileToBase64(file);
            const adminSoundKeyPattern = `sound${eventKey.charAt(0).toUpperCase() + eventKey.slice(1).replace(/_([a-z])/g, (g) => g[1].toUpperCase())}Url`;
            const adminSoundKey = adminSoundKeyPattern as SoundUrlKey;
            setPendingSoundUploads(prev => ({...prev, [adminSoundKey]: base64String}));
            setLocalAdminConfig(prev => ({ ...prev, [adminSoundKey]: base64String })); 
            showNotification(`${formatSoundEventName(eventKey)} sound updated. Save all admin changes to finalize.`, 'info');
        } catch (error) { console.error(`Error converting sound file for ${eventKey}:`, error); showNotification(`Failed to load sound for ${eventKey}.`, 'error');}
    }
  };


  const handleSaveAllAdminChanges = () => {
    const finalConfig = {...localAdminConfig};
    (Object.keys(pendingAdminAssetBase64) as Array<AdminConfigImageKey>).forEach(key => {
        if (pendingAdminAssetBase64[key]) {
            finalConfig[key] = pendingAdminAssetBase64[key]!;
        } else if (adminAssetUrlInputs[key] && adminAssetUrlInputs[key].trim() !== '') {
            finalConfig[key] = adminAssetUrlInputs[key];
        }
    });
    Object.keys(pendingSoundUploads).forEach(stringKey => {
        const key = stringKey as SoundUrlKey;
        if (pendingSoundUploads[key]) {
            finalConfig[key] = pendingSoundUploads[key]!;
        }
    });
    onUpdateAdminConfig(finalConfig);
  };

  const handleAiPromptChange = (assetKey: string, prompt: string) => {
    setAiPrompts(prev => ({ ...prev, [assetKey]: prompt }));
  };

  const generateCharacterPromptFromName = (
    characterName: string,
    characterType: 'player' | 'enemy'
  ): string => {
      const cleanName = characterName.replace(/\p{Emoji}/gu, '').trim();
      let baseDescription = "";
  
      if (characterType === 'player') {
          baseDescription = `A game character asset, a player Doge Whale, visually representing: ${cleanName}.`;
      } else { 
          baseDescription = `A game character asset, an enemy sea creature, visually representing: ${cleanName}.`;
      }
  
      let prompt = `${baseDescription}`;
  
      if (aiSuggestionStyle && aiSuggestionStyle !== 'any') {
          prompt += ` Style: ${aiSuggestionStyle}.`;
      } else {
          prompt += ` Style: 3D render.`; 
      }
      if (aiSuggestionDimensions) {
          prompt += ` Dimensions: ${aiSuggestionDimensions}.`;
      }
      if (aiSuggestionDirection && aiSuggestionDirection !== 'any') {
          prompt += ` Direction: ${aiSuggestionDirection}.`;
      }
      if (aiSuggestionBackground && aiSuggestionBackground !== 'any') {
          prompt += ` Background: ${aiSuggestionBackground}.`;
      } else {
          prompt += ` Background: transparent background for versatility.`;
      }
      return prompt.trim();
  };

  const handleAutoGenerateForCharacter = async (characterId: string) => {
    const character = runtimeGameCharacters[characterId];
    if (!character) return;

    const assetKey = `char_${characterId}`;
    const generatedPrompt = generateCharacterPromptFromName(
        character.name,
        character.type
    );
    
    setAiPrompts(prev => ({ ...prev, [assetKey]: generatedPrompt }));
    showNotification(`Prompt suggested for ${character.name}: "${generatedPrompt.substring(0,50)}..."`, 'info');
    
    await handleGenerateAiImage(assetKey, 'character', characterId);
  };


  const handleGenerateAiImage = async (assetKey: string, itemType: string, idOrConfigKey: string) => {
    const userPrompt = aiPrompts[assetKey]; 
    if (!userPrompt) {
      showNotification("Please enter or auto-generate a prompt for the AI.", "warning");
      return;
    }

    setIsGenerating(prev => ({ ...prev, [assetKey]: true }));
    setAiGeneratedImagePreviews(prev => ({ ...prev, [assetKey]: null }));

    let fullPrompt = ""; 
    let itemNameForNotification = idOrConfigKey;

    switch (itemType) {
        case 'nft':
            fullPrompt = `A digital art NFT for a game, depicting a Doge Whale character. The NFT should represent: ${userPrompt}.`;
            itemNameForNotification = runtimeNftDefinitions[idOrConfigKey]?.name || idOrConfigKey;
            break;
        case 'character':
            fullPrompt = userPrompt; 
            itemNameForNotification = runtimeGameCharacters[idOrConfigKey]?.name || idOrConfigKey;
            break;
        case 'adminConfigAsset': // Generic handler for AdminConfig assets based on idOrConfigKey
            const configKeyName = idOrConfigKey as keyof AdminConfig;
            const displayNameForKey = configKeyName
                                        .replace('adminConfig_', '')
                                        .replace('ImageUrl', '')
                                        .replace('Image', '')
                                        .replace(/([A-Z])/g, ' $1').trim();

            if (configKeyName.includes('dogeEscape')) {
                 fullPrompt = `A game asset for 'Doge Whale Escape', a 2D maze game. The asset is a ${displayNameForKey}. Appearance: ${userPrompt}. Style: Clear, slightly pixelated or cartoonish, suitable for a grid-based game.`;
            } else if (configKeyName === 'gameBackgroundImageUrl') {
                 fullPrompt = `A vibrant and immersive game background for an underwater space MMORPG featuring Doge Whales. The scene should be: ${userPrompt}. Scenic and detailed.`;
            } else if (configKeyName === 'defaultEnemyImageUrl') {
                fullPrompt = `A generic enemy creature for an underwater space game. Appearance: ${userPrompt}. Needs to be distinct and somewhat menacing.`;
            } else if (configKeyName === 'seaTokenImageUrl') {
                fullPrompt = `A single, distinct game currency item called a "Sea Token". It should look like: ${userPrompt}. Small, clear, iconic design.`;
            } else if (configKeyName === 'redArrowImageUrl') {
                 fullPrompt = `A sleek, powerful red arrow projectile for a defensive weapon system in a space game. Appearance: ${userPrompt}. Dynamic, sci-fi style, glowing red.`;
            } else if (configKeyName === 'flameParticleImageUrl') {
                fullPrompt = `Small, bright, fiery particles or hot embers, suitable for a flame cone weapon effect in a game. Details: ${userPrompt}. Style: VFX sprite, clear background if possible.`;
            } else if (configKeyName === 'enemyBurningEffectImageUrl') {
                fullPrompt = `A visual effect for a game, representing an enemy character on fire. Could be a sprite sheet for an animation or a static overlay. Details: ${userPrompt}. Style: Game visual effect, transparent background suitable for overlay.`;
            } else if (configKeyName === 'fireballProjectileImageUrl') {
                 fullPrompt = `A dynamic and impactful fireball projectile for a fantasy or sci-fi game weapon. Details: ${userPrompt}. Style: Magical, fiery, possibly with a trailing effect, on a transparent background.`;
            } else if (configKeyName.startsWith('decorativeFish')) {
                 const fishType = displayNameForKey.replace('Decorative Fish ', '');
                 fullPrompt = `A decorative ${fishType.toLowerCase()} fish for an underwater space game. Appearance: ${userPrompt}.`;
            } else if (configKeyName.startsWith('bubble')) {
                 const bubbleSize = displayNameForKey.replace('Bubble ', '');
                 fullPrompt = `A ${bubbleSize.toLowerCase()} bubble effect for an underwater game. Appearance: ${userPrompt}.`;
            } else {
                 fullPrompt = `A game asset: ${displayNameForKey}. Description: ${userPrompt}.`;
            }
            itemNameForNotification = displayNameForKey;
            break;
        default:
            showNotification("Unknown item type for AI generation.", "error");
            setIsGenerating(prev => ({ ...prev, [assetKey]: false }));
            return;
    }

    const result: GeminiImageResponse = await generateImageWithGemini(fullPrompt);
    setIsGenerating(prev => ({ ...prev, [assetKey]: false }));

    if (result.success && result.imageUrl) {
      setAiGeneratedImagePreviews(prev => ({ ...prev, [assetKey]: result.imageUrl! }));
      if (superAiAgentEnabled) {
        handleApplyAiImage(assetKey, itemType, idOrConfigKey, result.imageUrl);
        showNotification(`AI image generated and auto-applied to ${itemNameForNotification}!`, "success");
      } else {
        showNotification(`Image generated for ${itemNameForNotification}! Preview below. Click 'Apply AI Image'.`, "success");
      }
    } else {
        if (result.errorType === 'quota_exhausted') {
            showNotification(result.message || 'API Quota Exceeded. Check your plan or wait for reset.', 'error');
        } else {
            showNotification(result.message || `Failed to generate image for ${itemNameForNotification}. Check console.`, 'error');
        }
    }
  };

  const handleApplyAiImage = (assetKey: string, itemType: string, idOrConfigKey: string, imageUrlToApply?: string) => {
    const imageUrl = imageUrlToApply || aiGeneratedImagePreviews[assetKey];
    if (!imageUrl) {
      showNotification("No AI-generated image to apply.", "warning");
      return;
    }

    let itemNameForNotification = idOrConfigKey;

    if (itemType === 'nft') {
      onUpdateNftImage(idOrConfigKey, imageUrl);
      itemNameForNotification = runtimeNftDefinitions[idOrConfigKey]?.name || idOrConfigKey;
      showNotification(`AI image applied to NFT: ${itemNameForNotification}.`, "success");
    } else if (itemType === 'character') {
      onUpdateCharacterAttributes(idOrConfigKey, { image: imageUrl });
      itemNameForNotification = runtimeGameCharacters[idOrConfigKey]?.name || idOrConfigKey;
      showNotification(`AI image applied to Character: ${itemNameForNotification}.`, "success");
    } else if (itemType === 'adminConfigAsset') { // Updated for generic admin config assets
        const configKey = idOrConfigKey as AdminConfigImageKey;
        setLocalAdminConfig(prev => ({ ...prev, [configKey]: imageUrl }));
        setPendingAdminAssetBase64(prev => ({ ...prev, [configKey]: imageUrl }));
        setAdminAssetUrlInputs(prev => ({ ...prev, [configKey]: '' })); 

        itemNameForNotification = configKey.replace('adminConfig_', '').replace('ImageUrl', '').replace('Image', '').replace(/([A-Z])/g, ' $1').trim();
        showNotification(`AI image applied to ${itemNameForNotification}. Save all admin changes to finalize.`, "success");
    } else {
        showNotification("Unknown item type for applying AI image.", "error");
        return;
    }

    if (!superAiAgentEnabled || imageUrlToApply) { 
        setAiGeneratedImagePreviews(prev => ({ ...prev, [assetKey]: null })); 
    }
  };

  // AI Chat Bot Logic
  const handleSendAiQuery = async () => {
    if (currentAiQuery.trim() === '' || isAiResponding) return;

    const userMessage: AIChatMessage = {
      id: generateId(),
      sender: 'user',
      text: currentAiQuery,
      lang: languageOptions.find(l => l.code === selectedAiLanguage)?.name || selectedAiLanguage,
    };
    setAiChatMessages(prev => [...prev, userMessage]);
    setIsAiResponding(true);
    setCurrentAiQuery('');

    try {
      const languageName = languageOptions.find(l => l.code === selectedAiLanguage)?.name || 'English';
      let knowledgeBaseText = "";
      if (localAdminConfig.savedReplies && localAdminConfig.savedReplies.length > 0) {
          knowledgeBaseText = "You have access to the following predefined knowledge base. Use this information when relevant to the user's query:\n";
          knowledgeBaseText += JSON.stringify(localAdminConfig.savedReplies.map(r => ({topic: r.topic, answer: r.answer}))) + "\n---\n";
      }
      
      const systemInstruction = `${knowledgeBaseText}You are a helpful AI assistant for a game administrator. Respond to the user's query in ${languageName}. Be concise and helpful.`;
      
      const response: GenerateContentResponse = await geminiAi.models.generateContent({
        model: 'gemini-2.5-flash-preview-04-17',
        contents: userMessage.text,
        config: { systemInstruction: systemInstruction },
      });

      const aiTextResponse = response.text;
      const aiMessage: AIChatMessage = {
        id: generateId(),
        sender: 'ai',
        text: aiTextResponse,
      };
      setAiChatMessages(prev => [...prev, aiMessage]);

    } catch (error: any) {
      console.error("Error with AI Chat:", error);
      const errorMessage: AIChatMessage = {
        id: generateId(),
        sender: 'error',
        text: `AI Error: ${error.message || 'Could not get a response.'}`,
      };
      setAiChatMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsAiResponding(false);
    }
  };

  useEffect(() => {
    if (aiChatLogRef.current) {
      aiChatLogRef.current.scrollTop = aiChatLogRef.current.scrollHeight;
    }
  }, [aiChatMessages]);

  // Knowledge Base Management
  const handleAddReply = () => {
    if (!newReplyTopic.trim() || !newReplyAnswer.trim()) {
        showNotification("Topic and Answer cannot be empty.", "warning");
        return;
    }
    setLocalAdminConfig(prev => ({
        ...prev,
        savedReplies: [
            ...(prev.savedReplies || []),
            { id: generateId(), topic: newReplyTopic.trim(), answer: newReplyAnswer.trim() }
        ]
    }));
    setNewReplyTopic('');
    setNewReplyAnswer('');
    showNotification("Reply added to knowledge base. Save all admin changes to finalize.", "info");
  };

  const handleDeleteReply = (replyId: string) => {
    setLocalAdminConfig(prev => ({
        ...prev,
        savedReplies: (prev.savedReplies || []).filter(reply => reply.id !== replyId)
    }));
    showNotification("Reply removed from knowledge base. Save all admin changes to finalize.", "info");
  };


  const renderAssetImageEditor = (
    editorAssetKey: string, 
    displayName: string,
    itemType: 'nft' | 'character' | 'adminConfigAsset',
    idOrConfigKey: string, 
    currentImageUrl: string | undefined
  ) => {
    const assetSpecificPrompt = aiPrompts[editorAssetKey] || '';
    const isAssetGenerating = isGenerating[editorAssetKey] || false;
    const assetAiPreview = aiGeneratedImagePreviews[editorAssetKey] || null;
    const character = itemType === 'character' ? runtimeGameCharacters[idOrConfigKey] : null;
    
    let assetUrlInputValue = '';
    if (itemType === 'adminConfigAsset') {
      assetUrlInputValue = adminAssetUrlInputs[idOrConfigKey as AdminConfigImageKey] || '';
    } else if (itemType === 'nft') {
      assetUrlInputValue = nftImageInputs[idOrConfigKey] || '';
    } else if (itemType === 'character') {
      assetUrlInputValue = characterAttributeInputs[idOrConfigKey]?.imageURL || '';
    }


    return (
        <div className="mb-8 p-4 border rounded-lg bg-theme-dark/40 border-theme-border/40">
            <h5 className="text-lg font-medium text-gray-100 mb-3">{displayName}</h5>
            <img
                src={currentImageUrl || 'https://via.placeholder.com/150?text=No+Image'}
                alt={`${displayName} current preview`}
                className="w-32 h-32 object-contain rounded-md bg-black/40 border border-theme-border/60 mb-3"
                onError={(e) => (e.currentTarget.src = 'https://via.placeholder.com/150?text=Error')}
            />
            <div className="mb-3">
                <label htmlFor={`ai-prompt-${editorAssetKey}`} className="block text-sm font-medium text-gray-300 mb-1">AI Prompt:</label>
                <textarea id={`ai-prompt-${editorAssetKey}`} rows={3} value={assetSpecificPrompt} onChange={(e) => handleAiPromptChange(editorAssetKey, e.target.value)} placeholder="Describe the image or click Auto-Generate..." className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
                <div className="flex flex-wrap gap-2 mt-1.5">
                    {itemType === 'character' && character && (
                         <button 
                            onClick={() => handleAutoGenerateForCharacter(idOrConfigKey)} 
                            disabled={isAssetGenerating} 
                            className="py-2 px-4 bg-teal-600 hover:bg-teal-700 text-white text-sm font-semibold rounded-md transition-colors disabled:bg-teal-400 flex items-center"
                            title={`Auto-generate prompt & image for ${character.name}`}
                        >
                            ✨ Auto-Generate Art
                        </button>
                    )}
                    <button onClick={() => handleGenerateAiImage(editorAssetKey, itemType, idOrConfigKey)} disabled={isAssetGenerating} className="py-2 px-4 bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold rounded-md transition-colors disabled:bg-pink-400 disabled:text-gray-100 flex items-center">
                        {isAssetGenerating && <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin mr-2"></div>}Generate AI Image
                    </button>
                </div>
                {assetAiPreview && (
                    <div className="mt-2">
                        <img src={assetAiPreview} alt="AI Preview" className="w-28 h-28 object-contain rounded-md bg-black/40 border border-theme-border/60"/>
                        {!superAiAgentEnabled && (
                            <button onClick={() => handleApplyAiImage(editorAssetKey, itemType, idOrConfigKey)} className="mt-1.5 py-1.5 px-3 bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold rounded-md transition-colors">Apply AI Image</button>
                        )}
                    </div>
                )}
            </div>
            <div className="mb-3">
                <label htmlFor={`file-${editorAssetKey}`} className="block text-sm font-medium text-gray-300 mb-1">Upload Image:</label>
                <input type="file" id={`file-${editorAssetKey}`} accept="image/*,image/gif"
                    onChange={(e) => {
                        const file = e.target.files ? e.target.files[0] : null;
                        if (itemType === 'nft') handleNftImageFileUpload(idOrConfigKey, file);
                        else if (itemType === 'character') handleCharacterImageFileUpload(idOrConfigKey, file);
                        else if (itemType === 'adminConfigAsset') handleAdminConfigAssetFileUpload(idOrConfigKey as AdminConfigImageKey, file);
                    }}
                    className="w-full text-base text-gray-300 file:mr-3 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-pink-600 file:text-white hover:file:bg-pink-700"/>
            </div>
            <div className="mb-3">
                <label htmlFor={`url-${editorAssetKey}`} className="block text-sm font-medium text-gray-300 mb-1">Image Source URL or Local Path:</label>
                <input type="text" id={`url-${editorAssetKey}`} value={assetUrlInputValue}
                    onChange={(e) => {
                        if (itemType === 'nft') handleNftImageUrlChange(idOrConfigKey, e.target.value);
                        else if (itemType === 'character') handleCharacterAttributeChange(idOrConfigKey, 'imageURL', e.target.value);
                        else if (itemType === 'adminConfigAsset') handleAdminConfigAssetUrlChange(idOrConfigKey as AdminConfigImageKey, e.target.value);
                    }}
                    className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500" placeholder="Enter image URL or local path"/>
                 <p className="text-xs text-gray-400 mt-1">Enter URL (https://...), local path (e.g., /assets/images/image.png), or upload a file.</p>
            </div>
            {(itemType === 'nft' || itemType === 'character' || itemType === 'adminConfigAsset') && (
                 <button
                    onClick={() => {
                        if (itemType === 'nft') handleApplyCustomNftImage(idOrConfigKey);
                        else if (itemType === 'character') handleApplyCustomCharacterImage(idOrConfigKey);
                        else if (itemType === 'adminConfigAsset') handleApplyCustomAdminConfigAssetImage(idOrConfigKey as AdminConfigImageKey);
                    }}
                    className="mt-1.5 py-2 px-4 bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold rounded-md transition-colors"
                >
                    Apply Custom Image (Upload/URL)
                </button>
            )}
        </div>
    );
  };


  const renderNftManagement = () => (
    <div className="space-y-6 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-xl font-semibold text-theme-accent mb-4">Manage NFT Images</h3>
      {Object.values(runtimeNftDefinitions).map(nft => (
         renderAssetImageEditor(`nft_${nft.id}`, nft.name, 'nft', nft.id, pendingNftImageChanges[nft.id] || nftImageInputs[nft.id] || nft.image)
      ))}
    </div>
  );

  const renderCharacterManagement = () => (
    <div className="space-y-6 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-xl font-semibold text-theme-accent mb-4">Manage Game Characters</h3>
      {Object.keys(runtimeGameCharacters).map(charId => {
        const character = runtimeGameCharacters[charId];
        const currentInputs = characterAttributeInputs[charId] || { name: '', imageURL: '', defaultWeaponType: WeaponType.StandardBullet, autoFireHealthThreshold: 0, baseHealth: 100, baseSpeed: 1 };
        const charEditorKey = `char_${charId}`;
        let currentImageDisplay = character.image;
        if (currentInputs.imageBase64) currentImageDisplay = currentInputs.imageBase64;
        else if (currentInputs.imageURL) currentImageDisplay = currentInputs.imageURL;

        return (
            <div key={character.id} className="p-4 bg-theme-dark/60 rounded-lg border border-theme-border/60">
                <h4 className="text-lg font-medium text-gray-100 mb-3">{currentInputs.name || character.name} <span className="text-sm text-gray-400">({character.type})</span></h4>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-start mb-3">
                    <div><label htmlFor={`charName-${charId}`} className="block text-sm font-medium text-gray-300 mb-1">Name:</label><input type="text" id={`charName-${charId}`} value={currentInputs.name} onChange={(e) => handleCharacterAttributeChange(charId, 'name', e.target.value)} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
                    <div><label htmlFor={`charBaseHealth-${charId}`} className="block text-sm font-medium text-gray-300 mb-1">Base Health:</label><input type="number" id={`charBaseHealth-${charId}`} value={currentInputs.baseHealth} onChange={(e) => handleCharacterAttributeChange(charId, 'baseHealth', parseInt(e.target.value, 10))} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
                    {character.type === 'enemy' && (
                        <div><label htmlFor={`charBaseSpeed-${charId}`} className="block text-sm font-medium text-gray-300 mb-1">Base Speed:</label><input type="number" step="0.1" id={`charBaseSpeed-${charId}`} value={currentInputs.baseSpeed} onChange={(e) => handleCharacterAttributeChange(charId, 'baseSpeed', parseFloat(e.target.value))} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
                    )}
                    {character.type === 'player' && (
                        <>
                            <div><label htmlFor={`charWeaponType-${charId}`} className="block text-sm font-medium text-gray-300 mb-1">Weapon:</label><select id={`charWeaponType-${charId}`} value={Object.keys(WeaponType).find(key => WeaponType[key as keyof typeof WeaponType] === currentInputs.defaultWeaponType) || 'StandardBullet'} onChange={(e) => handleCharacterSelectChange(charId, 'defaultWeaponType', e.target.value)} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500">{Object.keys(WeaponType).map(weaponKey => (<option key={weaponKey} value={weaponKey}>{formatWeaponTypeName(weaponKey)}</option>))}</select></div>
                            <div><label htmlFor={`charAutoFire-${charId}`} className="block text-sm font-medium text-gray-300 mb-1">Auto-Fire Threshold (%):</label><input type="number" id={`charAutoFire-${charId}`} value={currentInputs.autoFireHealthThreshold || 0} min="0" max="100" onChange={(e) => handleCharacterAttributeChange(charId, 'autoFireHealthThreshold', parseInt(e.target.value, 10))} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
                        </>
                    )}
                </div>
                 <button onClick={() => handleApplyCharacterNonImageChanges(charId)} className="mt-2 py-2 px-4 bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold rounded-md transition-colors">Apply Attribute Changes</button>

                {renderAssetImageEditor(
                    charEditorKey,
                    `Image for ${currentInputs.name || character.name}`,
                    'character',
                    charId,
                    currentImageDisplay
                )}
            </div>
        )
      })}
    </div>
  );

  const renderStakingRates = () => (
    <div className="space-y-6">
      <h3 className="text-xl font-semibold text-theme-accent mb-4">Staking Configuration</h3>
      <div><label htmlFor="globalNftStakingRate" className="block text-base font-medium text-gray-200 mb-1.5">Global NFT Staking Reward Rate (Sea Tokens per NFT per hour):</label><input type="number" id="globalNftStakingRate" name="globalNftStakingRate" value={localAdminConfig.globalNftStakingRate} onChange={handleInputChange} step="0.01" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/><p className="text-sm text-gray-400 mt-1.5">Note: Slot staking uses its own base rate. This may apply to other/future staking.</p></div>
      <div><label htmlFor="globalTokenStakingRate" className="block text-base font-medium text-gray-200 mb-1.5">Sea Token Staking Reward Rate (per hour, e.g., 0.05 for 5%):</label><input type="number" id="globalTokenStakingRate" name="globalTokenStakingRate" value={localAdminConfig.globalTokenStakingRate} onChange={handleInputChange} step="0.001" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
    </div>
  );

  const renderGameAssets = () => ( 
    <div className="space-y-8 max-h-[60vh] overflow-y-auto pr-3">
      <p className="text-base text-gray-300">Asset images are now primarily managed in the "🤖 AI Img Gen" tab. This tab shows current settings and allows specific URL overrides if needed. Ensure images exist at the specified paths if using local assets (e.g., /assets/images/your-file.png).</p>
      
      {(['gameBackgroundImageUrl', 'defaultEnemyImageUrl', 'seaTokenImageUrl', 'redArrowImageUrl', 'flameParticleImageUrl', 'enemyBurningEffectImageUrl', 'fireballProjectileImageUrl'] as AdminConfigImageKey[]).map(configKey => {
        const displayName = configKey
            .replace('Url', '')
            .replace('Image', '')
            .replace(/([A-Z])/g, ' $1')
            .replace(/^./, str => str.toUpperCase())
            .trim();
        
        return (
            <div key={configKey} className="p-4 bg-theme-dark/60 rounded-lg border border-theme-border/60">
                <h4 className="text-lg font-medium text-gray-100 mb-2">{displayName}</h4>
                <img 
                    src={pendingAdminAssetBase64[configKey] || adminAssetUrlInputs[configKey] || localAdminConfig[configKey] || 'https://via.placeholder.com/150?text=No+Image'} 
                    alt={`${displayName} Preview`} 
                    className="w-32 h-32 object-contain rounded-md bg-black/40 border border-theme-border/60 mb-2"
                    onError={(e) => (e.currentTarget.src = 'https://via.placeholder.com/150?text=Error')}
                />
                <div>
                    <label htmlFor={`asset-url-${configKey}`} className="block text-sm font-medium text-gray-300 mb-1">Image Source URL or Local Path:</label>
                    <input 
                        type="text" 
                        id={`asset-url-${configKey}`} 
                        value={adminAssetUrlInputs[configKey] || ''} 
                        onChange={(e) => handleAdminConfigAssetUrlChange(configKey, e.target.value)}
                        className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"
                        placeholder="Enter image URL or local path"
                    />
                    <p className="text-xs text-gray-400 mt-1">Enter URL (https://...), local path (e.g., /assets/images/image.png), or upload via AI Gen tab.</p>
                </div>
            </div>
        );
      })}
      
       <div>
        <h3 className="text-xl font-semibold text-theme-accent mb-3">Decorative Fish & Bubbles</h3>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            {(['decorativeFishGoldenImage', 'decorativeFishStarImage', 'decorativeFishBluefinImage', 'bubbleSmallImage', 'bubbleMediumImage', 'bubbleLargeImage'] as AdminConfigImageKey[]).map(key => (
                <div key={key} className="p-4 bg-theme-dark/60 rounded-lg border border-theme-border/60">
                    <h4 className="text-lg font-medium text-gray-100 mb-2">{key.replace(/([A-Z])/g, ' $1').replace('Image','').trim()}:</h4>
                     <img src={pendingAdminAssetBase64[key] || adminAssetUrlInputs[key] || localAdminConfig[key] || `https://via.placeholder.com/100?text=${key.substring(0,10)}`} alt={`${key} preview`} className="w-24 h-24 object-contain rounded-lg bg-black/40 border border-theme-border/60 mb-2" onError={(e) => (e.currentTarget.src = 'https://via.placeholder.com/100?text=Error')}/>
                    <div>
                        <label htmlFor={`asset-url-${key}`} className="block text-sm font-medium text-gray-300 mb-1">Image Source URL or Local Path:</label>
                        <input 
                            type="text" 
                            id={`asset-url-${key}`} 
                            value={adminAssetUrlInputs[key] || ''} 
                            onChange={(e) => handleAdminConfigAssetUrlChange(key, e.target.value)}
                            className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"
                            placeholder="Enter image URL or local path"
                        />
                        <p className="text-xs text-gray-400 mt-1">Enter URL (https://...), local path (e.g., /assets/images/image.png), or upload via AI Gen tab.</p>
                    </div>
                </div>
            ))}
        </div>
      </div>
    </div>
  );

  const renderDogeEscapeAssets = () => (
    <div className="space-y-8 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-xl font-semibold text-theme-accent mb-4">Doge Whale Escape Game Assets</h3>
      <p className="text-sm text-gray-300 mb-6">Customize the images used in the Doge Whale Escape mini-game. Use the AI Generator, upload files, or provide URLs.</p>
      {dogeEscapeAssetConfigKeys.map(({ key, displayName, defaultUrl }) => 
        renderAssetImageEditor(
          `adminConfig_${key}`, 
          displayName, 
          'adminConfigAsset', 
          key, 
          (pendingAdminAssetBase64[key] as string | undefined) || (adminAssetUrlInputs[key] as string | undefined) || (localAdminConfig[key] as string | undefined) || defaultUrl
        )
      )}
    </div>
  );


  const renderGameplayMechanics = () => (
    <div className="space-y-6 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-xl font-semibold text-theme-accent mb-4">Core Gameplay Mechanics</h3>
      <div className="flex items-center justify-between p-4 bg-theme-dark/60 rounded-lg"><label htmlFor="playerAutoFire" className="text-base font-medium text-gray-200">Player Auto-Fire (for relevant weapons):</label><input type="checkbox" id="playerAutoFire" name="playerAutoFire" checked={localAdminConfig.playerAutoFire} onChange={handleInputChange} className="form-checkbox h-6 w-6 text-pink-600 bg-gray-700 border-gray-600 rounded focus:ring-pink-500"/></div>
      <div className="flex items-center justify-between p-4 bg-theme-dark/60 rounded-lg"><label htmlFor="playerAutoTargets" className="text-base font-medium text-gray-200">Player Aim Assist (auto-targets nearest enemy):</label><input type="checkbox" id="playerAutoTargets" name="playerAutoTargets" checked={localAdminConfig.playerAutoTargets || false} onChange={handleInputChange} className="form-checkbox h-6 w-6 text-pink-600 bg-gray-700 border-gray-600 rounded focus:ring-pink-500"/></div>
      <div className="flex items-center justify-between p-4 bg-theme-dark/60 rounded-lg"><label htmlFor="enemiesAutoTarget" className="text-base font-medium text-gray-200">Enemies Auto-Target Player:</label><input type="checkbox" id="enemiesAutoTarget" name="enemiesAutoTarget" checked={localAdminConfig.enemiesAutoTarget} onChange={handleInputChange} className="form-checkbox h-6 w-6 text-pink-600 bg-gray-700 border-gray-600 rounded focus:ring-pink-500"/></div>
      <div className="p-4 bg-theme-dark/60 rounded-lg">
        <label htmlFor="enemyFireCooldownMs" className="block text-base font-medium text-gray-200 mb-1.5">Enemy Fire Cooldown (ms):</label>
        <input type="number" id="enemyFireCooldownMs" name="enemyFireCooldownMs" value={localAdminConfig.enemyFireCooldownMs} onChange={handleInputChange} step="100" min="100" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
        <p className="text-sm text-gray-400 mt-1.5">Default: 2200ms. Lower is faster.</p>
      </div>

      <h3 className="text-xl font-semibold text-theme-accent mt-6 mb-4">Red Arrow Defense System</h3>
       <div className="flex items-center justify-between p-4 bg-theme-dark/60 rounded-lg"><label htmlFor="redArrowActive" className="text-base font-medium text-gray-200">Enable Red Arrow System (for Guardian Whale):</label><input type="checkbox" id="redArrowActive" name="redArrowActive" checked={localAdminConfig.redArrowActive} onChange={handleInputChange} className="form-checkbox h-6 w-6 text-pink-600 bg-gray-700 border-gray-600 rounded focus:ring-pink-500"/></div>
      <div className="p-4 bg-theme-dark/60 rounded-lg">
        <label htmlFor="redArrowCooldownMs" className="block text-base font-medium text-gray-200 mb-1.5">Red Arrow Cooldown (ms per shot):</label>
        <input type="number" id="redArrowCooldownMs" name="redArrowCooldownMs" value={localAdminConfig.redArrowCooldownMs} onChange={handleInputChange} step="50" min="50" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
        <p className="text-sm text-gray-400 mt-1.5">Default: {COOLDOWN_RED_ARROW_DEFENSE}ms (2 shots per second).</p>
      </div>
       <div className="p-4 bg-theme-dark/60 rounded-lg">
        <label htmlFor="redArrowShotCount" className="block text-base font-medium text-gray-200 mb-1.5">Red Arrows Fired Per Burst:</label>
        <input type="number" id="redArrowShotCount" name="redArrowShotCount" value={localAdminConfig.redArrowShotCount || RED_ARROW_DEFAULT_SHOT_COUNT} onChange={handleInputChange} step="1" min="1" max="10" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
        <p className="text-sm text-gray-400 mt-1.5">Default: {RED_ARROW_DEFAULT_SHOT_COUNT}. Number of arrows fired at once by Guardian Whale.</p>
      </div>
      <div className="p-4 bg-theme-dark/60 rounded-lg">
        <label htmlFor="redArrowProjectileSpeed" className="block text-base font-medium text-gray-200 mb-1.5">Red Arrow Projectile Speed:</label>
        <input type="number" id="redArrowProjectileSpeed" name="redArrowProjectileSpeed" value={localAdminConfig.redArrowProjectileSpeed} onChange={handleInputChange} step="0.5" min="1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
        <p className="text-sm text-gray-400 mt-1.5">Default: {RED_ARROW_PROJECTILE_SPEED}.</p>
      </div>
      <div className="p-4 bg-theme-dark/60 rounded-lg">
        <label htmlFor="redArrowDamage" className="block text-base font-medium text-gray-200 mb-1.5">Red Arrow Damage:</label>
        <input type="number" id="redArrowDamage" name="redArrowDamage" value={localAdminConfig.redArrowDamage} onChange={handleInputChange} step="10" min="0" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
        <p className="text-sm text-gray-400 mt-1.5">Default: {RED_ARROW_PROJECTILE_DAMAGE} (High damage for intercept/kill effect).</p>
      </div>
    </div>
  );


  const renderAiAssetGenerator = () => (
    <div className="space-y-8 max-h-[60vh] overflow-y-auto pr-3">
        <div className="p-5 bg-theme-dark/80 rounded-xl shadow-xl mb-6"> 
            <h4 className="text-lg font-semibold text-theme-accent mb-4">AI Generation Global Suggestions</h4>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div><label htmlFor="aiDimensions" className="block text-sm font-medium text-gray-300 mb-1">Dimensions/Aspect:</label><input type="text" id="aiDimensions" value={aiSuggestionDimensions} onChange={e => setAiSuggestionDimensions(e.target.value)} placeholder="e.g., 512x512, wide, portrait" className="w-full p-2.5 text-base rounded-md bg-theme-dark border-theme-border focus:ring-pink-500 focus:border-pink-500"/></div>
                <div><label htmlFor="aiDirection" className="block text-sm font-medium text-gray-300 mb-1">Facing Direction:</label><select id="aiDirection" value={aiSuggestionDirection} onChange={e => setAiSuggestionDirection(e.target.value)} className="w-full p-2.5 text-base rounded-md bg-theme-dark border-theme-border focus:ring-pink-500 focus:border-pink-500"><option value="any">Any</option><option value="facing right">Facing Right</option><option value="facing left">Facing Left</option><option value="front view">Front View</option><option value="side view">Side View</option></select></div>
                <div><label htmlFor="aiStyle" className="block text-sm font-medium text-gray-300 mb-1">Art Style:</label><select id="aiStyle" value={aiSuggestionStyle} onChange={e => setAiSuggestionStyle(e.target.value)} className="w-full p-2.5 text-base rounded-md bg-theme-dark border-theme-border focus:ring-pink-500 focus:border-pink-500"><option value="any">Any</option><option value="3D render">3D Render</option><option value="photorealistic">Photorealistic</option><option value="cartoon">Cartoon</option><option value="pixel art">Pixel Art</option><option value="epic fantasy">Epic Fantasy</option><option value="sci-fi">Sci-Fi</option><option value="watercolor">Watercolor</option><option value="abstract">Abstract</option></select></div>
                <div><label htmlFor="aiBackground" className="block text-sm font-medium text-gray-300 mb-1">Background Type:</label><select id="aiBackground" value={aiSuggestionBackground} onChange={e => setAiSuggestionBackground(e.target.value)} className="w-full p-2.5 text-base rounded-md bg-theme-dark border-theme-border focus:ring-pink-500 focus:border-pink-500"><option value="any">Any</option><option value="transparent background">Transparent</option><option value="simple color background">Simple Color</option><option value="detailed environment">Detailed Environment</option><option value="nebula">Nebula</option><option value="underwater scene">Underwater Scene</option></select></div>
            </div>
             <div className="flex items-center justify-between mt-4 pt-4 border-t border-theme-border/60">
                <label htmlFor="superAiAgentToggle" className="text-sm font-medium text-gray-200">Super AI Agent (Auto-apply generated images):</label>
                <input type="checkbox" id="superAiAgentToggle" checked={superAiAgentEnabled} onChange={(e) => setSuperAiAgentEnabled(e.target.checked)} className="form-checkbox h-5 w-5 text-pink-600"/>
            </div>
        </div>

      <h3 className="text-xl font-semibold text-theme-accent mt-6 mb-4">Generate & Manage Asset Images</h3>
      <div className="p-4 bg-black/30 rounded-lg"><h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">NFT Images</h4>{Object.values(runtimeNftDefinitions).map(nft => renderAssetImageEditor(`nft_${nft.id}`, `NFT: ${nft.name}`, 'nft', nft.id, pendingNftImageChanges[nft.id] || nftImageInputs[nft.id] || nft.image ))}</div>
      <div className="p-4 bg-black/30 rounded-lg"><h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">Character Images</h4>{Object.values(runtimeGameCharacters).map(char => renderAssetImageEditor(`char_${char.id}`, `Character: ${char.name} (${char.type})`, 'character', char.id, (characterAttributeInputs[char.id]?.imageBase64 || characterAttributeInputs[char.id]?.imageURL || char.image) ))}</div>
      <div className="p-4 bg-black/30 rounded-lg"><h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">Core Game Visuals</h4>
        {renderAssetImageEditor('adminConfig_gameBackgroundImageUrl', 'Game Background', 'adminConfigAsset', 'gameBackgroundImageUrl', localAdminConfig.gameBackgroundImageUrl)}
        {renderAssetImageEditor('adminConfig_defaultEnemyImageUrl', 'Default Enemy Fallback', 'adminConfigAsset', 'defaultEnemyImageUrl', localAdminConfig.defaultEnemyImageUrl)}
        {renderAssetImageEditor('adminConfig_seaTokenImageUrl', 'Sea Token', 'adminConfigAsset', 'seaTokenImageUrl', localAdminConfig.seaTokenImageUrl)}
        {renderAssetImageEditor('adminConfig_redArrowImageUrl', 'Red Arrow Projectile', 'adminConfigAsset', 'redArrowImageUrl', localAdminConfig.redArrowImageUrl || RED_ARROW_PROJECTILE_IMAGE_URL)}
      </div>
      <div className="p-4 bg-black/30 rounded-lg">
        <h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">Fire Effect Visuals 🔥</h4>
        {renderAssetImageEditor('adminConfig_flameParticleImageUrl', 'Flame Particle Effect (for Flame Cone)', 'adminConfigAsset', 'flameParticleImageUrl', localAdminConfig.flameParticleImageUrl)}
        {renderAssetImageEditor('adminConfig_enemyBurningEffectImageUrl', 'Enemy Burning Effect (Overlay/Sprite)', 'adminConfigAsset', 'enemyBurningEffectImageUrl', localAdminConfig.enemyBurningEffectImageUrl)}
        {renderAssetImageEditor('adminConfig_fireballProjectileImageUrl', 'Fireball Projectile Image', 'adminConfigAsset', 'fireballProjectileImageUrl', localAdminConfig.fireballProjectileImageUrl)}
      </div>
      <div className="p-4 bg-black/30 rounded-lg"><h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">Decorative Fish Visuals</h4>
        {renderAssetImageEditor('adminConfig_decorativeFishGoldenImage', 'Golden Fish', 'adminConfigAsset', 'decorativeFishGoldenImage', localAdminConfig.decorativeFishGoldenImage)}
        {renderAssetImageEditor('adminConfig_decorativeFishStarImage', 'Star Fish', 'adminConfigAsset', 'decorativeFishStarImage', localAdminConfig.decorativeFishStarImage)}
        {renderAssetImageEditor('adminConfig_decorativeFishBluefinImage', 'Bluefin Fish', 'adminConfigAsset', 'decorativeFishBluefinImage', localAdminConfig.decorativeFishBluefinImage)}
      </div>
       <div className="p-4 bg-black/30 rounded-lg"><h4 className="text-lg font-semibold text-gray-200 mb-3 border-b border-theme-secondary/40 pb-2">Bubble Visuals</h4>
        {renderAssetImageEditor('adminConfig_bubbleSmallImage', 'Small Bubble', 'adminConfigAsset', 'bubbleSmallImage', localAdminConfig.bubbleSmallImage)}
        {renderAssetImageEditor('adminConfig_bubbleMediumImage', 'Medium Bubble', 'adminConfigAsset', 'bubbleMediumImage', localAdminConfig.bubbleMediumImage)}
        {renderAssetImageEditor('adminConfig_bubbleLargeImage', 'Large Bubble', 'adminConfigAsset', 'bubbleLargeImage', localAdminConfig.bubbleLargeImage)}
      </div>
    </div>
  );

  const renderSoundManagement = () => (
    <div className="space-y-6 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-xl font-semibold text-theme-accent mb-3">Manage Sound Effects</h3>
      <p className="text-sm text-gray-300 mb-5">Upload custom sound files (MP3, WAV, OGG recommended). Changes are applied with "Save All Global Admin Config Changes".</p>
      {Object.values(SoundEvent).map(eventKey => {
        const formattedName = formatSoundEventName(eventKey);
        const adminSoundKeyPattern = `sound${eventKey.charAt(0).toUpperCase() + eventKey.slice(1).replace(/_([a-z])/g, (g) => g[1].toUpperCase())}Url`;
        const adminSoundKey = adminSoundKeyPattern as SoundUrlKey;
        const currentSoundSrc = localAdminConfig[adminSoundKey] as string | undefined;
        const displaySrc = currentSoundSrc && currentSoundSrc.startsWith('data:audio') 
          ? 'Custom Sound Loaded' 
          : (currentSoundSrc && currentSoundSrc.trim() !== '' ? currentSoundSrc.substring(0, 40) + (currentSoundSrc.length > 40 ? "..." : "") : 'No Sound Set');
        
        return (
          <div key={eventKey} className="p-4 bg-theme-dark/60 rounded-lg border border-theme-border/60">
            <label htmlFor={`soundFile-${eventKey}`} className="block text-base font-medium text-gray-200 mb-1.5">
              {formattedName}: <span className="text-sm text-gray-400 ml-1.5">({displaySrc})</span>
            </label>
            <input 
              type="file" 
              id={`soundFile-${eventKey}`} 
              accept="audio/*" 
              onChange={(e) => handleSoundFileUpload(eventKey, e.target.files ? e.target.files[0] : null)} 
              className="w-full text-base text-gray-300 file:mr-3 file:py-2 file:px-4 file:rounded-md file:border-0 file:font-semibold file:bg-pink-600 file:text-white hover:file:bg-pink-700"
            />
            {currentSoundSrc && currentSoundSrc.startsWith('data:audio') && (
              <audio controls src={currentSoundSrc} className="mt-2.5 w-full h-12">Preview</audio>
            )}
          </div>);
      })}
    </div>
  );

  const renderEffectsAndVisuals = () => (
    <div className="space-y-8 max-h-[60vh] overflow-y-auto pr-3">
      <h3 className="text-2xl font-semibold text-theme-accent mb-5">Effects & Visuals Configuration</h3>
      <div className="p-5 bg-theme-dark/60 rounded-xl border border-theme-border/60 mb-8">
          <h4 className="text-xl font-medium text-gray-100 mb-3">Blood Particle Effects</h4>
          <div><label htmlFor="bloodParticleLifespanSeconds" className="block text-base font-medium text-gray-200 mb-1.5">Blood Particle Lifespan (seconds):</label><input type="number" id="bloodParticleLifespanSeconds" name="bloodParticleLifespanSeconds" value={localAdminConfig.bloodParticleLifespanSeconds} onChange={handleInputChange} step="0.1" min="0.1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/><p className="text-sm text-gray-400 mt-1.5">Default: 4 seconds.</p></div>
      </div>
      <div className="p-5 bg-theme-dark/60 rounded-xl border border-theme-border/60 mb-8">
          <h4 className="text-xl font-medium text-gray-100 mb-4">Rain Effect Settings</h4>
          <div className="flex items-center justify-between mb-4"><label htmlFor="rainEffectEnabled" className="text-base font-medium text-gray-200">Enable Rain Effect:</label><input type="checkbox" id="rainEffectEnabled" name="rainEffectEnabled" checked={localAdminConfig.rainEffectEnabled} onChange={handleInputChange} className="form-checkbox h-6 w-6 text-pink-600 bg-gray-700 border-gray-600 rounded focus:ring-pink-500"/></div>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
            <div><label htmlFor="rainDropSpeedMin" className="block text-base font-medium text-gray-200 mb-1.5">Raindrop Min Speed:</label><input type="number" id="rainDropSpeedMin" name="rainDropSpeedMin" value={localAdminConfig.rainDropSpeedMin} onChange={handleInputChange} step="0.1" min="0.1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
            <div><label htmlFor="rainDropSpeedMax" className="block text-base font-medium text-gray-200 mb-1.5">Raindrop Max Speed:</label><input type="number" id="rainDropSpeedMax" name="rainDropSpeedMax" value={localAdminConfig.rainDropSpeedMax} onChange={handleInputChange} step="0.1" min="0.1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
            <div><label htmlFor="rainDurationSeconds" className="block text-base font-medium text-gray-200 mb-1.5">Rain Duration (seconds):</label><input type="number" id="rainDurationSeconds" name="rainDurationSeconds" value={localAdminConfig.rainDurationSeconds} onChange={handleInputChange} step="1" min="1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
            <div><label htmlFor="rainIntervalSeconds" className="block text-base font-medium text-gray-200 mb-1.5">Rain Interval (seconds):</label><input type="number" id="rainIntervalSeconds" name="rainIntervalSeconds" value={localAdminConfig.rainIntervalSeconds} onChange={handleInputChange} step="1" min="1" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
            <div className="md:col-span-2"><label htmlFor="rainIntensity" className="block text-base font-medium text-gray-200 mb-1.5">Rain Intensity (number of drops):</label><input type="number" id="rainIntensity" name="rainIntensity" value={localAdminConfig.rainIntensity} onChange={handleInputChange} step="10" min="10" className="w-full p-3 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/></div>
          </div>
          <p className="text-sm text-gray-400 mt-4">Rain cycles on and off based on duration and interval.</p>
      </div>
    </div>
  );

  const renderAdminAiChat = () => (
    <div className="flex flex-col h-[70vh] max-h-[75vh]">
        <div className="mb-4 flex items-center gap-4 p-3 bg-theme-dark/60 rounded-lg border border-theme-border/50">
            <label htmlFor="aiLanguageSelect" className="text-sm font-medium text-gray-200">Response Language:</label>
            <select
                id="aiLanguageSelect"
                value={selectedAiLanguage}
                onChange={(e) => setSelectedAiLanguage(e.target.value)}
                className="p-2.5 text-sm rounded-md bg-theme-dark border-theme-border text-white focus:ring-pink-500 focus:border-pink-500 flex-grow"
                aria-label="Select AI response language"
            >
                {languageOptions.map(lang => <option key={lang.code} value={lang.code}>{lang.name}</option>)}
            </select>
        </div>
        <div
            ref={aiChatLogRef}
            className="flex-grow overflow-y-auto p-4 rounded-lg border border-theme-border/30 mb-4 text-sm space-y-3 bg-black/20 shadow-inner"
            aria-live="polite"
            style={{minHeight: '200px'}}
        >
            {aiChatMessages.map((msg) => (
              <div key={msg.id} className={`chat-message ${msg.sender === 'user' ? 'text-right' : 'text-left'}`}>
                <span className={`relative inline-block p-3 rounded-xl max-w-[85%] shadow-md ${
                    msg.sender === 'user' ? 'bg-pink-600 text-white' :
                    msg.sender === 'ai' ? 'bg-blue-600 text-white' :
                    'bg-red-600 text-white' // Error
                }`}>
                  <span className="block text-xs font-semibold text-gray-300/90 mb-1">
                    {msg.sender === 'user' ? `You (${msg.lang || 'Unknown'})` : msg.sender === 'ai' ? 'Admin AI' : 'Error'}
                  </span>
                  {msg.text.split('\n').map((line, idx) => <p key={idx} className="m-0 leading-relaxed">{line}</p>)}
                </span>
              </div>
            ))}
            {aiChatMessages.length === 0 && <p className="text-gray-400 text-center italic p-4">Admin AI is ready. Ask about game configuration, best practices, or technical aspects.</p>}
             {isAiResponding && (
                 <div className="text-left">
                    <span className="relative inline-block p-3 rounded-xl max-w-[85%] shadow-md bg-blue-500 text-white">
                        <span className="block text-xs font-semibold text-gray-200/90 mb-1">Admin AI typing...</span>
                        <div className="flex items-center space-x-1.5">
                            <div className="w-2.5 h-2.5 bg-pink-300 rounded-full animate-pulse" style={{animationDelay: '0s'}}></div>
                            <div className="w-2.5 h-2.5 bg-pink-300 rounded-full animate-pulse" style={{animationDelay: '0.2s'}}></div>
                            <div className="w-2.5 h-2.5 bg-pink-300 rounded-full animate-pulse" style={{animationDelay: '0.4s'}}></div>
                        </div>
                    </span>
                </div>
            )}
        </div>
        <div className="flex gap-3 items-center mt-auto">
            <input
                type="text"
                value={currentAiQuery}
                onChange={(e) => setCurrentAiQuery(e.target.value)}
                onKeyPress={(e) => e.key === 'Enter' && handleSendAiQuery()}
                placeholder="Ask the Admin AI..."
                className="flex-grow p-3 text-base rounded-lg bg-theme-dark/70 border-2 border-theme-border/60 text-white focus:ring-2 focus:ring-pink-500 focus:border-transparent transition-all placeholder-gray-400"
                aria-label="Admin AI chat message input"
                disabled={isAiResponding}
            />
            <button
                onClick={handleSendAiQuery}
                className="py-3 px-6 bg-pink-600 hover:bg-pink-700 text-white font-semibold rounded-lg shadow-md transition-all duration-200 transform hover:scale-105 disabled:opacity-60 disabled:hover:scale-100"
                disabled={isAiResponding || currentAiQuery.trim() === ''}
            >
                {isAiResponding ? 'Sending...' : 'Send'}
            </button>
        </div>
    </div>
  );

  const renderKnowledgeBaseManagement = () => (
    <div className="space-y-6 max-h-[60vh] overflow-y-auto pr-3">
        <h3 className="text-xl font-semibold text-theme-accent mb-4">Manage AI Knowledge Base</h3>
        <p className="text-sm text-gray-300 mb-4">Provide predefined topics and answers to enhance the AI's responses in both Player Profile Chat and Admin AI Chat. This helps the AI provide consistent and accurate information.</p>
        
        <div className="p-4 bg-theme-dark/60 rounded-lg border border-theme-border/60">
            <h4 className="text-lg font-medium text-gray-100 mb-3">Add New Reply</h4>
            <div className="mb-3">
                <label htmlFor="newReplyTopic" className="block text-sm font-medium text-gray-300 mb-1">Topic/Question:</label>
                <input type="text" id="newReplyTopic" value={newReplyTopic} onChange={(e) => setNewReplyTopic(e.target.value)} placeholder="e.g., How to get Sea Tokens?" className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
            </div>
            <div className="mb-3">
                <label htmlFor="newReplyAnswer" className="block text-sm font-medium text-gray-300 mb-1">Answer/Information:</label>
                <textarea id="newReplyAnswer" value={newReplyAnswer} onChange={(e) => setNewReplyAnswer(e.target.value)} placeholder="e.g., You can get Sea Tokens by defeating enemies..." rows={3} className="w-full p-2.5 rounded-md bg-theme-dark border border-theme-border text-white text-base focus:ring-pink-500 focus:border-pink-500"/>
            </div>
            <button onClick={handleAddReply} className="py-2 px-4 bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold rounded-md transition-colors">Add Reply</button>
        </div>

        <div className="mt-6">
            <h4 className="text-lg font-medium text-gray-100 mb-3">Existing Replies:</h4>
            {(localAdminConfig.savedReplies && localAdminConfig.savedReplies.length > 0) ? (
                <ul className="space-y-3">
                    {localAdminConfig.savedReplies.map(reply => (
                        <li key={reply.id} className="p-3 bg-theme-dark/40 rounded-md border border-theme-border/40">
                            <p className="font-semibold text-gray-200 text-sm">Topic: <span className="font-normal text-gray-300">{reply.topic}</span></p>
                            <p className="font-semibold text-gray-200 text-sm mt-1">Answer: <span className="font-normal text-gray-300">{reply.answer}</span></p>
                            <button onClick={() => handleDeleteReply(reply.id)} className="mt-2 py-1 px-3 bg-red-600 hover:bg-red-700 text-white text-xs font-semibold rounded-md transition-colors">Delete</button>
                        </li>
                    ))}
                </ul>
            ) : (
                <p className="text-gray-400">No saved replies yet.</p>
            )}
        </div>
    </div>
  );


  const tabs: { id: AdminTab, label: string, content: () => React.ReactNode, icon?: string }[] = [
    { id: 'aiChat', label: 'Admin AI Chat', content: renderAdminAiChat, icon: '💬' },
    { id: 'knowledgeBase', label: 'Knowledge Base', content: renderKnowledgeBaseManagement, icon: '📚' },
    { id: 'aiGenerator', label: 'AI Img Gen', content: renderAiAssetGenerator, icon: '🤖' },
    { id: 'dogeEscapeAssets', label: '🐾 Doge Escape Assets', content: renderDogeEscapeAssets, icon: '🐾' },
    { id: 'nfts', label: 'NFTs (Legacy)', content: renderNftManagement, icon: '🖼️' },
    { id: 'characters', label: 'Characters (Legacy)', content: renderCharacterManagement, icon: '👾' },
    { id: 'assets', label: 'Assets (Legacy)', content: renderGameAssets, icon: '🎨'},
    { id: 'gameplay', label: 'Gameplay', content: renderGameplayMechanics, icon: '⚙️' },
    { id: 'sounds', label: 'Sounds', content: renderSoundManagement, icon: '🔊' },
    { id: 'effectsVisuals', label: 'Visual Effects', content: renderEffectsAndVisuals, icon: '✨' },
    { id: 'staking', label: 'Staking Rates', content: renderStakingRates, icon: '💰' },
  ];

  return (
    <Modal 
        isOpen={isOpen} 
        onClose={onClose} 
        title="🛠️ Doge Whale - Admin Super Panel" 
        size={isMaximized ? "xl" : "xl"} // Always use XL unless maximized which handles its own sizing
        isMaximizable={isMaximizable}
        isMaximized={isMaximized}
        onToggleMaximize={onToggleMaximize}
    >
      <div className="flex flex-col md:flex-row gap-4 md:gap-6">
        <div className={`md:w-1/4 space-y-2 ${isMaximized ? 'md:w-1/5' : ''}`}>
          {tabs.map(tab => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`w-full text-left py-2.5 px-4 text-sm font-medium rounded-md transition-colors duration-200 flex items-center gap-2
                          ${activeTab === tab.id ? 'bg-pink-700 text-white shadow-lg' : 'bg-pink-500 hover:bg-pink-600 text-white'}`}
              aria-pressed={activeTab === tab.id}
            >
              {tab.icon && <span className="text-lg">{tab.icon}</span>}
              {tab.label}
            </button>
          ))}
        </div>
        <div className={`md:w-3/4 ${isMaximized ? 'md:w-4/5' : ''} bg-theme-primary/20 p-4 rounded-lg shadow-inner`}>
          {tabs.find(tab => tab.id === activeTab)?.content()}
        </div>
      </div>
      <div className="mt-6 pt-4 border-t border-theme-border flex flex-col sm:flex-row justify-between items-center gap-3">
        <button
          onClick={handleSaveAllAdminChanges}
          className="w-full sm:w-auto order-1 sm:order-1 py-3 px-6 bg-pink-600 hover:bg-pink-700 text-white font-bold rounded-lg transition-colors duration-200 shadow-md transform hover:scale-102"
        >
          Save All Global Admin Config Changes
        </button>
        <button
          onClick={onLogout}
          className="w-full sm:w-auto order-2 sm:order-2 py-3 px-6 bg-red-600 hover:bg-red-700 text-white font-bold rounded-lg transition-colors duration-200 shadow-md transform hover:scale-102"
        >
          Logout Admin
        </button>
      </div>
    </Modal>
  );
};
