/* 成绩录入：选择 → 单科 / AI / 多科 → 成功，全流程真实联动 */
const TYPES = ['月考','期中','期末','周测','自主测试'];
const GRADES = ['小学一年级','小学二年级','小学三年级','小学四年级','小学五年级','小学六年级','初一','初二','初三','高一','高二','高三'];
const SEMESTERS = ['上学期','下学期'];
const ENTRY_SUBJECTS = ['语文','数学','英语','历史','地理','政治','物理','化学','生物','体育','科学'];
const uniqueItems = items => [...new Set(items.filter(Boolean))];
const parseOptionalNumber = value => value === '' || value === null || value === undefined ? null : parseFloat(value);
const parseOptionalRank = value => value === '' || value === null || value === undefined ? null : parseInt(value, 10);
const isPositiveRank = value => value === '' || (/^\d+$/.test(value) && parseInt(value, 10) > 0);

function EntrySelect({ onPick }) {
  const opts = [
    { mode:'ai', tone:'orange', icon:Icons.cam, title:'AI 拍照识别', rec:true, btn:'warm', btnT:'开始拍照录入',
      desc:'上传纸质试卷、成绩单照片，AI 自动识别考试名称、学科、分数，几秒生成待确认表单。',
      li:['自动 OCR 提取核心字段','支持裁剪 / 提亮 / 去模糊','识别后可手动校正'] },
    { mode:'manual', tone:'blue', icon:Icons.edit, title:'单科录入', btn:'primary', btnT:'开始单科录入',
      desc:'适合日常单科周测、随堂小测，只需录入一个学科的成绩，几步完成。',
      li:['年级学期统一记录','实时自动计算得分率','支持班级 / 年级排名'] },
    { mode:'batch', tone:'green', icon:Icons.sheet, title:'多科录入', btn:'green', btnT:'开始多科录入',
      desc:'适合期中、期末、月考等多科考试，一次填写考试批次信息，下方表格逐科录入。',
      li:['考试批次信息一次填写','多科表格逐科校验','支持总分与总排名记录'] },
  ];
  return <>
    <div style={{marginBottom:4}}><h2 style={{fontSize:22}}>选择录入方式</h2>
      <p className="muted" style={{marginTop:8,fontSize:13.5}}>三种方式覆盖日常小测、大型统考与纸质试卷场景，按你的需要选择即可。</p></div>
    <div className="step-flow">
      <div className="s"><span className="n">1</span><span className="t">选择方式</span></div><span className="arrow">→</span>
      <div className="s"><span className="n off">2</span><span className="t off">填写 / 识别</span></div><span className="arrow">→</span>
      <div className="s"><span className="n off">3</span><span className="t off">确认入库</span></div>
    </div>
    <div className="entry-grid">
      {opts.map(o=>(
        <div key={o.mode} className="entry-opt" onClick={()=>onPick(o.mode)}>
          {o.rec && <Tag tone="orange" dot className="recommend">推荐 · 最省力</Tag>}
          <div className={'eico bg-'+o.tone+'-soft'}><Ico d={o.icon} size={30}/></div>
          <h3>{o.title}</h3><p className="desc">{o.desc}</p>
          <ul>{o.li.map((l,i)=><li key={i}><span className={'ck bg-'+o.tone+'-soft'}><Ico d={Icons.check} size={11} sw={3.5}/></span>{l}</li>)}</ul>
          <div className="go"><Button variant={o.btn} style={{width:'100%'}}>{o.btnT}</Button></div>
        </div>
      ))}
    </div>
  </>;
}

