/* App 外殼 + 登入 — app.jsx */
const { useState: useAppState, useEffect: useAppEffect, useMemo: useAppMemo } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "深藍主控台",
  "accent": "#2f6fed",
  "fontScale": 100,
  "radius": "圓潤"
}/*EDITMODE-END*/;

const ROLE_LABELS = { teacher: '老師', assistant: '小老師', student: '學生' };

/* 角色 → 可用的導覽分頁 */
const NAV = {
  teacher:   [
    { key: 'class',  label: '全班成績', icon: 'users'   },
    { key: 'input',  label: '輸入成績', icon: 'pencil'  },
    { key: 'import', label: '匯入成績', icon: 'upload'  }
  ],
  assistant: [
    { key: 'mine',     label: '我的成績', icon: 'chart'  },
    { key: 'input',    label: '輸入成績', icon: 'pencil' },
    { key: 'analysis', label: '學習分析', icon: 'spark'  }
  ],
  student:   [
    { key: 'mine',     label: '我的成績', icon: 'chart' },
    { key: 'analysis', label: '學習分析', icon: 'spark' }
  ]
};

/* ── 全域載入畫面 ── */
function LoadingScreen({ message }) {
  return (
    <div className="loading-screen">
      <div className="loading-spinner" />
      <span className="loading-msg">{message || '載入中…'}</span>
    </div>
  );
}

