import { useState, useEffect, useCallback } from "react";

const STORAGE_KEY = "ai-character-profiles";

const DEFAULT_MODELS = [
  "llama3.3:70b", "qwen2.5:72b", "mistral-large", "llama3.1:8b",
  "qwen2.5:14b", "gemma3:27b", "deepseek-r1:14b", "phi4:14b"
];

const TTS_MODELS = ["Kokoro", "Chatterbox", "F5-TTS", "Qwen3-TTS", "Piper"];
const STT_MODELS = ["Whisper Large-v3", "Whisper Medium", "Whisper Small", "Whisper Turbo"];
const IMAGE_MODELS = ["SDXL", "Flux.1-dev", "Flux.1-schnell", "SD 1.5", "Pony Diffusion"];

const PERSONALITY_TRAITS = [
  "Warm", "Witty", "Calm", "Energetic", "Sarcastic", "Nurturing",
  "Curious", "Playful", "Formal", "Casual", "Empathetic", "Direct",
  "Creative", "Analytical", "Protective", "Mischievous"
];

const SPEAKING_STYLES = [
  "Conversational", "Poetic", "Concise", "Verbose", "Academic",
  "Informal", "Dramatic", "Deadpan", "Enthusiastic", "Measured"
];

const EMPTY_CHARACTER = {
  id: null,
  name: "",
  tagline: "",
  avatar: "",
  accentColor: "#7c6fff",
  personality: {
    traits: [],
    speakingStyle: "",
    coreValues: "",
    quirks: "",
    backstory: "",
    motivation: "",
  },
  prompts: {
    systemPrompt: "",
    wakeWordResponse: "",
    fallbackResponse: "",
    errorResponse: "",
    customPrompts: [],
  },
  models: {
    llm: "",
    tts: "",
    stt: "",
    imageGen: "",
    voiceCloneRef: "",
    ttsSpeed: 1.0,
    temperature: 0.7,
  },
  liveRepresentation: {
    live2dModel: "",
    idleExpression: "",
    speakingExpression: "",
    thinkingExpression: "",
    happyExpression: "",
    vtsTriggers: "",
  },
  userNotes: "",
  createdAt: null,
  updatedAt: null,
};

const TABS = ["Identity", "Personality", "Prompts", "Models", "Live2D", "Notes"];

const TAB_ICONS = {
  Identity: "◈",
  Personality: "◉",
  Prompts: "◎",
  Models: "⬡",
  Live2D: "◇",
  Notes: "▣",
};

function generateId() {
  return Date.now().toString(36) + Math.random().toString(36).slice(2);
}

function ColorPicker({ value, onChange }) {
  const presets = [
    "#7c6fff","#ff6b9d","#00d4aa","#ff9f43","#48dbfb",
    "#ff6348","#a29bfe","#fd79a8","#55efc4","#fdcb6e"
  ];
  return (
    <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
      {presets.map(c => (
        <button key={c} onClick={() => onChange(c)} style={{
          width: 28, height: 28, borderRadius: "50%", background: c, border: value === c ? "3px solid #fff" : "3px solid transparent",
          cursor: "pointer", outline: "none", boxShadow: value === c ? `0 0 0 2px ${c}` : "none", transition: "all 0.2s"
        }} />
      ))}
      <input type="color" value={value} onChange={e => onChange(e.target.value)}
        style={{ width: 28, height: 28, borderRadius: "50%", border: "none", cursor: "pointer", background: "none", padding: 0 }} />
    </div>
  );
}