function ManualEntry({ onDone, onBack }) {
  const { activeChild:c } = useStore();
  const subjects = uniqueItems([...c.subjectList, ...ENTRY_SUBJECTS]);
  const [name,setName] = React.useState('');
  const [date,setDate] = React.useState('2026-06-08');
  const [grade,setGrade] = React.useState(c.grade || '');
  const [semester,setSemester] = React.useState('上学期');
  const [type,setType] = React.useState('周测');
  const [subject,setSubject] = React.useState(subjects[1]||subjects[0]);
  const [score,setScore] = React.useState('');
  const [total,setTotal] = React.useState('100');
  const [classAvg,setClassAvg] = React.useState('');
  const [classMax,setClassMax] = React.useState('');
  const [gradeAvg,setGradeAvg] = React.useState('');
  const [classRank,setClassRank] = React.useState('');
  const [gradeRank,setGradeRank] = React.useState('');
  const [note,setNote] = React.useState('');
  const sc = parseFloat(score), tt = parseFloat(total);
  const over = sc>tt;
  const rankValid = isPositiveRank(classRank) && isPositiveRank(gradeRank);
  const valid = name.trim() && date && grade && semester && subject && sc>=0 && tt>0 && sc<=tt && rankValid;
  const rate = (sc>=0 && tt>0) ? (sc/tt*100) : null;

  const exam = { id:'m'+Date.now(), name:name.trim()||'未命名考试', date, grade, semester, type,
    subjects:[{ name:subject, score:sc||0, total:tt||100, classAvg:parseOptionalNumber(classAvg), classMax:parseOptionalNumber(classMax), gradeAvg:parseOptionalNumber(gradeAvg), gradeMax:null, classRank:parseOptionalRank(classRank), gradeRank:parseOptionalRank(gradeRank), note }] };
  const ptsItems = (rate!==null) ? computePoints(exam,'manual') : [];
  const ptsTotal = ptsItems.reduce((a,b)=>a+b.delta,0);

  return <div className="form-layout">
    <Card>
      <div className="section-title"><span className="bar"></span>考试基础信息</div>
      <div className="row2">
        <div className="field"><label>考试名称 <span className="req">*</span></label><input className="input" value={name} onChange={e=>setName(e.target.value)} placeholder="如：第三次数学周测"/></div>
        <div className="field"><label>考试时间 <span className="req">*</span></label><input className="input" type="date" value={date} onChange={e=>setDate(e.target.value)}/></div>
      </div>
      <div className="row2">
        <div className="field"><label>年级 <span className="req">*</span></label><select className="select" value={grade} onChange={e=>setGrade(e.target.value)}><option value="">请选择年级</option>{GRADES.map(g=><option key={g} value={g}>{g}</option>)}</select></div>
        <div className="field"><label>学期 <span className="req">*</span></label><select className="select" value={semester} onChange={e=>setSemester(e.target.value)}>{SEMESTERS.map(s=><option key={s} value={s}>{s}</option>)}</select></div>
      </div>
      <div className="field"><label>考试类型</label>
        <div className="chip-select">{TYPES.map(t=><span key={t} className={'chip '+(type===t?'on':'')} onClick={()=>setType(t)}>{t}</span>)}</div>
      </div>
      <div className="field"><label>学科 <span className="req">*</span></label>
        <div className="chip-select">{subjects.map(s=><span key={s} className={'chip '+(subject===s?'on':'')} onClick={()=>setSubject(s)}>{s}</span>)}</div>
      </div>
      <hr className="hr"/>
      <div className="section-title"><span className="bar" style={{background:'var(--green-400)'}}></span>成绩数据</div>
      <div className="row2">
        <div className="field"><label>个人得分 <span className="req">*</span></label><input className={'input '+(over?'err-input':'')} value={score} onChange={e=>setScore(e.target.value)} inputMode="numeric" placeholder="如 94"/></div>
        <div className="field"><label>试卷总分 <span className="req">*</span></label><input className="input" value={total} onChange={e=>setTotal(e.target.value)} inputMode="numeric"/></div>
      </div>
      {over && <div style={{color:'var(--coral)',fontSize:12,fontWeight:600,marginTop:-6,marginBottom:12}}>⚠ 个人得分不能超过试卷总分</div>}
      <div className="row3">
        <div className="field"><label>班级平均分</label><input className="input" value={classAvg} onChange={e=>setClassAvg(e.target.value)} placeholder="选填"/></div>
        <div className="field"><label>班级最高分</label><input className="input" value={classMax} onChange={e=>setClassMax(e.target.value)} placeholder="选填"/></div>
        <div className="field"><label>年级平均分</label><input className="input" value={gradeAvg} onChange={e=>setGradeAvg(e.target.value)} placeholder="选填"/></div>
      </div>
      <div className="row2">
        <div className="field"><label>班级排名</label><input className={'input '+(!isPositiveRank(classRank)?'err-input':'')} value={classRank} onChange={e=>setClassRank(e.target.value)} inputMode="numeric" placeholder="选填，如 12"/></div>
        <div className="field"><label>年级排名</label><input className={'input '+(!isPositiveRank(gradeRank)?'err-input':'')} value={gradeRank} onChange={e=>setGradeRank(e.target.value)} inputMode="numeric" placeholder="选填，如 86"/></div>
      </div>
      <div className="field"><label>错题备注</label><textarea className="input" rows="3" value={note} onChange={e=>setNote(e.target.value)} placeholder="记录本次错题、薄弱知识点，便于后续复盘…"></textarea></div>
      <div className="footbar">
        <Button variant="ghost" onClick={onBack}>返回</Button>
        <Button disabled={!valid} style={{opacity:valid?1:.5,cursor:valid?'pointer':'not-allowed'}} icon={<Ico d={Icons.edit} size={18}/>}
          onClick={()=>valid && onDone(exam,'manual',ptsItems)}>保存并入库</Button>
      </div>
    </Card>
    <div>
      <Card style={{marginBottom:18}}>
        <div className="card-head"><h3>实时预览</h3><span className="sub">自动计算</span></div>
        <div className="preview-num">
          <div className="l">本次得分率</div>
          <div className="v">{rate!==null ? rate.toFixed(2) : '—'}<small style={{fontSize:24}}>%</small></div>
          <div className="sub">{rate!==null ? `${sc} / ${tt} 分` : '请输入得分与总分'}{classAvg && sc? ` · 超班级均分 ${(sc-parseFloat(classAvg)).toFixed(0)} 分`:''}</div>
        </div>
        <div style={{marginTop:16}}>
          <div className="kv"><span className="k">年级学期</span><span className="v">{grade || '—'} · {semester}</span></div>
          <div className="kv"><span className="k">学科</span><span className="v" style={{color:SUBJECT_COLOR[subject]}}>{subject}</span></div>
          <div className="kv"><span className="k">考试类型</span><span className="v">{type}</span></div>
          <div className="kv"><span className="k">个人得分</span><span className="v">{score||'—'}</span></div>
          <div className="kv"><span className="k">班级排名</span><span className="v">{classRank||'—'}</span></div>
          <div className="kv"><span className="k">年级排名</span><span className="v">{gradeRank||'—'}</span></div>
        </div>
      </Card>
      <div className="pts-hint"><Ico d={Icons.gift} size={18}/><span>本次完整录入预计 <b>+{ptsTotal||5} 积分</b>{rate>=90?'（含高分奖励）':''}</span></div>
    </div>
  </div>;
}

