const { useState, useEffect, useCallback } = React;

// ── LocalStorage helpers ──────────────────────────────────────────
const LS_STATE = 'gfy_state_v2';
const loadState = () => {
  try {
    const s = localStorage.getItem(LS_STATE);
    if (s) return { ...window.GEEKIFY_DATA, ...JSON.parse(s) };
  } catch {}
  return window.GEEKIFY_DATA;
};
const saveState = (s) => {
  try { localStorage.setItem(LS_STATE, JSON.stringify(s)); } catch {}
};

// ── Level-up overlay ──────────────────────────────────────────────
const LevelUpOverlay = ({ level, onDismiss }) => (
  <div style={{ position: 'fixed', inset: 0, zIndex: 9999, background: 'rgba(0,0,0,.97)',
    display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column' }}>
    <div style={{ textAlign: 'center', animation: 'lvlIn .55s cubic-bezier(.2,1.4,.4,1) both' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 16, justifyContent: 'center', marginBottom: 32 }}>
        <Spark size={28} color="rgba(245,158,11,.5)" />
        <span style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 10, letterSpacing: 5,
          color: 'rgba(245,158,11,.6)', textTransform: 'uppercase' }}>Level Up</span>
        <Spark size={28} color="rgba(245,158,11,.5)" />
      </div>
      <div style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 108, fontWeight: 900, lineHeight: .9,
        color: 'var(--accent)', letterSpacing: -6,
        textShadow: '0 0 80px rgba(245,158,11,.4), 0 0 160px rgba(245,158,11,.15)' }}>{level}</div>
      <div style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 20, color: '#e0e0e8', marginTop: 18, fontWeight: 700 }}>レベル達成！</div>
      <div style={{ fontSize: 13, color: '#727288', marginTop: 6, marginBottom: 44 }}>スキルポイントを 1 ポイント獲得</div>
      <div style={{ display: 'flex', gap: 6, justifyContent: 'center', marginBottom: 44 }}>
        {[...Array(5)].map((_, i) => (
          <div key={i} style={{ width: 6, height: 6, background: 'var(--accent)', borderRadius: 1, opacity: .3 + i*.14 }} />
        ))}
      </div>
      <button onClick={onDismiss} style={{ padding: '14px 56px', background: 'var(--accent)', color: '#000',
        border: 'none', borderRadius: 4, cursor: 'pointer',
        fontFamily: "'Exo 2',sans-serif", fontWeight: 900, fontSize: 13, letterSpacing: 2 }}>続ける</button>
    </div>
  </div>
);

// ── Tweaks panel ──────────────────────────────────────────────────
const TweaksPanel = ({ visible, tweaks, onChange }) => {
  if (!visible) return null;
  const lbl = { fontSize: 10, color: '#727288', marginBottom: 6,
    fontFamily: "'Exo 2',sans-serif", letterSpacing: 1.5, textTransform: 'uppercase' };
  return (
    <div style={{ position: 'fixed', bottom: 20, right: 20, width: 234, zIndex: 800,
      background: '#0d0d16', borderTop: '1px solid rgba(255,255,255,.1)',
      border: '1px solid rgba(255,255,255,.07)', borderRadius: 6, padding: 18,
      boxShadow: '0 16px 48px rgba(0,0,0,.8)' }}>
      <div style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 10, color: 'var(--accent)',
        letterSpacing: 2.5, marginBottom: 18, textTransform: 'uppercase' }}>Tweaks</div>

      <div style={{ marginBottom: 14 }}>
        <div style={lbl}>キャラクター名</div>
        <input value={tweaks.name} onChange={e => onChange('name', e.target.value)}
          style={{ width: '100%', padding: '7px 10px', background: '#07070e',
            border: '1px solid rgba(255,255,255,.07)', borderRadius: 4, color: '#eee',
            fontSize: 12, boxSizing: 'border-box', fontFamily: "'Noto Sans JP',sans-serif" }} />
      </div>
      <div style={{ marginBottom: 14 }}>
        <div style={lbl}>ストリーク: <span style={{ color: '#666' }}>{tweaks.streak}日</span></div>
        <input type="range" min={0} max={30} value={tweaks.streak}
          onChange={e => onChange('streak', +e.target.value)}
          style={{ width: '100%', accentColor: 'var(--accent)' }} />
      </div>
      <div style={{ marginBottom: 14 }}>
        <div style={lbl}>XP倍率: <span style={{ color: '#666' }}>{tweaks.xpMult}x</span></div>
        <input type="range" min={1} max={5} step={.5} value={tweaks.xpMult}
          onChange={e => onChange('xpMult', +e.target.value)}
          style={{ width: '100%', accentColor: 'var(--accent)' }} />
      </div>
      <div style={{ marginBottom: 14 }}>
        <div style={lbl}>アクセントカラー</div>
        <div style={{ display: 'flex', gap: 6 }}>
          {['#f59e0b','#ef4444','#a78bfa','#34d399','#60a5fa'].map(c => (
            <div key={c} onClick={() => onChange('accent', c)} style={{
              width: 24, height: 24, borderRadius: 3, background: c, cursor: 'pointer',
              border: tweaks.accent === c ? '2px solid #fff' : '2px solid transparent',
              boxShadow: tweaks.accent === c ? `0 0 8px ${c}` : 'none', transition: 'all .15s'
            }} />
          ))}
        </div>
      </div>
      <div style={{ paddingTop: 14, borderTop: '1px solid rgba(255,255,255,.05)' }}>
        <div style={lbl}>オンボーディングをリセット</div>
        <button onClick={() => { localStorage.removeItem('gfy_onboarding'); window.location.reload(); }}
          style={{ width: '100%', padding: '7px', background: 'rgba(239,68,68,.08)',
            border: '1px solid rgba(239,68,68,.2)', borderRadius: 4, color: '#ef4444',
            cursor: 'pointer', fontSize: 11, fontFamily: "'Exo 2',sans-serif", letterSpacing: .5 }}>
          リセットして最初から
        </button>
      </div>
    </div>
  );
};