function TagSelector({ options, selected, onChange, max = 6 }) {
  return (
    <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
      {options.map(opt => {
        const active = selected.includes(opt);
        return (
          <button key={opt} onClick={() => {
            if (active) onChange(selected.filter(s => s !== opt));
            else if (selected.length < max) onChange([...selected, opt]);
          }} style={{
            padding: "5px 14px", borderRadius: 20, fontSize: 13, fontFamily: "inherit",
            background: active ? "var(--accent)" : "rgba(255,255,255,0.06)",
            color: active ? "#fff" : "rgba(255,255,255,0.55)",
            border: active ? "1px solid var(--accent)" : "1px solid rgba(255,255,255,0.1)",
            cursor: "pointer", transition: "all 0.18s", fontWeight: active ? 600 : 400,
          }}>
            {opt}
          </button>
        );
      })}
    </div>
  );
}

function Field({ label, hint, children }) {
  return (
    <div style={{ marginBottom: 22 }}>
      <label style={{ display: "block", fontSize: 12, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", color: "rgba(255,255,255,0.45)", marginBottom: 6 }}>
        {label}
      </label>
      {hint && <p style={{ fontSize: 12, color: "rgba(255,255,255,0.3)", marginBottom: 8, marginTop: -2 }}>{hint}</p>}
      {children}
    </div>
  );
}

function Input({ value, onChange, placeholder, type = "text" }) {
  return (
    <input type={type} value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder}
      style={{
        width: "100%", background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)",
        borderRadius: 8, padding: "10px 14px", color: "#fff", fontSize: 14, fontFamily: "inherit",
        outline: "none", boxSizing: "border-box", transition: "border-color 0.2s",
      }}
      onFocus={e => e.target.style.borderColor = "var(--accent)"}
      onBlur={e => e.target.style.borderColor = "rgba(255,255,255,0.1)"}
    />
  );
}

function Textarea({ value, onChange, placeholder, rows = 4 }) {
  return (
    <textarea value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder} rows={rows}
      style={{
        width: "100%", background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)",
        borderRadius: 8, padding: "10px 14px", color: "#fff", fontSize: 14, fontFamily: "inherit",
        outline: "none", boxSizing: "border-box", resize: "vertical", lineHeight: 1.6,
        transition: "border-color 0.2s",
      }}
      onFocus={e => e.target.style.borderColor = "var(--accent)"}
      onBlur={e => e.target.style.borderColor = "rgba(255,255,255,0.1)"}
    />
  );
}

function Select({ value, onChange, options, placeholder }) {
  return (
    <select value={value} onChange={e => onChange(e.target.value)}
      style={{
        width: "100%", background: "rgba(20,20,35,0.95)", border: "1px solid rgba(255,255,255,0.1)",
        borderRadius: 8, padding: "10px 14px", color: value ? "#fff" : "rgba(255,255,255,0.35)",
        fontSize: 14, fontFamily: "inherit", outline: "none", cursor: "pointer",
        appearance: "none", backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='rgba(255,255,255,0.3)' stroke-width='2' fill='none'/%3E%3C/svg%3E")`,
        backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center",
      }}>
      <option value="">{placeholder || "Select..."}</option>
      {options.map(o => <option key={o} value={o}>{o}</option>)}
    </select>
  );
}

function Slider({ value, onChange, min, max, step, label }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
      <input type="range" min={min} max={max} step={step} value={value}
        onChange={e => onChange(parseFloat(e.target.value))}
        style={{ flex: 1, accentColor: "var(--accent)", cursor: "pointer" }} />
      <span style={{ fontSize: 14, color: "rgba(255,255,255,0.7)", minWidth: 38, textAlign: "right", fontVariantNumeric: "tabular-nums" }}>
        {value.toFixed(1)}
      </span>
    </div>
  );
}