function BatchEntry({ onDone, onBack }) {
  const { activeChild:c, state } = useStore();
  const subjects = uniqueItems([...c.subjectList, ...ENTRY_SUBJECTS]);
  const [name,setName] = React.useState('');
  const [date,setDate] = React.useState('2026-06-08');
  const [grade,setGrade] = React.useState(c.grade || '');
  const [semester,setSemester] = React.useState('上学期');
  const [type,setType] = React.useState('期中');
  const [totalScore,setTotalScore] = React.useState('');
  const [totalMaxScore,setTotalMaxScore] = React.useState('');
  const [classTotalAvg,setClassTotalAvg] = React.useState('');
  const [classTotalMax,setClassTotalMaxScore] = React.useState('');
  const [classTotalRank,setClassTotalRank] = React.useState('');
  const [gradeTotalRank,setGradeTotalRank] = React.useState('');
  const init = subjects.map(s=>({ name:s, score:'', total: s==='语文'&&c.stage==='中学'?'120':'100', classAvg:'', classMax:'', gradeAvg:'', classRank:'', gradeRank:'' }));
  const [rows,setRows] = React.useState(init);
  const setRow = (i,k,v)=> setRows(rs=>rs.map((r,j)=>j===i?{...r,[k]:v}:r));
  const filled = rows.filter(r=>parseFloat(r.score)>=0 && parseFloat(r.total)>0);
  const totalSc = parseFloat(totalScore), totalMax = parseFloat(totalMaxScore);
  const totalOver = totalSc > totalMax;
  const totalRate = (totalSc>=0 && totalMax>0) ? totalSc/totalMax*100 : null;
  const rowRanksValid = rows.every(r=>isPositiveRank(r.classRank) && isPositiveRank(r.gradeRank));
  const totalRanksValid = isPositiveRank(classTotalRank) && isPositiveRank(gradeTotalRank);
  const valid = name.trim() && date && grade && semester && filled.length>0 && !rows.some(r=>parseFloat(r.score)>parseFloat(r.total)) && (!totalScore || (totalSc>=0 && totalMax>0 && !totalOver)) && rowRanksValid && totalRanksValid;

  // Excel导入相关
  const [importing, setImporting] = React.useState(false);
  const [importResult, setImportResult] = React.useState(null);
  const fileInputRef = React.useRef(null);

  // 下载模板
  const handleDownloadTemplate = async () => {
    try {
      const resp = await fetch('/api/import/template', {
        headers: { Authorization: `Bearer ${state.token}` }
      });
      const blob = await resp.blob();
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = '学情星成绩导入模板.xlsx';
      a.click();
      window.URL.revokeObjectURL(url);
    } catch (e) {
      console.error('下载模板失败:', e);
    }
  };

  // 选择文件
  const handleFileSelect = (e) => {
    const file = e.target.files[0];
    if (file) handleImport(file);
  };

  // 导入Excel
  const handleImport = async (file) => {
    setImporting(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      if (state.role === 'parent' && c.id !== 'me') {
        formData.append('childId', c.id);
      }

      const resp = await fetch('/api/import/excel', {
        method: 'POST',
        headers: { Authorization: `Bearer ${state.token}` },
        body: formData
      });

      const result = await resp.json();
      if (resp.ok && result.success) {
        setImportResult(result.data);
      }
    } catch (e) {
      console.error('导入失败:', e);
    } finally {
      setImporting(false);
    }
  };

  const exam = { id:'b'+Date.now(), name:name.trim()||'未命名考试', date, grade, semester, type,
    totalScore:parseOptionalNumber(totalScore), totalMaxScore:parseOptionalNumber(totalMaxScore), totalRate:totalRate,
    classTotalAvg:parseOptionalNumber(classTotalAvg), classTotalMax:parseOptionalNumber(classTotalMax), classTotalRank:parseOptionalRank(classTotalRank), gradeTotalRank:parseOptionalRank(gradeTotalRank),
    subjects: filled.map(r=>({ name:r.name, score:parseFloat(r.score), total:parseFloat(r.total),
      classAvg:parseOptionalNumber(r.classAvg), classMax:parseOptionalNumber(r.classMax), gradeAvg:parseOptionalNumber(r.gradeAvg), gradeMax:null, classRank:parseOptionalRank(r.classRank), gradeRank:parseOptionalRank(r.gradeRank), note:'' })) };

  return <Card>
    <div className="section-title"><span className="bar"></span>考试批次信息 <span className="muted" style={{fontWeight:500,marginLeft:8}}>除学科外，以下字段统一应用于本次考试</span></div>
    <div className="row2">
      <div className="field"><label>考试名称 <span className="req">*</span></label><input className="input" value={name} onChange={e=>setName(e.target.value)} placeholder="如：初三下学期期中考试"/></div>
      <div className="field"><label>考试时间 <span className="req">*</span></label><input className="input" type="date" value={date} onChange={e=>setDate(e.target.value)}/></div>
    </div>
    <div className="row2">
      <div className="field"><label>年级 <span className="req">*</span></label><select className="select" value={grade} onChange={e=>setGrade(e.target.value)}><option value="">请选择年级</option>{GRADES.map(g=><option key={g} value={g}>{g}</option>)}</select></div>
      <div className="field"><label>学期 <span className="req">*</span></label><select className="select" value={semester} onChange={e=>setSemester(e.target.value)}>{SEMESTERS.map(s=><option key={s} value={s}>{s}</option>)}</select></div>
    </div>
    <div className="field"><label>考试类型</label><div className="chip-select">{TYPES.map(t=><span key={t} className={'chip '+(type===t?'on':'')} onClick={()=>setType(t)}>{t}</span>)}</div></div>
    <div className="row3">
      <div className="field"><label>所有科目的总得分</label><input className={'input '+(totalOver?'err-input':'')} value={totalScore} onChange={e=>setTotalScore(e.target.value)} inputMode="numeric" placeholder="选填"/></div>
      <div className="field"><label>试卷总分</label><input className="input" value={totalMaxScore} onChange={e=>setTotalMaxScore(e.target.value)} inputMode="numeric" placeholder="选填"/></div>
      <div className="field"><label>总得分率</label><input className="input" value={totalRate!==null?totalRate.toFixed(1)+'%':'自动计算'} readOnly/></div>
    </div>
    {totalOver && <div style={{color:'var(--coral)',fontSize:12,fontWeight:600,marginTop:-6,marginBottom:12}}>⚠ 所有科目的总得分不能超过试卷总分</div>}
    <div className="row2">
      <div className="field"><label>班级总平均分</label><input className="input" value={classTotalAvg} onChange={e=>setClassTotalAvg(e.target.value)} placeholder="选填"/></div>
      <div className="field"><label>班级总最高分</label><input className="input" value={classTotalMax} onChange={e=>setClassTotalMaxScore(e.target.value)} placeholder="选填"/></div>
    </div>
    <div className="row2">
      <div className="field"><label>班级总排名</label><input className={'input '+(!isPositiveRank(classTotalRank)?'err-input':'')} value={classTotalRank} onChange={e=>setClassTotalRank(e.target.value)} inputMode="numeric" placeholder="选填"/></div>
      <div className="field"><label>年级总排名</label><input className={'input '+(!isPositiveRank(gradeTotalRank)?'err-input':'')} value={gradeTotalRank} onChange={e=>setGradeTotalRank(e.target.value)} inputMode="numeric" placeholder="选填"/></div>
    </div>
    <div style={{display:'flex',gap:12,alignItems:'center',background:'var(--green-50)',borderRadius:'var(--r)',padding:'14px 18px',margin:'18px 0'}}>
      <div style={{width:40,height:40,borderRadius:11,background:'#fff',display:'grid',placeItems:'center',color:'var(--green-600)',boxShadow:'var(--shadow-sm)',flex:'0 0 auto'}}><Ico d={Icons.sheet} size={21}/></div>
      <div style={{flex:1}}><div style={{fontWeight:700,fontSize:13.5}}>用 Excel 模板批量上传</div><div style={{fontSize:12,color:'var(--ink-2)'}}>下载标准模板填写后一键导入，适合多科目快速录入</div></div>
      <input ref={fileInputRef} type="file" accept=".xlsx,.xls" style={{display:'none'}} onChange={handleFileSelect}/>
      <Button variant="ghost" size="sm" icon={<Ico d={Icons.download} size={16}/>} onClick={handleDownloadTemplate}>下载模板</Button>
      <Button variant="green" size="sm" disabled={importing} onClick={()=>fileInputRef.current?.click()}>{importing?'导入中…':'导入 Excel'}</Button>
    </div>

    {importResult && (
      <div style={{background:importResult.errorCount? 'var(--orange-50)':'var(--green-50)',borderRadius:'var(--r)',padding:12,marginBottom:16}}>
        <div style={{fontWeight:700}}>
          {importResult.errorCount? '导入完成（部分失败）':'导入完成'}
        </div>
        <div style={{fontSize:13,marginTop:4}}>
          成功导入 {importResult.successCount} 场考试
          {importResult.errorCount>0 && `，${importResult.errorCount} 条数据存在问题`}
        </div>
        {importResult.errors && importResult.errors.slice(0,5).map((err,i)=>(
          <div key={i} style={{fontSize:12,color:'var(--ink-3)',marginTop:4}}>
            第{err.row}行：{err.message}
          </div>
        ))}
      </div>
    )}
    <div style={{overflowX:'auto'}}>
      <table className="tbl batch-tbl" style={{minWidth:980}}>
        <thead><tr><th style={{width:110}}>学科</th><th>个人得分 *</th><th>试卷总分 *</th><th>得分率</th><th>班级平均分</th><th>班级最高分</th><th>年级平均分</th><th>班级排名</th><th>年级排名</th></tr></thead>
        <tbody>{rows.map((r,i)=>{
          const sc=parseFloat(r.score), tt=parseFloat(r.total), over=sc>tt;
          const rate = (sc>=0&&tt>0)?(sc/tt*100):null;
          const col = rate===null?'var(--ink-4)':rate>=90?'var(--green-600)':rate>=80?'var(--blue-600)':'var(--coral)';
          return <tr key={r.name}>
            <td><span className="subj-cell"><SubjDot name={r.name}/>{r.name}</span></td>
            <td><input className={'input '+(over?'err-input':'')} value={r.score} onChange={e=>setRow(i,'score',e.target.value)} placeholder="—"/></td>
            <td><input className="input" value={r.total} onChange={e=>setRow(i,'total',e.target.value)}/></td>
            <td style={{textAlign:'center',fontFamily:"'Outfit'",fontWeight:800,color:col}}>{rate!==null?rate.toFixed(1)+'%':'—'}</td>
            <td><input className="input" value={r.classAvg} onChange={e=>setRow(i,'classAvg',e.target.value)} placeholder="选填"/></td>
            <td><input className="input" value={r.classMax} onChange={e=>setRow(i,'classMax',e.target.value)} placeholder="选填"/></td>
            <td><input className="input" value={r.gradeAvg} onChange={e=>setRow(i,'gradeAvg',e.target.value)} placeholder="选填"/></td>
            <td><input className={'input '+(!isPositiveRank(r.classRank)?'err-input':'')} value={r.classRank} onChange={e=>setRow(i,'classRank',e.target.value)} placeholder="选填"/></td>
            <td><input className={'input '+(!isPositiveRank(r.gradeRank)?'err-input':'')} value={r.gradeRank} onChange={e=>setRow(i,'gradeRank',e.target.value)} placeholder="选填"/></td>
          </tr>;
        })}</tbody>
      </table>
    </div>
    <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginTop:20}}>
      <Button variant="ghost" size="sm" onClick={onBack}>返回</Button>
      <Button disabled={!valid} style={{opacity:valid?1:.5,cursor:valid?'pointer':'not-allowed'}}
        onClick={()=>valid && onDone(exam,'batch',computePoints(exam,'batch'))}>多科保存（{filled.length} 科）</Button>
    </div>
  </Card>;
}