/* ── 登入畫面 ── */
function LoginScreen({ onLogin }) {
  const [email, setEmail]         = useAppState('');
  const [password, setPassword]   = useAppState('');
  const [loading, setLoading]     = useAppState(false);
  const [error, setError]         = useAppState(null);
  const [forgot, setForgot]       = useAppState(false);
  const [forgotEmail, setForgotEmail] = useAppState('');
  const [resetSent, setResetSent] = useAppState(false);
  const [resetLoading, setResetLoading] = useAppState(false);

  async function handleLogin(e) {
    if (e) e.preventDefault();
    if (!email || !password) return;
    setLoading(true);
    setError(null);
    try {
      await onLogin(email, password);
    } catch (err) {
      setError('帳號或密碼錯誤，請再試一次。');
      setLoading(false);
    }
  }

  async function handleReset() {
    if (!forgotEmail) return;
    setResetLoading(true);
    try {
      await API.resetPassword(forgotEmail);
      setResetSent(true);
    } catch {
      setResetSent(true); /* 不揭露帳號是否存在 */
    } finally {
      setResetLoading(false);
    }
  }

  return (
    <div className="login">
      <div className="login-bg" />
      <div className="login-card">
        <div className="brand">
          <span className="brand-mark">√</span>
          <div>
            <div className="brand-title">數學科成績查詢系統</div>
            <div className="brand-sub">七年三班・平時成績</div>
          </div>
        </div>

        <form className="login-form" onSubmit={handleLogin}>
          <div className="login-lead">請輸入帳號密碼登入</div>

          <label className="login-field">
            <span className="login-flabel"><Icon name="mail" size={14} /> 帳號（Email）</span>
            <input className="text-input" type="email" value={email} autoComplete="username"
              placeholder="your@email.com"
              onChange={e => { setEmail(e.target.value); setError(null); }} />
          </label>

          <label className="login-field">
            <span className="login-flabel"><Icon name="lock" size={14} /> 密碼</span>
            <input className="text-input" type="password" value={password} autoComplete="current-password"
              onChange={e => { setPassword(e.target.value); setError(null); }} />
          </label>

          {error && <div className="login-error"><Icon name="info" size={14} />{error}</div>}

          <Button full type="submit" disabled={loading || !email || !password}>
            {loading ? '登入中…' : '登入'}
          </Button>
        </form>

        <div className="login-foot">
          <button className="link-btn" onClick={() => { setForgot(true); setResetSent(false); setForgotEmail(email); }}>
            忘記密碼？
          </button>
          <span className="demo-hint">系統由老師設定帳號</span>
        </div>
      </div>

      {/* 忘記密碼 Modal */}
      {forgot && (
        <div className="modal-overlay" onClick={() => setForgot(false)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <div className="modal-head">
              <span className="modal-ic"><Icon name="mail" size={20} /></span>
              <h3>重設密碼</h3>
            </div>
            {resetSent ? (
              <div className="reset-sent">
                <span className="done-badge sm"><Icon name="check" size={22} /></span>
                <p>若此 Email 已註冊，重設連結將寄送至信箱，請查收。</p>
              </div>
            ) : (
              <>
                <p className="modal-text">輸入你的帳號 Email，系統將寄送密碼重設連結。</p>
                <input className="text-input" value={forgotEmail}
                  placeholder="your@email.com"
                  onChange={e => setForgotEmail(e.target.value)} />
                <Button full icon="mail" disabled={resetLoading || !forgotEmail} onClick={handleReset}>
                  {resetLoading ? '寄送中…' : '寄送重設連結'}
                </Button>
              </>
            )}
            <button className="modal-close" onClick={() => setForgot(false)}>關閉</button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ── 主 App ── */
function App() {
  const [t, setTweak]     = useTweaks(TWEAK_DEFAULTS);
  const [appReady, setAppReady] = useAppState(false);  /* 初始 session 檢查完畢 */
  const [user, setUser]   = useAppState(null);
  const [tab, setTab]     = useAppState('mine');
  const [grades, setGrades] = useAppState([]);
  const [types, setTypes]   = useAppState(window.APPDATA.assessmentTypes.slice());
  const [loadErr, setLoadErr] = useAppState(null);

  /* 套用主題 */
  useAppEffect(() => {
    const root = document.documentElement;
    root.dataset.theme  = t.theme === '淨白學院' ? 'light' : 'dark';
    root.dataset.radius = t.radius === '方正' ? 'sharp' : 'round';
    root.style.setProperty('--accent', t.accent);
    root.style.setProperty('--font-scale', t.fontScale / 100);
  }, [t.theme, t.accent, t.fontScale, t.radius]);

  /* 初次載入：檢查是否有現有 session */
  useAppEffect(() => {
    API.getSession().then(function (session) {
      if (session) {
        return loadUserData(session.user);
      }
      setAppReady(true);
    }).catch(function (err) {
      console.error('Session 檢查失敗', err);
      setAppReady(true);
    });

    /* 監聽 auth 狀態變化（登入 / 登出） */
    var sub = API.onAuthChange(function (event, session) {
      if (event === 'SIGNED_OUT') {
        setUser(null);
        setGrades([]);
        window.APPDATA.students = [];
        setAppReady(true);
      }
    });
    return function () { if (sub && sub.data) sub.data.subscription.unsubscribe(); };
  }, []);

  async function loadUserData(authUser) {
    setLoadErr(null);
    try {
      const profile = await API.getProfile(authUser.id);
      const [students, fetchedGrades] = await Promise.all([
        API.getStudents(),
        API.getGrades(profile.role, profile.student_id)
      ]);

      /* 更新全域 APPDATA.students 供 screens 使用 */
      window.APPDATA.students = students;

      setUser({
        id:        authUser.id,
        email:     authUser.email,
        role:      profile.role,
        roleLabel: profile.role_label || ROLE_LABELS[profile.role] || profile.role,
        name:      profile.name,
        studentId: profile.student_id
      });
      setGrades(fetchedGrades);
      setTab(NAV[profile.role][0].key);
    } catch (err) {
      console.error('載入資料失敗', err);
      setLoadErr('載入資料失敗：' + (err.message || '請稍後再試'));
      await API.signOut();
    } finally {
      setAppReady(true);
    }
  }

  async function login(email, password) {
    setAppReady(false);
    const data = await API.signIn(email, password);   /* 若失敗會 throw */
    await loadUserData(data.user);
  }

  async function logout() {
    await API.signOut();
    setUser(null);
    setGrades([]);
    window.APPDATA.students = [];
    setAppReady(true);
  }

  /* ── 成績操作 ── */
  async function addGrade(g) {
    const dbGrade = {
      id:         'g' + Date.now() + '_' + Math.floor(Math.random() * 9999),
      student_id: g.studentId,
      type:       g.type,
      title:      g.title,
      date:       g.date,
      score:      g.score,
      created_by: user.id
    };
    const saved = await API.addGrade(dbGrade);
    setGrades(prev => [...prev, Object.assign({}, saved, { addedThisSession: true })]);
  }

  async function deleteGrade(id) {
    await API.deleteGrade(id);
    setGrades(prev => prev.filter(g => g.id !== id));
  }

  function addType(t2) {
    setTypes(prev => prev.includes(t2) ? prev : [...prev, t2]);
  }

  async function commitImport(rows) {
    const students = window.APPDATA.students;
    const dbRows = rows.map(function (r, i) {
      const st = students.find(s => s.seat === r.seat);
      if (!st) return null;
      return {
        id:         'imp' + Date.now() + '_' + i,
        student_id: st.id,
        type:       r.type,
        title:      r.title,
        date:       r.date,
        score:      r.score,
        created_by: user.id
      };
    }).filter(Boolean);

    if (!dbRows.length) return;
    const saved = await API.addGrades(dbRows);
    setGrades(prev => [
      ...prev,
      ...saved.map(g => Object.assign({}, g, { addedThisSession: true }))
    ]);
  }

  /* ── Tweaks 面板 ── */
  const panel = (
    <TweaksPanel>
      <TweakSection label="視覺方向" />
      <TweakRadio label="主題" value={t.theme} options={['深藍主控台', '淨白學院']}
        onChange={v => setTweak('theme', v)} />
      <TweakColor label="主色" value={t.accent}
        options={['#2f6fed', '#4263eb', '#1098ad', '#1b3a8c']}
        onChange={v => setTweak('accent', v)} />
      <TweakRadio label="圓角" value={t.radius} options={['圓潤', '方正']}
        onChange={v => setTweak('radius', v)} />
      <TweakSection label="字級" />
      <TweakSlider label="整體字級" value={t.fontScale} min={90} max={115} step={5} unit="%"
        onChange={v => setTweak('fontScale', v)} />
    </TweaksPanel>
  );

  /* 初始 session 還在確認中 */
  if (!appReady) return <><LoadingScreen message="連線中…" />{panel}</>;

  /* 未登入 */
  if (!user) {
    return (
      <>
        <LoginScreen onLogin={login} />
        {loadErr && <div className="toast toast-warn" style={{ bottom: 80, left: '50%', transform: 'translateX(-50%)' }}>
          <Icon name="info" size={16} />{loadErr}
        </div>}
        {panel}
      </>
    );
  }

  const nav = NAV[user.role];
  const sid = user.studentId;

  return (
    <div className="app">
      {/* 頂部列 */}
      <header className="topbar">
        <div className="topbar-l">
          <span className="brand-mark sm">√</span>
          <span className="topbar-title">數學科成績查詢系統</span>
        </div>
        <nav className="topnav">
          {nav.map(n => (
            <button key={n.key} className={'navbtn' + (tab === n.key ? ' active' : '')} onClick={() => setTab(n.key)}>
              <Icon name={n.icon} size={16} />{n.label}
            </button>
          ))}
        </nav>
        <div className="topbar-r">
          <div className="user-chip">
            <Avatar name={user.name} size={32} />
            <div className="user-meta">
              <span className="user-name">{user.name}</span>
              <span className={'user-role role-tag-' + user.role}>{user.roleLabel}</span>
            </div>
          </div>
          <button className="icon-btn" title="登出" onClick={logout}><Icon name="logout" size={18} /></button>
        </div>
      </header>

      {/* 行動版導覽 */}
      <nav className="topnav mobile">
        {nav.map(n => (
          <button key={n.key} className={'navbtn' + (tab === n.key ? ' active' : '')} onClick={() => setTab(n.key)}>
            <Icon name={n.icon} size={16} />{n.label}
          </button>
        ))}
      </nav>

      <main className="content">
        {tab === 'mine'     && <MyGradesScreen     studentId={sid} grades={grades} />}
        {tab === 'analysis' && <AnalysisScreen     studentId={sid} grades={grades} />}
        {tab === 'input'    && <InputGradesScreen  grades={grades} addGrade={addGrade}
                                 deleteGrade={deleteGrade} types={types} addType={addType}
                                 currentUser={user} />}
        {tab === 'class'    && <ClassGradesScreen  grades={grades} types={types} />}
        {tab === 'import'   && <ImportScreen       commitImport={commitImport} />}
      </main>

      {panel}
    </div>
  );
}

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