function CustomPromptsEditor({ prompts, onChange }) {
  const add = () => onChange([...prompts, { trigger: "", response: "" }]);
  const remove = i => onChange(prompts.filter((_, idx) => idx !== i));
  const update = (i, field, val) => {
    const next = [...prompts];
    next[i] = { ...next[i], [field]: val };
    onChange(next);
  };
  return (
    <div>
      {prompts.map((p, i) => (
        <div key={i} style={{ background: "rgba(255,255,255,0.04)", borderRadius: 10, padding: 14, marginBottom: 10, position: "relative" }}>
          <button onClick={() => remove(i)} style={{
            position: "absolute", top: 10, right: 10, background: "rgba(255,80,80,0.15)",
            border: "none", color: "#ff6b6b", borderRadius: 6, cursor: "pointer", padding: "2px 8px", fontSize: 12
          }}>✕</button>
          <div style={{ marginBottom: 8 }}>
            <Input value={p.trigger} onChange={v => update(i, "trigger", v)} placeholder="Trigger keyword or context..." />
          </div>
          <Textarea value={p.response} onChange={v => update(i, "response", v)} placeholder="Custom response or behaviour..." rows={2} />
        </div>
      ))}
      <button onClick={add} style={{
        width: "100%", padding: "10px", background: "rgba(255,255,255,0.04)",
        border: "1px dashed rgba(255,255,255,0.15)", borderRadius: 8, color: "rgba(255,255,255,0.45)",
        cursor: "pointer", fontSize: 13, fontFamily: "inherit", transition: "all 0.2s"
      }}
        onMouseEnter={e => e.target.style.borderColor = "var(--accent)"}
        onMouseLeave={e => e.target.style.borderColor = "rgba(255,255,255,0.15)"}
      >+ Add Custom Prompt</button>
    </div>
  );
}