function AIEntry({ onDone, onBack }) {
  const { activeChild:c } = useStore();
  const [tool,setTool] = React.useState('裁剪');
  const exam = { id:'a'+Date.now(), name:'期中考试', date:'2026-05-18', grade:c.grade || '初一年级', semester:'下学期', type:'期中',
    subjects:[{ name: c.subjectList.includes('物理')?'物理':c.subjectList[0], score:72, total:100, classAvg:null, classMax:null, gradeAvg:null, gradeMax:null, note:'' }] };
  return <div className="ai-layout">
    <Card>
      <div className="card-head"><h3>试卷图片</h3><div className="spacer"></div><Tag tone="blue">已上传 1 张</Tag></div>
      <div className="upload-zone">
        <div className="paper-ph">
          <div className="crop-box" style={{left:'12%',top:'10%',right:'12%',bottom:'14%'}}>
            <span className="h" style={{left:-6,top:-6}}></span><span className="h" style={{right:-6,top:-6}}></span>
            <span className="h" style={{left:-6,bottom:-6}}></span><span className="h" style={{right:-6,bottom:-6}}></span>
          </div>
          <div className="label"><span className="pill">[ 试卷 / 成绩单照片 ]</span></div>
        </div>
        <div className="tools">{['裁剪','提亮','去模糊','重新上传'].map(t=><div key={t} className={'tool '+(tool===t?'on':'')} onClick={()=>setTool(t)}><Ico d={t==='重新上传'?Icons.cam:Icons.edit} size={18}/>{t}</div>)}</div>
      </div>
      <div className="progress-card">
        <div className="spin"></div>
        <div style={{flex:1}}><div style={{fontWeight:700,fontSize:13.5,color:'var(--green-600)'}}>AI 识别完成 ✓</div><div style={{fontSize:12,color:'var(--ink-2)',marginTop:2}}>已提取 7 个核心字段，请在右侧核对</div></div>
        <div style={{fontFamily:"'Outfit'",fontWeight:800,fontSize:20,color:'var(--green-600)'}}>100%</div>
      </div>
    </Card>
    <Card>
      <div className="card-head"><h3>识别结果 · 待确认</h3><div className="spacer"></div><Tag tone="green" dot>可手动校正</Tag></div>
      <div className="rec-field"><span className="rk">考试名称</span><span className="rv">期中考试</span><span className="conf hi">识别 99%</span></div>
      <div className="rec-field"><span className="rk">考试时间</span><span className="rv">2026-05-18</span><span className="conf hi">识别 98%</span></div>
      <div className="rec-field"><span className="rk">年级学期</span><span className="rv">{exam.grade} · {exam.semester}</span><span className="conf hi">识别 98%</span></div>
      <div className="rec-field"><span className="rk">学科</span><span className="rv" style={{color:SUBJECT_COLOR[exam.subjects[0].name]}}>{exam.subjects[0].name}</span><span className="conf hi">识别 97%</span></div>
      <div className="rec-field"><span className="rk">个人得分</span><span className="rv">72</span><span className="conf lo">建议核对</span></div>
      <div className="rec-field"><span className="rk">试卷总分</span><span className="rv">100</span><span className="conf hi">识别 99%</span></div>
      <div style={{display:'flex',gap:12,justifyContent:'flex-end',marginTop:22}}>
        <Button variant="ghost" onClick={onBack}>返回</Button>
        <Button onClick={()=>onDone(exam,'ai',computePoints(exam,'ai'))}>确认入库</Button>
      </div>
    </Card>
  </div>;
}

