/* 积分中心：余额 / 收支 / 任务 / 兑换，全部通过后端 API 驱动 */
function Points() {
  const { state, dispatch, activeChild:c } = useStore();
  const isParent = state.role==='parent';
  const [addOpen,setAddOpen] = React.useState(false);
  const [rname,setRname] = React.useState('');
  const [rcost,setRcost] = React.useState('');
  const [ricon,setRicon] = React.useState('🎁');
  const [addLoading,setAddLoading] = React.useState(false);
  const [localToast,setLocalToast] = React.useState(null);
  const [balance,setBalance] = React.useState(null);
  const [transactions,setTransactions] = React.useState([]);
  const [rewards,setRewards] = React.useState([]);
  const [redemptions,setRedemptions] = React.useState([]);
  const [redeemConfirmOpen, setRedeemConfirmOpen] = React.useState(false);
  const [pendingReward, setPendingReward] = React.useState(null);

  const showLocalToast = (type, msg)=>{
    setLocalToast({ type, msg });
    setTimeout(()=>setLocalToast(null), 2600);
  };

  const childIdParam = isParent && c.id !== 'me' ? `?childId=${c.id}` : '';
  const childIdBody = isParent && c.id !== 'me' ? c.id : undefined;

  const loadPointsData = React.useCallback(async ()=>{
    if (!state.token) return;
    try {
      const headers = { Authorization: `Bearer ${state.token}` };
      const [balRes, txRes, rwRes, rdRes] = await Promise.all([
        fetch('/api/points/balance' + childIdParam, { headers }),
        fetch('/api/points/transactions' + childIdParam, { headers }),
        fetch('/api/points/rewards', { headers }),
        fetch('/api/points/redemptions' + childIdParam, { headers })
      ]);
      const balData = await balRes.json();
      const txData = await txRes.json();
      const rwData = await rwRes.json();
      const rdData = await rdRes.json();
      if (balData.success) setBalance(balData.data);
      if (txData.success) setTransactions(txData.data || []);
      if (rwData.success) setRewards(rwData.data || []);
      if (rdData.success) setRedemptions(rdData.data || []);
    } catch(e) {}
  }, [state.token, c.id, isParent]);

  React.useEffect(()=>{ loadPointsData(); }, [loadPointsData]);

  const currentBalance = balance ? balance.balance : c.points;
  const totalEarned = balance ? balance.total_earned : c.pointsLog.filter(l=>l.delta>0).reduce((a,b)=>a+b.delta,0);
  const totalSpent = balance ? balance.total_spent : c.pointsLog.filter(l=>l.delta<0).reduce((a,b)=>a+Math.abs(b.delta),0);
  const streakDays = balance ? balance.streak_days : c.streak;

  const recentTx = transactions.slice(0, 7).map(t=>({ date: t.created_at ? t.created_at.slice(0,10) : '', text: t.description, delta: t.amount }));
  const barDays = recentTx.map(l=>l.date.slice(5).replace('-','/'));
  const barVals = recentTx.map(l=>Math.abs(l.delta));

  const apiRewards = rewards.length ? rewards : state.rewards;

  const handleRedeemClick = (reward)=>{
    const rewardId = reward.id;
    const pointsCost = reward.points_cost || reward.cost;
    if (currentBalance < pointsCost) {
      showLocalToast('error', '积分不足，继续加油');
      return;
    }
    setPendingReward(reward);
    setRedeemConfirmOpen(true);
  };

  const handleRedeemConfirm = async ()=>{
    const reward = pendingReward;
    const rewardId = reward.id;
    const pointsCost = reward.points_cost || reward.cost;
    try {
      const resp = await fetch('/api/points/redeem', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${state.token}` },
        body: JSON.stringify({ rewardId, childId: childIdBody })
      });
      const result = await resp.json();
      if (resp.ok && result.success) {
        showLocalToast('success', `兑换「${reward.name}」申请已提交，等待家长确认`);
        dispatch({type:'REDEEM', childId:c.id, reward:{...reward, cost: pointsCost}});
        loadPointsData();
      } else {
        showLocalToast('error', result.message || '兑换失败');
      }
    } catch(e) {
      showLocalToast('error', '网络异常，兑换失败');
    } finally {
      setRedeemConfirmOpen(false);
      setPendingReward(null);
    }
  };

  const submitReward = async ()=>{
    if (!rname.trim() || !(parseInt(rcost)>0)) return;
    setAddLoading(true);
    try {
      const resp = await fetch('/api/points/rewards', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${state.token}` },
        body: JSON.stringify({ name: rname.trim(), points_cost: parseInt(rcost), icon: ricon })
      });
      const result = await resp.json();
      if (resp.ok && result.success) {
        showLocalToast('success', '自定义权益已添加');
        dispatch({type:'ADD_REWARD', reward:{ id:String(result.data.rewardId), icon:ricon, name:rname.trim(), cost:parseInt(rcost), custom:true }});
        loadPointsData();
        setAddOpen(false); setRname(''); setRcost(''); setRicon('🎁');
      } else {
        showLocalToast('error', result.message || '添加失败');
      }
    } catch(e) {
      showLocalToast('error', '网络异常');
    } finally {
      setAddLoading(false);
    }
  };

  const rules = [['单科满分','+20','var(--orange-500)'],['得分率 ≥90%','+15','var(--orange-500)'],['较上次提升5分+','+10','var(--green-600)'],['完善错题备注','+3/科','var(--blue-600)'],['AI 拍照录入','+8','var(--blue-600)'],['月度稳步提升','+30','var(--green-600)']];
  const tasks = [
    { ti:Icons.edit, cls:'bg-blue-soft', t:'单次录入完整成绩', s:'每场 +5', r:'+5' },
    { ti:Icons.sheet, cls:'bg-green-soft', t:'批量录入成绩', s:'每次 +10', r:'+10' },
    { ti:Icons.heart, cls:'bg-orange-soft', t:`连续 ${streakDays} 天录入打卡`, s: streakDays>=7 ? '额外奖励 · 已达成' : `还差 ${7-streakDays} 天`, done: streakDays>=7 },
    { ti:Icons.chart, cls:'bg-purple-soft', t:'单科较上次提升 5 分+', s:'达成自动到账', r:'+10' },
  ];

  const localToastNode = localToast ? <div style={{position:'fixed', top:22, left:'50%', transform:'translateX(-50%)', zIndex:999,
    background:'#fff', border:'1px solid var(--line)', borderLeft:`4px solid ${localToast.type === 'error' ? 'var(--coral)' : '#5fcfa0'}`, borderRadius:12,
    padding:'13px 20px', boxShadow:'var(--shadow-lg)', display:'flex', alignItems:'center', gap:10, fontWeight:700, fontSize:13.5, animation:'toastIn .3s'}}>
    <span style={{width:20,height:20,borderRadius:'50%',background:localToast.type === 'error' ? 'var(--coral)' : '#5fcfa0',color:'#fff',display:'grid',placeItems:'center'}}><Ico d={Icons.check} size={13} sw={3.5}/></span>
    {localToast.msg}
  </div> : null;

  return <>
    <div className="pts-hero">
      <div className="pts-balance">
        <div className="l">{c.name} · 当前可用积分</div>
        <div className="v">{currentBalance}</div>
        <div className="meta">
          <div><div className="mv">+{totalEarned}</div><div className="ml">累计获得</div></div>
          <div><div className="mv">-{totalSpent}</div><div className="ml">累计消耗</div></div>
          <div><div className="mv">{streakDays} 天</div><div className="ml">连续打卡</div></div>
        </div>
      </div>
      <Card>
        <div className="card-head"><h3>近期积分收支</h3><div className="spacer"></div><Tag tone="orange">积分明细</Tag></div>
        {recentTx.length ? <EChart option={ChartOpt.pointsBar(barDays, barVals)} height={200}/>
          : <div style={{textAlign:'center',padding:'40px 0',color:'var(--ink-3)',fontSize:13}}>暂无积分收支记录</div>}
      </Card>
    </div>

    <div className="two">
      <Card>
        <div className="card-head"><h3>积分任务</h3><span className="sub">完成即自动到账</span></div>
        {tasks.map((t,i)=>(
          <div className="task" key={i}>
            <div className={'ti '+t.cls}><Ico d={t.ti} size={19}/></div>
            <div><div className="tt">{t.t}</div><div className="ts">{t.s}</div></div>
            {t.done ? <Tag tone="green" className="done">✓ 已领取</Tag> : <span className="reward">{t.r}</span>}
          </div>
        ))}
      </Card>
      <Card>
        <div className="card-head"><h3>积分获取规则</h3><div className="spacer"></div></div>
        <div className="grid g2" style={{gap:12}}>
          {rules.map(([n,v,col])=>(
            <div key={n} style={{display:'flex',justifyContent:'space-between',alignItems:'center',background:'var(--surface-2)',borderRadius:'var(--r-sm)',padding:'12px 14px'}}>
              <span style={{fontSize:13,color:'var(--ink-2)',fontWeight:600}}>{n}</span><b style={{fontFamily:"'Outfit'",color:col,fontSize:15}}>{v}</b></div>
          ))}
        </div>
        <div style={{background:'var(--blue-50)',borderRadius:'var(--r-sm)',padding:13,fontSize:12.5,color:'var(--blue-600)',lineHeight:1.6,marginTop:14}}>💡 越主动记录、越努力提升，积分越多。积分可在下方商城兑换专属奖励。</div>
      </Card>
    </div>

    <Card>
      <div className="card-head"><h3>兑换商城</h3><div className="spacer"></div>
        <Tag tone="green" dot>含家长自定义权益</Tag>
        {isParent && <Button variant="soft" size="sm" style={{marginLeft:10}} icon={<Ico d={Icons.plus} size={15}/>} onClick={()=>setAddOpen(true)}>新增自定义权益</Button>}
      </div>
      <div className="reward-grid">
        {apiRewards.map(r=>{
          const cost = r.points_cost || r.cost;
          const can = currentBalance >= cost;
          const isCustom = r.is_custom !== undefined ? r.is_custom : r.custom;
          const icon = r.icon || '🎁';
          return <div className={'reward-card '+(can?'':'disabled')} key={r.id} style={isCustom?{borderColor:'var(--green-100)',background:'var(--green-50)'}:null}>
            {isCustom && <span className="custom-tag">家长自定义</span>}
            <div className="rico" style={isCustom?{background:'#fff'}:{background:'var(--orange-50)'}}>{icon}</div>
            <div className="rn">{r.name}</div>
            <div className="rc">{cost} 分</div>
            <Button variant={can?'warm':'ghost'} size="sm" style={{width:'100%',marginTop:12,opacity:can?1:.6}}
              onClick={()=>handleRedeemClick({...r, cost})}>{can?'立即兑换':'积分不足'}</Button>
          </div>;
        })}
      </div>
    </Card>

    {redemptions.length > 0 && <Card style={{marginTop:18}}>
      <div className="card-head"><h3>兑换记录</h3><div className="spacer"></div></div>
      {redemptions.slice(0,5).map(rd=>(
        <div key={rd.id} style={{display:'flex',alignItems:'center',gap:12,padding:'10px 0',borderBottom:'1px solid var(--line)'}}>
          <span style={{fontSize:20}}>{rd.icon || '🎁'}</span>
          <div style={{flex:1}}><div style={{fontWeight:700,fontSize:13}}>{rd.name || '权益'}</div><div style={{fontSize:12,color:'var(--ink-3)'}}>{rd.created_at ? rd.created_at.slice(0,10) : ''}</div></div>
          <span style={{fontFamily:"'Outfit'",fontWeight:700,color:'var(--coral)',fontSize:13}}>-{rd.points_cost} 分</span>
          <Tag tone={rd.status==='confirmed'?'green':rd.status==='rejected'?'coral':'orange'}>{rd.status==='confirmed'?'已确认':rd.status==='rejected'?'已拒绝':'待确认'}</Tag>
        </div>
      ))}
    </Card>}

    <Modal open={addOpen} onClose={()=>setAddOpen(false)} title="新增家庭自定义权益">
      <div className="field"><label>权益名称 <span className="req">*</span></label><input className="input" value={rname} onChange={e=>setRname(e.target.value)} placeholder="如：周末游乐场出游"/></div>
      <div className="row2">
        <div className="field"><label>所需积分 <span className="req">*</span></label><input className="input" value={rcost} onChange={e=>setRcost(e.target.value)} inputMode="numeric" placeholder="如 300"/></div>
        <div className="field"><label>图标</label>
          <div className="chip-select">{['🎁','🎮','📝','🍦','🎬','⚽','📚','🏖️'].map(e=><span key={e} className={'chip '+(ricon===e?'on':'')} style={{fontSize:18}} onClick={()=>setRicon(e)}>{e}</span>)}</div>
        </div>
      </div>
      <div style={{fontSize:12,color:'var(--ink-3)',lineHeight:1.6,background:'var(--surface-2)',padding:'10px 12px',borderRadius:8}}>保存后立即在学生端商城同步显示，无需审核，即时生效。</div>
      <div style={{display:'flex',gap:12,justifyContent:'flex-end',marginTop:22}}>
        <Button variant="ghost" onClick={()=>setAddOpen(false)}>取消</Button>
        <Button variant="green" onClick={submitReward} disabled={addLoading}>{addLoading?'保存中...':'保存权益'}</Button>
      </div>
    </Modal>

    <Modal open={redeemConfirmOpen} onClose={()=>{ setRedeemConfirmOpen(false); setPendingReward(null); }} title="确认兑换">
      {pendingReward && <>
        <div style={{display:'flex',alignItems:'center',gap:14,padding:'10px 0 20px'}}>
          <div style={{width:52,height:52,borderRadius:'var(--r)',background:'var(--orange-50)',display:'grid',placeItems:'center',fontSize:28}}>{pendingReward.icon || '🎁'}</div>
          <div>
            <div style={{fontWeight:700,fontSize:15}}>{pendingReward.name}</div>
            <div style={{fontSize:13,color:'var(--ink-3)',marginTop:4}}>需要 <b style={{color:'var(--orange-500)',fontFamily:'Outfit'}}>{pendingReward.points_cost || pendingReward.cost}</b> 积分</div>
          </div>
        </div>
        <div style={{fontSize:12.5,color:'var(--ink-3)',lineHeight:1.6,background:'var(--surface-2)',padding:'10px 12px',borderRadius:8}}>
          兑换申请将提交给家长确认，确认后积分正式扣除，权益生效。
        </div>
      </>}
      <div style={{display:'flex',gap:12,justifyContent:'flex-end',marginTop:22}}>
        <Button variant="ghost" onClick={()=>{ setRedeemConfirmOpen(false); setPendingReward(null); }}>取消</Button>
        <Button variant="warm" onClick={handleRedeemConfirm}>确认兑换</Button>
      </div>
    </Modal>

    {localToastNode}
  </>;
}
Object.assign(window, { Points });