// ── Navigation ────────────────────────────────────────────────────
const NAV = [
  { id: 'dashboard',    icon: '◈', label: 'ダッシュボード' },
  { id: 'quests',       icon: '⚔', label: 'クエスト' },
  { id: 'character',    icon: '✦', label: 'キャラクター' },
  { id: 'achievements', icon: '◉', label: '実績' },
];

// ── App ───────────────────────────────────────────────────────────
const App = () => {
  const [obDone, setObDone]   = useState(() => localStorage.getItem('gfy_onboarding') === 'done');
  const [screen, setScreen]   = useState(() => localStorage.getItem('gfy_screen') || 'dashboard');
  const [gs, setGs]           = useState(loadState);
  const [levelUp, setLevelUp] = useState(null);
  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [notifOpen, setNotifOpen]   = useState(false);
  const [tweaks, setTweaks]   = useState(window.TWEAK_DEFAULTS);

  useEffect(() => { localStorage.setItem('gfy_screen', screen); }, [screen]);
  useEffect(() => { document.documentElement.style.setProperty('--accent', tweaks.accent); }, [tweaks.accent]);
  // Persist game state
  useEffect(() => { saveState(gs); }, [gs]);

  // Notification count (overdue + due today + system alerts)
  const today = new Date().toISOString().split('T')[0];
  const notifCount = (() => {
    const overdue  = gs.projects.flatMap(p => p.tasks.filter(t => !t.done && t.due && t.due < today)).length;
    const dueToday = gs.projects.flatMap(p => p.tasks.filter(t => !t.done && t.due === today)).length;
    const pts      = gs.character.skillPoints > 0 ? 1 : 0;
    return overdue + dueToday + pts;
  })();

  // Tweaks host protocol
  useEffect(() => {
    const h = e => {
      if (e.data?.type === '__activate_edit_mode')   setTweaksOpen(true);
      if (e.data?.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', h);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', h);
  }, []);

  const handleTweak = (key, val) => {
    setTweaks(t => ({ ...t, [key]: val }));
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [key]: val } }, '*');
    if (key === 'name')   setGs(s => ({ ...s, character: { ...s.character, name: val } }));
    if (key === 'streak') setGs(s => ({ ...s, character: { ...s.character, streak: val } }));
  };

  // Onboarding complete
  const handleObComplete = ({ character, skills, project, user }) => {
    setGs(s => ({
      ...s,
      user,
      character: { ...s.character, ...character },
      skills: skills.length > 0 ? skills : s.skills,
      projects: project ? [project] : s.projects,
    }));
    localStorage.setItem('gfy_onboarding', 'done');
    setObDone(true);
  };

  // Task complete
  const handleCompleteTask = (task, projectId) => {
    setGs(s => {
      const gain = Math.round(task.xp * tweaks.xpMult);
      let { xp, level, xpToNext, skillPoints } = s.character;
      xp += gain;
      if (xp >= xpToNext) {
        xp -= xpToNext; level++; xpToNext = Math.round(xpToNext * 1.3); skillPoints++;
        setTimeout(() => setLevelUp(level), 350);
      }
      const skills = s.skills.map(sk => {
        if (sk.id !== task.skillId) return sk;
        let { xp: sx, level: sl, xpToNext: st } = sk;
        sx += Math.round(gain * .65);
        if (sx >= st) { sx -= st; sl++; st = Math.round(st * 1.2); }
        return { ...sk, xp: sx, level: sl, xpToNext: st };
      });
      const projects = s.projects.map(p => p.id !== projectId ? p :
        { ...p, tasks: p.tasks.map(t => t.id === task.id ? { ...t, done: true } : t) });
      return { ...s, character: { ...s.character, xp, level, xpToNext, skillPoints }, skills, projects };
    });
  };

  const handleToggleSubtask = (stId, taskId, projectId) => {
    setGs(s => ({ ...s, projects: s.projects.map(p => p.id !== projectId ? p : {
      ...p, tasks: p.tasks.map(t => t.id !== taskId ? t : {
        ...t, subtasks: t.subtasks.map(st => st.id === stId ? { ...st, done: !st.done } : st)
      })
    })}));
  };

  const handleAddTask    = task    => setGs(s => ({ ...s, projects: s.projects.map(p =>
    p.id !== task.projectId ? p : { ...p, tasks: [...p.tasks, task] }) }));

  const handleAddProject = proj    => setGs(s => ({ ...s, projects: [...s.projects, proj] }));
  const handleDelProject = projId  => setGs(s => ({ ...s, projects: s.projects.filter(p => p.id !== projId) }));

  const handleAddSkill   = skill   => setGs(s => ({ ...s, skills: [...s.skills, skill] }));
  const handleAllocPoint = skillId => setGs(s => {
    if (s.character.skillPoints <= 0) return s;
    return {
      ...s,
      character: { ...s.character, skillPoints: s.character.skillPoints - 1 },
      skills: s.skills.map(sk => sk.id !== skillId ? sk : { ...sk, xp: Math.min(sk.xp + 120, sk.xpToNext - 1) })
    };
  });

  if (!obDone) return <OnboardingScreen onComplete={handleObComplete} />;

  const isMobile = window.innerWidth < 700;

  return (
    <div style={{ display: 'flex', height: '100vh', background: '#06060b', color: '#f0f0f2', overflow: 'hidden' }}>

      {/* ── Sidebar (desktop) ── */}
      {!isMobile && (
        <div style={{ width: 212, background: '#08080f', borderRight: '1px solid rgba(255,255,255,.05)',
          display: 'flex', flexDirection: 'column', flexShrink: 0 }}>
          {/* Logo */}
          <div style={{ padding: '22px 22px 16px', borderBottom: '1px solid rgba(255,255,255,.05)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Spark size={14} color="var(--accent)" opacity={.8} />
              <span style={{ fontFamily: "'Exo 2',sans-serif", fontWeight: 900, fontSize: 18,
                color: 'var(--accent)', letterSpacing: 4 }}>GEEKIFY</span>
            </div>
            <div style={{ fontSize: 9, color: '#454558', letterSpacing: 3, marginTop: 3 }}>TASK RPG</div>
          </div>

          {/* Character mini */}
          <div style={{ padding: '14px 16px', borderBottom: '1px solid rgba(255,255,255,.05)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ width: 32, height: 32, borderRadius: 5, background: gs.user?.avatarColor || 'var(--accent)',
                border: '1px solid rgba(255,255,255,.1)', flexShrink: 0,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: "'Exo 2',sans-serif", fontSize: 14, fontWeight: 900, color: '#fff' }}>
                {gs.character.name[0]}
              </div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 12, fontWeight: 700,
                  color: '#c0c0c8', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {gs.character.name}
                </div>
                <div style={{ fontSize: 9, color: '#606074', marginTop: 2, letterSpacing: .5 }}>
                  Lv.{gs.character.level} · ⚡{gs.character.streak}
                  {gs.user?.googleConnected && <span style={{ marginLeft: 5, color: '#2a5e2a' }}>● 同期</span>}
                </div>
              </div>
            </div>
            <div style={{ marginTop: 10 }}>
              <XPBar xp={gs.character.xp} xpToNext={gs.character.xpToNext} height={3} />
            </div>
          </div>

          {/* Nav */}
          <nav style={{ flex: 1, padding: '12px 12px 0' }}>
            {NAV.map(item => (
              <div key={item.id} onClick={() => setScreen(item.id)} style={{
                display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px',
                borderRadius: 4, cursor: 'pointer', marginBottom: 1, transition: 'all .15s',
                background: screen === item.id ? 'rgba(245,158,11,.07)' : 'transparent',
                borderLeft: screen === item.id ? '2px solid var(--accent)' : '2px solid transparent',
              }}>
                <span style={{ fontSize: 14, color: screen === item.id ? 'var(--accent)' : '#565668', width: 17, textAlign: 'center' }}>{item.icon}</span>
                <span style={{ fontFamily: "'Exo 2',sans-serif", fontSize: 12,
                  color: screen === item.id ? '#d0d0d8' : '#6e6e82',
                  fontWeight: screen === item.id ? 700 : 400 }}>{item.label}</span>
              </div>
            ))}
            {/* Notification bell */}
            <div style={{ marginTop: 8, borderTop: '1px solid rgba(255,255,255,.04)', paddingTop: 8 }}>
              <NotifBell count={notifCount} active={notifOpen} onClick={() => setNotifOpen(o => !o)} />
            </div>
          </nav>

          {/* Bottom: sync + settings */}
          <div style={{ padding: '14px 16px', borderTop: '1px solid rgba(255,255,255,.05)' }}>
            {gs.user?.googleConnected && (
              <div style={{ fontSize: 10, color: '#2e5a2e', fontFamily: "'Exo 2',sans-serif",
                letterSpacing: .5, marginBottom: 10 }}>⟳ 同期済み · たった今</div>
            )}
            <div onClick={() => setTweaksOpen(t => !t)} style={{ fontSize: 11, color: '#565668', cursor: 'pointer',
              fontFamily: "'Exo 2',sans-serif", display: 'flex', gap: 6, alignItems: 'center', transition: 'color .15s' }}
              onMouseEnter={e => e.currentTarget.style.color = '#555'}
              onMouseLeave={e => e.currentTarget.style.color = '#565668'}>
              <span>⚙</span><span>設定 / Tweaks</span>
            </div>
          </div>
        </div>
      )}

      {/* ── Main content ── */}
      <div style={{ flex: 1, overflow: 'auto', paddingBottom: isMobile ? 58 : 0 }}>
        {screen === 'dashboard'    && <DashboardScreen    state={gs} />}
        {screen === 'quests'       && <QuestsScreen       state={gs}
          onCompleteTask={handleCompleteTask} onToggleSubtask={handleToggleSubtask}
          onAddTask={handleAddTask} onAddProject={handleAddProject} onDeleteProject={handleDelProject} />}
        {screen === 'character'    && <CharacterScreen    state={gs} onAddSkill={handleAddSkill} onAllocatePoint={handleAllocPoint} />}
        {screen === 'achievements' && <AchievementsScreen state={gs} />}
      </div>

      {/* ── Mobile bottom nav ── */}
      {isMobile && (
        <div style={{ position: 'fixed', bottom: 0, left: 0, right: 0, height: 56,
          background: '#08080f', borderTop: '1px solid rgba(255,255,255,.05)', display: 'flex', zIndex: 500 }}>
          {NAV.map(item => (
            <div key={item.id} onClick={() => setScreen(item.id)} style={{
              flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center',
              justifyContent: 'center', gap: 3, cursor: 'pointer',
              borderTop: screen === item.id ? '1.5px solid var(--accent)' : '1.5px solid transparent'
            }}>
              <span style={{ fontSize: 16, color: screen === item.id ? 'var(--accent)' : '#565668' }}>{item.icon}</span>
              <span style={{ fontSize: 9, color: screen === item.id ? 'var(--accent)' : '#565668',
                fontFamily: "'Exo 2',sans-serif", letterSpacing: .5 }}>{item.label}</span>
            </div>
          ))}
        </div>
      )}

      {levelUp && <LevelUpOverlay level={levelUp} onDismiss={() => setLevelUp(null)} />}
      {notifOpen && <NotificationsPanel state={gs} onClose={() => setNotifOpen(false)} />}
      <TweaksPanel visible={tweaksOpen} tweaks={tweaks} onChange={handleTweak} />
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