function CharacterCard({ character, active, onSelect, onDelete }) {
  const initials = character.name ? character.name.slice(0, 2).toUpperCase() : "??";
  return (
    <div onClick={() => onSelect(character.id)} style={{
      padding: "14px 16px", borderRadius: 12, cursor: "pointer", marginBottom: 8,
      background: active ? `linear-gradient(135deg, ${character.accentColor}22, ${character.accentColor}11)` : "rgba(255,255,255,0.04)",
      border: active ? `1px solid ${character.accentColor}66` : "1px solid rgba(255,255,255,0.07)",
      transition: "all 0.2s", position: "relative",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
        <div style={{
          width: 40, height: 40, borderRadius: "50%", background: `linear-gradient(135deg, ${character.accentColor}, ${character.accentColor}88)`,
          display: "flex", alignItems: "center", justifyContent: "center", fontSize: 14, fontWeight: 800,
          color: "#fff", flexShrink: 0, boxShadow: `0 4px 12px ${character.accentColor}44`
        }}>{initials}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 700, fontSize: 15, color: "#fff", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {character.name || "Unnamed"}
          </div>
          {character.tagline && (
            <div style={{ fontSize: 12, color: "rgba(255,255,255,0.4)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
              {character.tagline}
            </div>
          )}
        </div>
        <button onClick={e => { e.stopPropagation(); onDelete(character.id); }} style={{
          background: "none", border: "none", color: "rgba(255,255,255,0.2)", cursor: "pointer",
          fontSize: 16, padding: "2px 6px", borderRadius: 4, transition: "color 0.15s", flexShrink: 0
        }}
          onMouseEnter={e => e.target.style.color = "#ff6b6b"}
          onMouseLeave={e => e.target.style.color = "rgba(255,255,255,0.2)"}
        >×</button>
      </div>
      {character.personality.traits.length > 0 && (
        <div style={{ display: "flex", gap: 4, flexWrap: "wrap", marginTop: 10 }}>
          {character.personality.traits.slice(0, 3).map(t => (
            <span key={t} style={{
              fontSize: 10, padding: "2px 8px", borderRadius: 10, fontWeight: 600, letterSpacing: "0.04em",
              background: `${character.accentColor}22`, color: character.accentColor, border: `1px solid ${character.accentColor}44`
            }}>{t}</span>
          ))}
          {character.personality.traits.length > 3 && (
            <span style={{ fontSize: 10, color: "rgba(255,255,255,0.3)", padding: "2px 4px" }}>+{character.personality.traits.length - 3}</span>
          )}
        </div>
      )}
    </div>
  );
}

function ExportModal({ character, onClose }) {
  const json = JSON.stringify(character, null, 2);
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard.writeText(json);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  return (
    <div style={{
      position: "fixed", inset: 0, background: "rgba(0,0,0,0.7)", zIndex: 100,
      display: "flex", alignItems: "center", justifyContent: "center", padding: 24
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        background: "#13131f", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 16,
        padding: 28, width: "100%", maxWidth: 640, maxHeight: "80vh", display: "flex", flexDirection: "column"
      }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
          <h3 style={{ margin: 0, fontSize: 18, color: "#fff" }}>Export Character</h3>
          <button onClick={onClose} style={{ background: "none", border: "none", color: "rgba(255,255,255,0.4)", fontSize: 22, cursor: "pointer" }}>×</button>
        </div>
        <pre style={{
          flex: 1, overflow: "auto", background: "rgba(0,0,0,0.3)", borderRadius: 10,
          padding: 16, fontSize: 12, color: "rgba(255,255,255,0.7)", lineHeight: 1.6, margin: 0
        }}>{json}</pre>
        <button onClick={copy} style={{
          marginTop: 16, padding: "12px", background: "var(--accent)", border: "none",
          borderRadius: 10, color: "#fff", fontWeight: 700, fontSize: 14, cursor: "pointer",
          fontFamily: "inherit", transition: "opacity 0.2s"
        }}>{copied ? "✓ Copied!" : "Copy to Clipboard"}</button>
      </div>
    </div>
  );
}

export default function CharacterManager() {
  const [characters, setCharacters] = useState([]);
  const [activeId, setActiveId] = useState(null);
  const [activeTab, setActiveTab] = useState("Identity");
  const [exportModal, setExportModal] = useState(false);
  const [saved, setSaved] = useState(false);

  // Load from storage
  useEffect(() => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY);
      if (stored) {
        const parsed = JSON.parse(stored);
        setCharacters(parsed);
        if (parsed.length > 0) setActiveId(parsed[0].id);
      }
    } catch (e) {}
  }, []);

  // Save to storage
  const saveToStorage = useCallback((chars) => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(chars));
    } catch (e) {}
  }, []);

  const activeCharacter = characters.find(c => c.id === activeId) || null;

  const updateCharacter = (updater) => {
    setCharacters(prev => {
      const next = prev.map(c => c.id === activeId ? { ...updater(c), updatedAt: new Date().toISOString() } : c);
      saveToStorage(next);
      return next;
    });
    setSaved(true);
    setTimeout(() => setSaved(false), 1500);
  };

  const createCharacter = () => {
    const newChar = {
      ...JSON.parse(JSON.stringify(EMPTY_CHARACTER)),
      id: generateId(),
      accentColor: ["#7c6fff","#ff6b9d","#00d4aa","#ff9f43","#48dbfb"][Math.floor(Math.random() * 5)],
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    const next = [newChar, ...characters];
    setCharacters(next);
    setActiveId(newChar.id);
    setActiveTab("Identity");
    saveToStorage(next);
  };

  const deleteCharacter = (id) => {
    const next = characters.filter(c => c.id !== id);
    setCharacters(next);
    saveToStorage(next);
    if (activeId === id) setActiveId(next.length > 0 ? next[0].id : null);
  };

  const accentColor = activeCharacter?.accentColor || "#7c6fff";

  const set = (path, value) => {
    updateCharacter(c => {
      const parts = path.split(".");
      const next = JSON.parse(JSON.stringify(c));
      let obj = next;
      for (let i = 0; i < parts.length - 1; i++) obj = obj[parts[i]];
      obj[parts[parts.length - 1]] = value;
      return next;
    });
  };

  const renderTab = () => {
    if (!activeCharacter) return null;
    const c = activeCharacter;

    switch (activeTab) {
      case "Identity":
        return (
          <div>
            <Field label="Character Name">
              <Input value={c.name} onChange={v => set("name", v)} placeholder="e.g. Aria, Nova, Echo..." />
            </Field>
            <Field label="Tagline" hint="A short phrase that captures their essence">
              <Input value={c.tagline} onChange={v => set("tagline", v)} placeholder="e.g. Your curious, warm-hearted companion" />
            </Field>
            <Field label="Accent Color" hint="Used for UI theming and visual identity">
              <ColorPicker value={c.accentColor} onChange={v => set("accentColor", v)} />
            </Field>
            <Field label="Live2D / Avatar Reference" hint="Filename or URL of the character's visual model">
              <Input value={c.avatar} onChange={v => set("avatar", v)} placeholder="e.g. aria_v2.model3.json" />
            </Field>
            <Field label="Backstory" hint="Who are they? Where do they come from? Keep it rich.">
              <Textarea value={c.personality.backstory} onChange={v => set("personality.backstory", v)}
                placeholder="Write a detailed origin story, background, and personal history for this character..." rows={5} />
            </Field>
            <Field label="Core Motivation" hint="What drives them? What do they care about most?">
              <Textarea value={c.personality.motivation} onChange={v => set("personality.motivation", v)}
                placeholder="e.g. A deep desire to help and grow alongside their human companion..." rows={3} />
            </Field>
          </div>
        );

      case "Personality":
        return (
          <div>
            <Field label="Personality Traits" hint={`Select up to 6 traits (${c.personality.traits.length}/6)`}>
              <TagSelector options={PERSONALITY_TRAITS} selected={c.personality.traits}
                onChange={v => set("personality.traits", v)} max={6} />
            </Field>
            <Field label="Speaking Style">
              <TagSelector options={SPEAKING_STYLES} selected={c.personality.speakingStyle ? [c.personality.speakingStyle] : []}
                onChange={v => set("personality.speakingStyle", v[v.length - 1] || "")} max={1} />
            </Field>
            <Field label="Core Values" hint="What principles guide their responses and behaviour?">
              <Textarea value={c.personality.coreValues} onChange={v => set("personality.coreValues", v)}
                placeholder="e.g. Honesty, kindness, intellectual curiosity, loyalty to their user..." rows={3} />
            </Field>
            <Field label="Quirks & Mannerisms" hint="Unique behavioural patterns, phrases, habits that make them feel real">
              <Textarea value={c.personality.quirks} onChange={v => set("personality.quirks", v)}
                placeholder="e.g. Tends to use nautical metaphors. Hums softly when thinking. Has strong opinions about tea..." rows={3} />
            </Field>
          </div>
        );

      case "Prompts":
        return (
          <div>
            <Field label="System Prompt" hint="The core instruction set defining who this character is to the LLM">
              <Textarea value={c.prompts.systemPrompt} onChange={v => set("prompts.systemPrompt", v)}
                placeholder="You are [name], a [description]. Your personality is [traits]. You speak in a [style] manner. You care deeply about [values]..." rows={8} />
            </Field>
            <Field label="Wake Word Response" hint="First response when activated by wake word">
              <Textarea value={c.prompts.wakeWordResponse} onChange={v => set("prompts.wakeWordResponse", v)}
                placeholder="e.g. 'Yes? I'm here.' or 'Hmm? What do you need?'" rows={2} />
            </Field>
            <Field label="Fallback Response" hint="When the character doesn't understand or can't help">
              <Textarea value={c.prompts.fallbackResponse} onChange={v => set("prompts.fallbackResponse", v)}
                placeholder="e.g. 'I'm not sure I follow — could you say that differently?'" rows={2} />
            </Field>
            <Field label="Error Response" hint="When something goes wrong technically">
              <Textarea value={c.prompts.errorResponse} onChange={v => set("prompts.errorResponse", v)}
                placeholder="e.g. 'Something went wrong on my end. Give me a moment.'" rows={2} />
            </Field>
            <Field label="Custom Prompt Rules" hint="Context-specific overrides and triggers">
              <CustomPromptsEditor prompts={c.prompts.customPrompts}
                onChange={v => set("prompts.customPrompts", v)} />
            </Field>
          </div>
        );

      case "Models":
        return (
          <div>
            <Field label="LLM (Language Model)" hint="Primary reasoning and conversation model via Ollama">
              <Select value={c.models.llm} onChange={v => set("models.llm", v)} options={DEFAULT_MODELS} placeholder="Select LLM..." />
            </Field>
            <Field label="LLM Temperature" hint="Higher = more creative, lower = more focused">
              <Slider value={c.models.temperature} onChange={v => set("models.temperature", v)} min={0} max={2} step={0.1} />
            </Field>
            <Field label="Text-to-Speech Engine">
              <Select value={c.models.tts} onChange={v => set("models.tts", v)} options={TTS_MODELS} placeholder="Select TTS..." />
            </Field>
            <Field label="TTS Speed">
              <Slider value={c.models.ttsSpeed} onChange={v => set("models.ttsSpeed", v)} min={0.5} max={2.0} step={0.1} />
            </Field>
            <Field label="Voice Clone Reference" hint="Path or filename of reference audio for voice cloning">
              <Input value={c.models.voiceCloneRef} onChange={v => set("models.voiceCloneRef", v)} placeholder="e.g. /voices/aria_reference.wav" />
            </Field>
            <Field label="Speech-to-Text Engine">
              <Select value={c.models.stt} onChange={v => set("models.stt", v)} options={STT_MODELS} placeholder="Select STT..." />
            </Field>
            <Field label="Image Generation Model" hint="Used when character generates images or self-portraits">
              <Select value={c.models.imageGen} onChange={v => set("models.imageGen", v)} options={IMAGE_MODELS} placeholder="Select image model..." />
            </Field>
          </div>
        );

      case "Live2D":
        return (
          <div>
            <Field label="Live2D Model File" hint="Path to .model3.json file, relative to VTube Studio models folder">
              <Input value={c.liveRepresentation.live2dModel} onChange={v => set("liveRepresentation.live2dModel", v)} placeholder="e.g. Aria/aria.model3.json" />
            </Field>
            <Field label="Idle Expression" hint="VTube Studio expression name when listening/waiting">
              <Input value={c.liveRepresentation.idleExpression} onChange={v => set("liveRepresentation.idleExpression", v)} placeholder="e.g. idle_blink" />
            </Field>
            <Field label="Speaking Expression" hint="Expression triggered when TTS audio is playing">
              <Input value={c.liveRepresentation.speakingExpression} onChange={v => set("liveRepresentation.speakingExpression", v)} placeholder="e.g. talking_smile" />
            </Field>
            <Field label="Thinking Expression" hint="Triggered while LLM is processing a response">
              <Input value={c.liveRepresentation.thinkingExpression} onChange={v => set("liveRepresentation.thinkingExpression", v)} placeholder="e.g. thinking_tilt" />
            </Field>
            <Field label="Happy / Positive Expression" hint="Triggered on positive sentiment responses">
              <Input value={c.liveRepresentation.happyExpression} onChange={v => set("liveRepresentation.happyExpression", v)} placeholder="e.g. happy_bright" />
            </Field>
            <Field label="VTube Studio Custom Triggers" hint="Additional WebSocket API trigger mappings (JSON)">
              <Textarea value={c.liveRepresentation.vtsTriggers} onChange={v => set("liveRepresentation.vtsTriggers", v)}
                placeholder={'{\n  "on_error": "expression_concerned",\n  "on_wake": "expression_alert"\n}'} rows={5} />
            </Field>
          </div>
        );

      case "Notes":
        return (
          <div>
            <Field label="Developer Notes" hint="Freeform notes, ideas, todos, and observations about this character">
              <Textarea value={c.userNotes} onChange={v => set("userNotes", v)}
                placeholder={"Ideas, observations, things to try...\n\n- Voice reference sounds slightly too formal, adjust Chatterbox guidance scale\n- Try adding more nautical metaphors to system prompt\n- Need to map 'confused' expression in VTS\n- Consider adding weather awareness skill"}
                rows={16} />
            </Field>
            <div style={{ background: "rgba(255,255,255,0.03)", borderRadius: 10, padding: 16, fontSize: 12, color: "rgba(255,255,255,0.35)", lineHeight: 1.7 }}>
              <div style={{ marginBottom: 4, fontWeight: 700, color: "rgba(255,255,255,0.45)", letterSpacing: "0.06em", textTransform: "uppercase", fontSize: 11 }}>Character Info</div>
              <div>ID: <span style={{ color: "rgba(255,255,255,0.5)", fontFamily: "monospace" }}>{c.id}</span></div>
              {c.createdAt && <div>Created: {new Date(c.createdAt).toLocaleString()}</div>}
              {c.updatedAt && <div>Updated: {new Date(c.updatedAt).toLocaleString()}</div>}
            </div>
          </div>
        );

      default:
        return null;
    }
  };

  return (
    <div style={{
      "--accent": accentColor,
      minHeight: "100vh",
      background: "#0d0d18",
      color: "#fff",
      fontFamily: "'DM Sans', 'Segoe UI', system-ui, sans-serif",
      display: "flex",
      flexDirection: "column",
    }}>
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap');
        * { box-sizing: border-box; }
        ::-webkit-scrollbar { width: 6px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 3px; }
        input::placeholder, textarea::placeholder { color: rgba(255,255,255,0.2); }
        select option { background: #13131f; }
      `}</style>

      {/* Header */}
      <div style={{
        padding: "18px 28px", borderBottom: "1px solid rgba(255,255,255,0.06)",
        display: "flex", alignItems: "center", justifyContent: "space-between",
        background: "rgba(0,0,0,0.2)", backdropFilter: "blur(10px)",
        position: "sticky", top: 0, zIndex: 10,
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
          <div style={{
            width: 36, height: 36, borderRadius: 10,
            background: `linear-gradient(135deg, ${accentColor}, ${accentColor}88)`,
            display: "flex", alignItems: "center", justifyContent: "center", fontSize: 18,
            boxShadow: `0 4px 16px ${accentColor}44`
          }}>◈</div>
          <div>
            <div style={{ fontWeight: 800, fontSize: 17, letterSpacing: "-0.01em" }}>Character Manager</div>
            <div style={{ fontSize: 12, color: "rgba(255,255,255,0.35)" }}>AI Personality Configuration</div>
          </div>
        </div>
        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
          {saved && <span style={{ fontSize: 12, color: accentColor, fontWeight: 600 }}>✓ Saved</span>}
          {activeCharacter && (
            <button onClick={() => setExportModal(true)} style={{
              padding: "8px 16px", background: "rgba(255,255,255,0.07)", border: "1px solid rgba(255,255,255,0.12)",
              borderRadius: 8, color: "rgba(255,255,255,0.7)", fontSize: 13, cursor: "pointer",
              fontFamily: "inherit", fontWeight: 600, transition: "all 0.2s"
            }}>Export JSON</button>
          )}
        </div>
      </div>

      <div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
        {/* Sidebar */}
        <div style={{
          width: 260, borderRight: "1px solid rgba(255,255,255,0.06)",
          display: "flex", flexDirection: "column", background: "rgba(0,0,0,0.15)",
          flexShrink: 0,
        }}>
          <div style={{ padding: "16px 16px 8px" }}>
            <button onClick={createCharacter} style={{
              width: "100%", padding: "11px", background: `linear-gradient(135deg, ${accentColor}cc, ${accentColor}88)`,
              border: "none", borderRadius: 10, color: "#fff", fontWeight: 700, fontSize: 14,
              cursor: "pointer", fontFamily: "inherit", transition: "opacity 0.2s",
              boxShadow: `0 4px 16px ${accentColor}33`
            }}>+ New Character</button>
          </div>
          <div style={{ flex: 1, overflowY: "auto", padding: "4px 16px 16px" }}>
            {characters.length === 0 ? (
              <div style={{ textAlign: "center", padding: "40px 16px", color: "rgba(255,255,255,0.2)", fontSize: 13, lineHeight: 1.6 }}>
                No characters yet.<br />Create your first one above.
              </div>
            ) : (
              characters.map(c => (
                <CharacterCard key={c.id} character={c} active={c.id === activeId}
                  onSelect={setActiveId} onDelete={deleteCharacter} />
              ))
            )}
          </div>
        </div>

        {/* Main editor */}
        {activeCharacter ? (
          <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
            {/* Character header */}
            <div style={{
              padding: "20px 28px 0", borderBottom: "1px solid rgba(255,255,255,0.06)",
              background: `linear-gradient(180deg, ${accentColor}0a 0%, transparent 100%)`,
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 16, marginBottom: 18 }}>
                <div style={{
                  width: 52, height: 52, borderRadius: 16, flexShrink: 0,
                  background: `linear-gradient(135deg, ${accentColor}, ${accentColor}66)`,
                  display: "flex", alignItems: "center", justifyContent: "center",
                  fontSize: 20, fontWeight: 800, boxShadow: `0 6px 20px ${accentColor}44`
                }}>
                  {activeCharacter.name ? activeCharacter.name.slice(0, 2).toUpperCase() : "??"}
                </div>
                <div>
                  <div style={{ fontSize: 22, fontWeight: 800, letterSpacing: "-0.02em", lineHeight: 1.2 }}>
                    {activeCharacter.name || <span style={{ color: "rgba(255,255,255,0.25)" }}>Unnamed Character</span>}
                  </div>
                  {activeCharacter.tagline && (
                    <div style={{ fontSize: 14, color: "rgba(255,255,255,0.45)", marginTop: 2 }}>{activeCharacter.tagline}</div>
                  )}
                </div>
              </div>
              {/* Tabs */}
              <div style={{ display: "flex", gap: 2 }}>
                {TABS.map(tab => (
                  <button key={tab} onClick={() => setActiveTab(tab)} style={{
                    padding: "9px 16px", background: "none", border: "none",
                    borderBottom: activeTab === tab ? `2px solid ${accentColor}` : "2px solid transparent",
                    color: activeTab === tab ? "#fff" : "rgba(255,255,255,0.4)",
                    fontSize: 13, fontWeight: activeTab === tab ? 700 : 500,
                    cursor: "pointer", fontFamily: "inherit", transition: "all 0.18s",
                    display: "flex", alignItems: "center", gap: 6,
                  }}>
                    <span style={{ fontSize: 11 }}>{TAB_ICONS[tab]}</span>{tab}
                  </button>
                ))}
              </div>
            </div>

            {/* Tab content */}
            <div style={{ flex: 1, overflowY: "auto", padding: "24px 28px" }}>
              {renderTab()}
            </div>
          </div>
        ) : (
          <div style={{
            flex: 1, display: "flex", alignItems: "center", justifyContent: "center",
            flexDirection: "column", gap: 16, color: "rgba(255,255,255,0.2)"
          }}>
            <div style={{ fontSize: 64, opacity: 0.3 }}>◈</div>
            <div style={{ fontSize: 16, fontWeight: 600 }}>No character selected</div>
            <div style={{ fontSize: 13 }}>Create a new character to get started</div>
          </div>
        )}
      </div>

      {exportModal && activeCharacter && (
        <ExportModal character={activeCharacter} onClose={() => setExportModal(false)} />
      )}
    </div>
  );
}