function EntrySuccess({ data, onView, onAgain, onHome }) {
  const total = data.items.reduce((a,b)=>a+b.delta,0);
  return <div className="success-wrap">
    <Card className="success-card">
      <div className="check-circle"><Ico d={Icons.check} size={46} sw={3} style={{color:'#fff'}}/></div>
      <h2>录入成功！🎉</h2>
      <p className="sub" style={{color:'var(--ink-2)',marginTop:10,fontSize:14}}>「{data.exam.name}」{data.exam.subjects.length} 个学科成绩已存档，学情报告与积分已同步更新。</p>
      <div className="pts-earn">
        <div style={{fontSize:12.5,color:'var(--orange-500)',fontWeight:700}}>本次获得积分</div>
        <div className="total">+{total}</div>
        <div className="pts-list">{data.items.map((it,i)=><div className="pl" key={i}><span className="muted">{it.text}</span><span className="pv">+{it.delta}</span></div>)}</div>
      </div>
      <div className="actions">
        <Button size="lg" onClick={onView}>查看成绩记录</Button>
        <div className="alt"><Button variant="ghost" onClick={onAgain}>继续录入</Button><Button variant="ghost" onClick={onHome}>返回首页</Button></div>
      </div>
    </Card>
  </div>;
}

function Entry() {
  const { state, dispatch } = useStore();
  const { go } = useNav();
  const [step,setStep] = React.useState('select');
  const [success,setSuccess] = React.useState(null);
  const savingRef = React.useRef(false);
  const handleDone = (exam,mode,items)=>{ dispatch({type:'ADD_EXAM', childId:undefined, exam, mode}); };
  const { activeChild } = useStore();
  const submit = async (exam,mode,items)=>{
    if (savingRef.current) return;
    savingRef.current = true;
    try {
      const resp = await fetch('/api/exams', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${state.token}` },
        body: JSON.stringify({
          exam_name: exam.name, exam_date: exam.date, exam_type: exam.type,
          semester: exam.semester, grade: exam.grade || '', mode,
          subjects: exam.subjects.map(s => ({
            subject: s.name, score: s.score, max_score: s.total,
            class_avg: s.classAvg, class_max: s.classMax,
            grade_avg: s.gradeAvg, grade_max: s.gradeMax,
            class_rank: s.classRank, grade_rank: s.gradeRank,
            wrong_notes: s.note || ''
          })),
          total_score: exam.totalScore || null,
          total_max_score: exam.totalMaxScore || null,
          rank_class: exam.classTotalRank || null,
          rank_grade: exam.gradeTotalRank || null,
          class_total_avg: exam.classTotalAvg || null,
          class_total_max: exam.classTotalMax || null,
          grade_total_avg: exam.gradeTotalAvg || null,
          grade_total_max: exam.gradeTotalMax || null,
          childId: state.role === 'parent' ? activeChild.id : undefined
        })
      });
      const result = await resp.json();
      if (resp.ok && result.success) {
        const savedExam = { ...exam, id: String(result.data.examId), awarded: result.data.pointsAwarded || 0 };
        dispatch({type:'ADD_EXAM', childId:activeChild.id, exam:savedExam, mode});
        setSuccess({exam:savedExam, items});
        setStep('success');
      } else {
        dispatch({type:'ADD_EXAM', childId:activeChild.id, exam, mode});
        setSuccess({exam, items});
        setStep('success');
      }
    } catch(e) {
      dispatch({type:'ADD_EXAM', childId:activeChild.id, exam, mode});
      setSuccess({exam, items});
      setStep('success');
    } finally {
      savingRef.current = false;
    }
  };

  if (step==='success' && success) return <EntrySuccess data={success} onView={()=>go('records')} onAgain={()=>{setStep('select');setSuccess(null);}} onHome={()=>go('home')}/>;
  if (step==='manual') return <ManualEntry onDone={submit} onBack={()=>setStep('select')}/>;
  if (step==='batch') return <BatchEntry onDone={submit} onBack={()=>setStep('select')}/>;
  if (step==='ai') return <AIEntry onDone={submit} onBack={()=>setStep('select')}/>;
  return <EntrySelect onPick={setStep}/>;
}
Object.assign(window, { Entry });
