// HelperMatch Admin — Phase B4: Subscriptions + Plans
// Subscriptions list + detail, manual backfill, extend/refund/cancel
// Plans CRUD (pricing, entitlements, publish)

const PLAN_META = {
  free:     { label: 'Basic',    badge: 'plan-free',    color: '#667085' },
  standard: { label: 'Standard', badge: 'plan-std',     color: '#1F4C8F' },
  premium:  { label: 'Premium',  badge: 'plan-premium', color: '#6941C6' },
};

const PlanBadge = ({ plan }) => {
  const m = PLAN_META[plan] || PLAN_META.free;
  return (
    <span style={{
      display:'inline-flex',alignItems:'center',gap:5,
      padding:'2px 8px',borderRadius:4,fontSize:11,fontWeight:600,
      background:m.color+'14',color:m.color,border:'1px solid '+m.color+'33',
      letterSpacing:0.3,textTransform:'uppercase',
    }}>{m.label}</span>
  );
};

// ============================================================
// SUBSCRIPTIONS PAGE
// ============================================================
const SubscriptionsPageReal = () => {
  const { t } = (window.useI18n ? window.useI18n() : { t: (k)=>k });
  const { user } = useAuth();
  const toast = useToast();
  const [tab, setTab] = uS(() => {
    const m = window.location.hash.match(/status=([A-Z_]+)/);
    return m ? m[1] : 'ACTIVE';
  });
  const [q, setQ] = uS('');
  const [planFilter, setPlanFilter] = uS('');
  const [marketFilter, setMarketFilter] = uS('');
  const [sortBy, setSortBy] = uS('newest');
  const [openId, setOpenId] = uS(null);
  const [showNew, setShowNew] = uS(false);
  const [subs, setSubs] = uS(() => ADMIN.subs.map(s => ({ ...s })));

  const tabs = [
    { key: 'ACTIVE',    label: 'Active' },
    { key: 'EXPIRED',   label: 'Expired' },
    { key: 'CANCELLED', label: 'Cancelled' },
    { key: 'MANUAL',    label: '手動補單' },
    { key: 'ALL',       label: '全部' },
  ];
  const tabCount = (k) => {
    if (k === 'ALL') return subs.length;
    if (k === 'MANUAL') return subs.filter(s => s.manualNote).length;
    return subs.filter(s => s.status === k).length;
  };

  const filtered = uM(() => {
    let list = subs;
    if (tab === 'MANUAL') list = list.filter(s => s.manualNote);
    else if (tab !== 'ALL') list = list.filter(s => s.status === tab);
    if (q) {
      const qL = q.toLowerCase();
      list = list.filter(s => {
        const emp = ADMIN.employers.find(e => e.id === s.empId);
        return s.id.toLowerCase().includes(qL)
          || (s.stripeSession||'').toLowerCase().includes(qL)
          || (emp && (emp.name.toLowerCase().includes(qL) || emp.email.toLowerCase().includes(qL) || emp.id.toLowerCase().includes(qL)));
      });
    }
    if (planFilter) list = list.filter(s => s.plan === planFilter);
    if (marketFilter) {
      list = list.filter(s => {
        const emp = ADMIN.employers.find(e => e.id === s.empId);
        return emp && emp.homeMarket === marketFilter;
      });
    }
    list = [...list];
    if (sortBy === 'newest') list.sort((a,b) => new Date(b.startAt) - new Date(a.startAt));
    if (sortBy === 'oldest') list.sort((a,b) => new Date(a.startAt) - new Date(b.startAt));
    if (sortBy === 'amountDesc') list.sort((a,b) => b.amount - a.amount);
    return list;
  }, [subs, tab, q, planFilter, marketFilter, sortBy]);

  // KPI strip
  const now = ADMIN.now;
  const kpi = uM(() => {
    const active = subs.filter(s => s.status === 'ACTIVE');
    const mrr = active.reduce((sum, s) => sum + s.amount, 0);
    const expiringSoon = active.filter(s => {
      const daysLeft = FMT.daysUntil(s.endAt);
      return daysLeft >= 0 && daysLeft <= 3;
    }).length;
    const manualCount = subs.filter(s => s.manualNote).length;
    const last30dRevenue = subs
      .filter(s => new Date(s.startAt) > new Date(now.getTime() - 30 * 86400000))
      .reduce((sum, s) => sum + s.amount, 0);
    return { active: active.length, mrr, expiringSoon, manualCount, last30dRevenue };
  }, [subs]);

  const openSub = subs.find(s => s.id === openId);

  const update = (id, patch, logAction, logDiff) => {
    setSubs(xs => xs.map(s => s.id === id ? { ...s, ...patch } : s));
    if (logAction) {
      ADMIN.auditLogs.unshift({
        id: 'log_' + Math.random().toString(36).slice(2,8),
        at: new Date(), actor: 'Vincent Chen', action: logAction,
        targetType: 'Subscription', targetId: id, diff: logDiff || {}
      });
    }
  };

  const createSub = (data) => {
    const newId = 'sub_' + Math.floor(Math.random()*900 + 9100);
    const newSub = {
      id: newId,
      empId: data.empId,
      plan: data.plan,
      amount: data.amount,
      startAt: data.startAt,
      endAt: data.endAt,
      status: 'ACTIVE',
      stripeSession: 'manual_backfill_' + Math.random().toString(36).slice(2, 8),
      manualNote: data.note,
    };
    setSubs(xs => [newSub, ...xs]);
    ADMIN.auditLogs.unshift({
      id: 'log_' + Math.random().toString(36).slice(2,8),
      at: new Date(), actor: 'Vincent Chen', action: 'SUBSCRIPTION_MANUAL_CREATE',
      targetType: 'Subscription', targetId: newId,
      diff: { plan: data.plan, amount: data.amount, empId: data.empId, note: data.note }
    });
    toast.push({ kind: 'success', msg: '已建立手動補單 ' + newId });
  };

  return (
    <div className="a-page">
      <div className="a-page-header">
        <div>
          <h1 className="a-page-title"><AIcon name="card"/> {t('admin.subscriptions.title')}</h1>
          <p className="a-page-sub">{t('admin.subscriptions.subtitle')}</p>
        </div>
        <div className="flex gap-2">
          {/* CSV export — Super Admin only (data egress / privacy gate). */}
          {isSuperAdmin(user) && (
            <button className="a-btn a-btn-default">
              <AIcon name="download" size={14}/> 匯出 CSV
            </button>
          )}
          <button className="a-btn a-btn-primary" onClick={() => setShowNew(true)}>
            <AIcon name="plus" size={14}/> 手動補單
          </button>
        </div>
      </div>

      {/* KPIs */}
      <div style={{display:'grid',gridTemplateColumns:'repeat(4, 1fr)',gap:12,marginBottom:20}}>
        <KpiTile label="Active 訂閱" value={kpi.active} icon="check" />
        <KpiTile label="7 日內到期" value={kpi.expiringSoon} icon="clock" tone={kpi.expiringSoon > 0 ? 'warn' : 'neutral'} />
        <KpiTile label="30 日營收 (TWD)" value={'NT$' + (kpi.last30dRevenue/100).toLocaleString('en-US', {maximumFractionDigits: 0})} icon="chart" mono />
        <KpiTile label="手動補單累計" value={kpi.manualCount} icon="wrench" tone={kpi.manualCount > 0 ? 'info' : 'neutral'} />
      </div>

      {/* Tabs */}
      <div className="a-tabs">
        {tabs.map(t => (
          <div key={t.key} className={'a-tab ' + (tab === t.key ? 'active' : '')}
               onClick={() => { setTab(t.key); window.location.hash = '#/subscriptions?status=' + t.key; }}>
            {t.label}
            {tabCount(t.key) > 0 && <span className="a-tab-count">{tabCount(t.key)}</span>}
          </div>
        ))}
      </div>

      {/* Filters */}
      <div className="a-table-toolbar" style={{marginBottom:12}}>
        <div className="a-input-group" style={{width:280}}>
          <div className="a-input-group-prefix"><AIcon name="search" size={14}/></div>
          <input className="a-input" placeholder="Sub ID / 雇主名稱 / Stripe ID" value={q} onChange={e => setQ(e.target.value)}/>
        </div>
        <select className="a-select" style={{width:140}} value={planFilter} onChange={e => setPlanFilter(e.target.value)}>
          <option value="">所有方案</option>
          <option value="standard">Standard</option>
          <option value="premium">Premium</option>
        </select>
        <select className="a-select" style={{width:140}} value={marketFilter} onChange={e => setMarketFilter(e.target.value)}>
          <option value="">所有市場</option>
          {ADMIN.markets.map(m => <option key={m.code} value={m.code}>{m.nameZh}</option>)}
        </select>
        <select className="a-select" style={{width:160}} value={sortBy} onChange={e => setSortBy(e.target.value)}>
          <option value="newest">最新開始</option>
          <option value="oldest">最舊開始</option>
          <option value="amountDesc">金額高→低</option>
        </select>
        <span className="ml-auto text-muted fs-13">共 {filtered.length} 筆</span>
      </div>

      {/* Table */}
      <div className="a-table-wrap">
        <table className="a-table">
          <thead>
            <tr>
              <th>Sub ID</th>
              <th>雇主</th>
              <th>方案</th>
              <th>金額</th>
              <th>期間</th>
              <th>剩餘</th>
              <th>來源</th>
              <th>狀態</th>
              <th style={{width:40}}></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && (
              <tr><td colSpan={9}><AEmpty icon="card" label="沒有符合條件的訂閱" /></td></tr>
            )}
            {filtered.map(s => {
              const emp = ADMIN.employers.find(e => e.id === s.empId);
              const daysLeft = FMT.daysUntil(s.endAt);
              const isExpiringSoon = s.status === 'ACTIVE' && daysLeft >= 0 && daysLeft <= 3;
              const isExpired = s.status === 'ACTIVE' && daysLeft < 0;
              return (
                <tr key={s.id} className="clickable" onClick={() => setOpenId(s.id)}>
                  <td><Mono>{s.id}</Mono></td>
                  <td>
                    {emp ? (
                      <div>
                        <div style={{fontWeight:500}}>{emp.name}</div>
                        <div className="text-muted fs-12">{emp.email} · <Flag code={emp.homeMarket}/></div>
                      </div>
                    ) : <span className="text-muted">—</span>}
                  </td>
                  <td><PlanBadge plan={s.plan}/></td>
                  <td className="a-table-num"><Mono>NT${(s.amount/100).toLocaleString('en-US', {maximumFractionDigits:0})}</Mono></td>
                  <td className="fs-12" style={{color:'var(--a-ink-soft)'}}>
                    <div>{FMT.iso(s.startAt).slice(0,10)}</div>
                    <div className="text-muted">→ {FMT.iso(s.endAt).slice(0,10)}</div>
                  </td>
                  <td>
                    {s.status !== 'ACTIVE' ? <span className="text-muted">—</span> : (
                      <span style={{
                        fontWeight:500,
                        color: isExpired ? 'var(--a-danger)' : (isExpiringSoon ? 'var(--a-warn)' : 'var(--a-ink-soft)'),
                      }}>
                        {isExpired ? '已過期 ' + Math.abs(daysLeft) + ' 天' :
                         daysLeft === 0 ? '今日到期' :
                         daysLeft + ' 天'}
                      </span>
                    )}
                  </td>
                  <td>
                    {s.manualNote ? (
                      <span style={{display:'inline-flex',alignItems:'center',gap:4,color:'var(--a-warn)',fontSize:12}}>
                        <AIcon name="wrench" size={12}/> 手動
                      </span>
                    ) : (
                      <span style={{display:'inline-flex',alignItems:'center',gap:4,color:'var(--a-ink-soft)',fontSize:12}}>
                        <AIcon name="card" size={12}/> Stripe
                      </span>
                    )}
                  </td>
                  <td><StatusBadge status={s.status}/></td>
                  <td onClick={e => e.stopPropagation()}>
                    <button className="a-icon-btn" onClick={() => setOpenId(s.id)}>
                      <AIcon name="chevronRight" size={14}/>
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {openSub && (
        <SubscriptionDrawer sub={openSub} onClose={() => setOpenId(null)} onUpdate={update}/>
      )}

      {showNew && (
        <ManualBackfillModal onClose={() => setShowNew(false)} onCreate={(data) => { createSub(data); setShowNew(false); }}/>
      )}
    </div>
  );
};

// ============================================================
// KPI TILE
// ============================================================
const KpiTile = ({ label, value, icon, tone = 'neutral', mono = false }) => {
  const toneColor = { neutral:'var(--a-ink-soft)', success:'var(--a-success)', warn:'var(--a-warn)', danger:'var(--a-danger)', info:'var(--a-info)' }[tone];
  return (
    <div className="a-card" style={{padding:16}}>
      <div className="flex items-center gap-2" style={{marginBottom:8,color:'var(--a-ink-muted)',fontSize:12}}>
        <AIcon name={icon} size={14}/> {label}
      </div>
      <div style={{fontSize:22,fontWeight:600,color:toneColor,fontFamily:mono?'var(--a-mono)':'inherit'}}>{value}</div>
    </div>
  );
};

// ============================================================
// SUBSCRIPTION DRAWER
// ============================================================
const SubscriptionDrawer = ({ sub, onClose, onUpdate }) => {
  const toast = useToast();
  const [extendDays, setExtendDays] = uS(7);
  const [showExtend, setShowExtend] = uS(false);
  const [showRefund, setShowRefund] = uS(false);
  const [showCancel, setShowCancel] = uS(false);

  const emp = ADMIN.employers.find(e => e.id === sub.empId);
  const plan = ADMIN.plans.find(p => p.id === 'plan_' + sub.plan);
  const daysLeft = FMT.daysUntil(sub.endAt);
  const totalDays = Math.ceil((new Date(sub.endAt) - new Date(sub.startAt)) / 86400000);
  const usedDays = Math.max(0, totalDays - Math.max(0, daysLeft));
  const pct = Math.min(100, Math.max(0, Math.round(usedDays * 100 / totalDays)));

  // Build lifecycle timeline
  const timeline = [];
  timeline.push({ at: sub.startAt, label: '訂閱建立', icon: 'check', tone: 'success' });
  if (sub.manualNote) timeline.push({ at: sub.startAt, label: '手動補單 · ' + sub.manualNote.slice(0, 40), icon: 'wrench', tone: 'warn' });
  if (sub.status === 'CANCELLED') timeline.push({ at: sub.endAt, label: '已取消', icon: 'x', tone: 'danger' });
  else if (sub.status === 'EXPIRED') timeline.push({ at: sub.endAt, label: '期限到期', icon: 'clock', tone: 'neutral' });

  return (
    <ADrawer open onClose={onClose} width="lg" title={
      <div className="flex items-center gap-2">
        <Mono>{sub.id}</Mono>
        <StatusBadge status={sub.status}/>
        <PlanBadge plan={sub.plan}/>
      </div>
    }>
      {/* Employer header */}
      {emp && (
        <div className="a-card" style={{padding:16,marginBottom:16,background:'var(--a-paper-2)'}}>
          <div className="flex items-center gap-3">
            <div style={{
              width:44,height:44,borderRadius:'50%',
              background:'var(--a-primary)',color:'#fff',
              display:'grid',placeItems:'center',fontWeight:600,fontSize:16,
            }}>{emp.name.charAt(0)}</div>
            <div style={{flex:1}}>
              <div style={{fontWeight:600,fontSize:15}}>{emp.name}</div>
              <div className="text-muted fs-13">{emp.email} · <Flag code={emp.homeMarket}/> {emp.homeMarket}</div>
            </div>
            <div style={{textAlign:'right'}}>
              <div className="text-muted fs-12">家庭規模</div>
              <div style={{fontWeight:500}}>{emp.familySize} 人</div>
            </div>
            <button className="a-btn a-btn-default a-btn-sm">
              <AIcon name="external" size={12}/> 開啟雇主檔案
            </button>
          </div>
        </div>
      )}

      {/* Period & usage */}
      <div className="a-card" style={{marginBottom:16}}>
        <div className="a-card-header">
          <h3 className="a-card-title"><AIcon name="clock" size={14}/> 訂閱期間</h3>
        </div>
        <div className="a-card-body">
          <div style={{display:'grid',gridTemplateColumns:'repeat(4, 1fr)',gap:16,marginBottom:16}}>
            <div>
              <div className="text-muted fs-12">起始</div>
              <div style={{fontWeight:500,marginTop:4}}>{FMT.iso(sub.startAt).slice(0,10)}</div>
            </div>
            <div>
              <div className="text-muted fs-12">到期</div>
              <div style={{fontWeight:500,marginTop:4}}>{FMT.iso(sub.endAt).slice(0,10)}</div>
            </div>
            <div>
              <div className="text-muted fs-12">總天數</div>
              <div style={{fontWeight:500,marginTop:4}}>{totalDays} 天</div>
            </div>
            <div>
              <div className="text-muted fs-12">剩餘</div>
              <div style={{
                fontWeight:600,marginTop:4,
                color: sub.status !== 'ACTIVE' ? 'var(--a-ink-muted)' :
                       daysLeft < 0 ? 'var(--a-danger)' :
                       daysLeft <= 3 ? 'var(--a-warn)' : 'var(--a-success)',
              }}>
                {sub.status !== 'ACTIVE' ? '—' :
                 daysLeft < 0 ? '已過期 ' + Math.abs(daysLeft) + ' 天' :
                 daysLeft === 0 ? '今日到期' : daysLeft + ' 天'}
              </div>
            </div>
          </div>
          {sub.status === 'ACTIVE' && (
            <div style={{height:6,background:'var(--a-line)',borderRadius:3,overflow:'hidden'}}>
              <div style={{
                height:'100%',width:pct+'%',
                background: daysLeft < 0 ? 'var(--a-danger)' : daysLeft <= 3 ? 'var(--a-warn)' : 'var(--a-primary)',
              }}/>
            </div>
          )}
        </div>
      </div>

      {/* Payment */}
      <div className="a-card" style={{marginBottom:16}}>
        <div className="a-card-header">
          <h3 className="a-card-title"><AIcon name="card" size={14}/> 付款資訊</h3>
        </div>
        <div className="a-card-body">
          <dl style={{margin:0,display:'grid',gridTemplateColumns:'140px 1fr',gap:'10px 14px',fontSize:13}}>
            <dt className="text-muted">金額</dt>
            <dd style={{margin:0,fontFamily:'var(--a-mono)',fontWeight:600,fontSize:15}}>NT${(sub.amount/100).toLocaleString('en-US', {maximumFractionDigits:0})}</dd>
            <dt className="text-muted">方案</dt>
            <dd style={{margin:0}}>
              <PlanBadge plan={sub.plan}/>
              {plan && <span className="text-muted fs-12" style={{marginLeft:8}}>· {plan.durationDays} 天 · 聯絡上限 {plan.maxContacts ?? '∞'}</span>}
            </dd>
            <dt className="text-muted">來源</dt>
            <dd style={{margin:0}}>
              {sub.manualNote ? (
                <span style={{display:'inline-flex',alignItems:'center',gap:4,color:'var(--a-warn)'}}>
                  <AIcon name="wrench" size={13}/> 手動補單
                </span>
              ) : (
                <span style={{display:'inline-flex',alignItems:'center',gap:4}}>
                  <AIcon name="card" size={13}/> Stripe
                </span>
              )}
            </dd>
            <dt className="text-muted">交易 ID</dt>
            <dd style={{margin:0}}>
              <Mono>{sub.stripeSession}</Mono>
              {!sub.manualNote && (
                <button className="a-btn a-btn-ghost a-btn-xs" style={{marginLeft:6}}
                        onClick={() => { navigator.clipboard.writeText(sub.stripeSession); toast.push({kind:'success',msg:'已複製'}); }}>
                  <AIcon name="copy" size={11}/>
                </button>
              )}
              {!sub.manualNote && (
                <a href={'https://dashboard.stripe.com/test/checkout/sessions/' + sub.stripeSession}
                   target="_blank" rel="noreferrer"
                   style={{marginLeft:8,fontSize:12,color:'var(--a-primary)',textDecoration:'none'}}>
                  <AIcon name="external" size={11}/> 開啟 Stripe
                </a>
              )}
            </dd>
            {sub.manualNote && (<>
              <dt className="text-muted">補單備註</dt>
              <dd style={{margin:0,padding:'8px 10px',background:'#FEF3C7',borderRadius:6,border:'1px solid #FCD34D',color:'#713F12',fontSize:12.5,lineHeight:1.5}}>
                {sub.manualNote}
              </dd>
            </>)}
          </dl>
        </div>
      </div>

      {/* Entitlements */}
      {plan && (
        <div className="a-card" style={{marginBottom:16}}>
          <div className="a-card-header">
            <h3 className="a-card-title"><AIcon name="briefcase" size={14}/> 方案權益</h3>
          </div>
          <div className="a-card-body">
            <div style={{display:'grid',gridTemplateColumns:'repeat(4, 1fr)',gap:12}}>
              <Entitlement icon="eye"    label="影片觀看"   value={plan.maxVideoViews ?? '∞'} />
              <Entitlement icon="chat"   label="聯絡次數"   value={plan.maxContacts ?? '∞'} />
              <Entitlement icon="briefcase" label="可發職缺" value={plan.maxJobPosts} />
              <Entitlement icon="check"  label="候選人比較" value={plan.canCompare ? '支援' : '—'} />
            </div>
          </div>
        </div>
      )}

      {/* Timeline */}
      <div className="a-card" style={{marginBottom:16}}>
        <div className="a-card-header">
          <h3 className="a-card-title"><AIcon name="clock" size={14}/> 生命週期</h3>
        </div>
        <div className="a-card-body">
          <div style={{position:'relative',paddingLeft:20}}>
            <div style={{position:'absolute',left:6,top:6,bottom:6,width:1,background:'var(--a-line)'}}/>
            {timeline.map((e, i) => (
              <div key={i} style={{position:'relative',marginBottom:12,paddingLeft:8}}>
                <div style={{
                  position:'absolute',left:-20,top:2,width:13,height:13,borderRadius:'50%',
                  background:'var(--a-paper)',border:'2px solid ' + (
                    e.tone === 'success' ? 'var(--a-success)' :
                    e.tone === 'danger' ? 'var(--a-danger)' :
                    e.tone === 'warn' ? 'var(--a-warn)' : 'var(--a-ink-muted)'
                  ),
                  display:'grid',placeItems:'center',
                }}>
                  <AIcon name={e.icon} size={7}/>
                </div>
                <div style={{fontSize:13,fontWeight:500}}>{e.label}</div>
                <div className="text-muted fs-12">{FMT.iso(e.at)}</div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Actions */}
      {sub.status === 'ACTIVE' && (
        <div style={{display:'flex',gap:8,padding:'12px 0',borderTop:'1px solid var(--a-line)',justifyContent:'flex-end'}}>
          <button className="a-btn a-btn-default" onClick={() => setShowExtend(true)}>
            <AIcon name="clock" size={14}/> 延長期限
          </button>
          <button className="a-btn a-btn-danger" onClick={() => setShowRefund(true)}>
            <AIcon name="card" size={14}/> 退款
          </button>
          <button className="a-btn a-btn-danger-solid" onClick={() => setShowCancel(true)}>
            <AIcon name="x" size={14}/> 取消訂閱
          </button>
        </div>
      )}

      {/* Extend modal */}
      {showExtend && (
        <AModal open onClose={() => setShowExtend(false)} title="延長訂閱期限" footer={
          <>
            <button className="a-btn a-btn-default" onClick={() => setShowExtend(false)}>取消</button>
            <button className="a-btn a-btn-primary" onClick={() => {
              const newEnd = new Date(new Date(sub.endAt).getTime() + extendDays * 86400000);
              onUpdate(sub.id, { endAt: newEnd }, 'SUBSCRIPTION_EXTEND', {
                endAt: { before: FMT.iso(sub.endAt).slice(0,10), after: FMT.iso(newEnd).slice(0,10) },
                extendDays,
              });
              toast.push({ kind:'success', msg:'已延長 ' + extendDays + ' 天' });
              setShowExtend(false);
            }}>確認延長</button>
          </>
        }>
          <div style={{marginBottom:12}}>
            <label className="text-muted fs-12">延長天數</label>
            <div style={{display:'flex',gap:6,marginTop:6}}>
              {[3, 7, 14, 30].map(d => (
                <button key={d} className={'a-btn a-btn-sm ' + (extendDays === d ? 'a-btn-primary' : 'a-btn-default')}
                        onClick={() => setExtendDays(d)}>+{d} 天</button>
              ))}
              <input type="number" className="a-input a-input-sm" style={{width:80}} value={extendDays}
                     onChange={e => setExtendDays(Number(e.target.value))} />
            </div>
          </div>
          <div style={{background:'var(--a-bg)',padding:10,borderRadius:6,fontSize:12.5}}>
            <div className="text-muted">新的到期日：</div>
            <div style={{fontWeight:600,marginTop:2}}>
              {FMT.iso(new Date(new Date(sub.endAt).getTime() + extendDays * 86400000)).slice(0,10)}
            </div>
          </div>
        </AModal>
      )}

      {/* Cancel modal */}
      {showCancel && (
        <CancelModal sub={sub} onClose={() => setShowCancel(false)} onConfirm={(reason) => {
          onUpdate(sub.id, {
            status: 'CANCELLED',
            endAt: new Date(),
            manualNote: (sub.manualNote ? sub.manualNote + ' / ' : '') + '取消：' + reason,
          }, 'SUBSCRIPTION_CANCEL', {
            status: { before: 'ACTIVE', after: 'CANCELLED' }, reason,
          });
          toast.push({ kind:'success', msg:'訂閱已取消' });
          setShowCancel(false);
          onClose();
        }}/>
      )}

      {/* Refund modal */}
      {showRefund && (
        <RefundModal sub={sub} onClose={() => setShowRefund(false)} onConfirm={(data) => {
          onUpdate(sub.id, {
            status: 'CANCELLED',
            endAt: new Date(),
            manualNote: (sub.manualNote ? sub.manualNote + ' / ' : '') + '退款 NT$' + (data.amount/100).toFixed(0) + '：' + data.reason,
          }, 'SUBSCRIPTION_REFUND', {
            refundAmount: data.amount, reason: data.reason,
            status: { before: 'ACTIVE', after: 'CANCELLED' },
          });
          toast.push({ kind:'success', msg:'已提交退款 NT$' + (data.amount/100).toFixed(0) });
          setShowRefund(false);
          onClose();
        }}/>
      )}
    </ADrawer>
  );
};

const Entitlement = ({ icon, label, value }) => (
  <div style={{padding:'10px 12px',border:'1px solid var(--a-line)',borderRadius:8,background:'var(--a-paper-2)'}}>
    <div className="flex items-center gap-1" style={{color:'var(--a-ink-muted)',fontSize:11.5,marginBottom:4}}>
      <AIcon name={icon} size={12}/> {label}
    </div>
    <div style={{fontWeight:600,fontSize:16,fontFamily:'var(--a-mono)'}}>{value}</div>
  </div>
);

// ============================================================
// CANCEL MODAL
// ============================================================
const CancelModal = ({ sub, onClose, onConfirm }) => {
  const [reason, setReason] = uS('');
  const presets = ['雇主主動要求','系統錯誤重複扣款','詐欺嫌疑','信用卡爭議','其他'];
  return (
    <AModal open onClose={onClose} title={<>取消訂閱 <Mono>{sub.id}</Mono></>} footer={
      <>
        <button className="a-btn a-btn-default" onClick={onClose}>返回</button>
        <button className="a-btn a-btn-danger-solid" disabled={!reason.trim()}
                onClick={() => onConfirm(reason.trim())}>
          <AIcon name="x" size={14}/> 確認取消
        </button>
      </>
    }>
      <div style={{padding:12,background:'#FEF2F2',border:'1px solid #FECACA',borderRadius:6,marginBottom:12,fontSize:13,color:'#991B1B'}}>
        <strong>⚠ 此動作將立即終止訂閱</strong>
        <div style={{marginTop:4,fontSize:12.5,lineHeight:1.5,color:'#7F1D1D'}}>
          雇主將無法繼續瀏覽完整候選人資料、聯絡候選人。此操作會記錄於審計日誌。
        </div>
      </div>
      <label className="text-muted fs-12">取消原因 *</label>
      <div style={{display:'flex',gap:4,flexWrap:'wrap',margin:'6px 0'}}>
        {presets.map(p => (
          <button key={p} className={'a-btn a-btn-xs ' + (reason === p ? 'a-btn-primary' : 'a-btn-default')}
                  onClick={() => setReason(p)}>{p}</button>
        ))}
      </div>
      <textarea className="a-textarea" placeholder="詳細描述…" value={reason}
                onChange={e => setReason(e.target.value)} style={{minHeight:72,marginTop:4}}/>
    </AModal>
  );
};

// ============================================================
// REFUND MODAL
// ============================================================
const RefundModal = ({ sub, onClose, onConfirm }) => {
  const [amount, setAmount] = uS(sub.amount);
  const [reason, setReason] = uS('');
  const [mode, setMode] = uS('full');
  uE(() => {
    if (mode === 'full') setAmount(sub.amount);
    if (mode === 'partial') setAmount(Math.round(sub.amount / 2));
  }, [mode]);

  return (
    <AModal open onClose={onClose} title={<>退款 <Mono>{sub.id}</Mono></>} footer={
      <>
        <button className="a-btn a-btn-default" onClick={onClose}>返回</button>
        <button className="a-btn a-btn-danger" disabled={!reason.trim() || amount <= 0}
                onClick={() => onConfirm({ amount, reason: reason.trim(), mode })}>
          <AIcon name="card" size={14}/> 確認退款 NT${(amount/100).toFixed(0)}
        </button>
      </>
    }>
      <div style={{display:'flex',gap:8,marginBottom:12}}>
        {[['full','全額退款'],['partial','部分退款'],['custom','自訂金額']].map(([v, l]) => (
          <button key={v} className={'a-btn a-btn-sm ' + (mode === v ? 'a-btn-primary' : 'a-btn-default')}
                  onClick={() => setMode(v)}>{l}</button>
        ))}
      </div>
      <label className="text-muted fs-12">退款金額（NT$）</label>
      <input type="number" className="a-input" value={Math.round(amount/100)}
             onChange={e => setAmount(Number(e.target.value) * 100)}
             disabled={mode === 'full'} style={{marginTop:6,marginBottom:12}}/>
      <div style={{padding:10,background:'var(--a-bg)',borderRadius:6,fontSize:12.5,marginBottom:12}}>
        <div className="flex" style={{justifyContent:'space-between'}}>
          <span className="text-muted">原金額</span>
          <Mono>NT${(sub.amount/100).toFixed(0)}</Mono>
        </div>
        <div className="flex" style={{justifyContent:'space-between',marginTop:4,fontWeight:600}}>
          <span>退款金額</span>
          <Mono style={{color:'var(--a-danger)'}}>-NT${(amount/100).toFixed(0)}</Mono>
        </div>
      </div>
      <label className="text-muted fs-12">退款原因 *</label>
      <textarea className="a-textarea" value={reason} onChange={e => setReason(e.target.value)}
                placeholder="例：雇主客訴 xxx，經內部確認退款" style={{marginTop:4}}/>
    </AModal>
  );
};

// ============================================================
// MANUAL BACKFILL MODAL
// ============================================================
const ManualBackfillModal = ({ onClose, onCreate }) => {
  const [empId, setEmpId] = uS('');
  const [plan, setPlan] = uS('standard');
  const [duration, setDuration] = uS(7);
  const [note, setNote] = uS('');
  const [empQ, setEmpQ] = uS('');

  const planMeta = ADMIN.plans.find(p => p.id === 'plan_' + plan);
  const amount = planMeta?.price || 0;
  const startAt = new Date();
  const endAt = new Date(startAt.getTime() + duration * 86400000);

  const matchedEmp = uM(() => {
    if (empId) return ADMIN.employers.find(e => e.id === empId);
    return null;
  }, [empId]);

  const empSuggestions = uM(() => {
    if (!empQ || empId) return [];
    const qL = empQ.toLowerCase();
    return ADMIN.employers.filter(e =>
      e.name.toLowerCase().includes(qL) ||
      e.email.toLowerCase().includes(qL) ||
      e.id.toLowerCase().includes(qL)
    ).slice(0, 5);
  }, [empQ, empId]);

  return (
    <AModal open onClose={onClose} title="手動補單" footer={
      <>
        <button className="a-btn a-btn-default" onClick={onClose}>取消</button>
        <button className="a-btn a-btn-primary" disabled={!empId || !note.trim()}
                onClick={() => onCreate({ empId, plan, amount, startAt, endAt, note: note.trim() })}>
          <AIcon name="plus" size={14}/> 建立訂閱
        </button>
      </>
    }>
      <div style={{padding:12,background:'#FFFBEB',border:'1px solid #FDE68A',borderRadius:6,marginBottom:16,fontSize:12.5,color:'#713F12',lineHeight:1.55}}>
        <strong>⚠ 僅限客服後台補救流程</strong><br/>
        Stripe 連線失敗、金流廠商爭議、超商繳費未自動銷帳等情境。補單會標註為「手動」來源，並記錄於審計日誌。
      </div>

      {/* Employer picker */}
      <label className="text-muted fs-12">雇主 *</label>
      {matchedEmp ? (
        <div style={{
          display:'flex',alignItems:'center',gap:12,padding:10,marginTop:6,
          border:'1px solid var(--a-primary-line)',background:'var(--a-primary-50)',borderRadius:6,
        }}>
          <div style={{width:36,height:36,borderRadius:'50%',background:'var(--a-primary)',color:'#fff',display:'grid',placeItems:'center',fontWeight:600}}>{matchedEmp.name.charAt(0)}</div>
          <div style={{flex:1}}>
            <div style={{fontWeight:500}}>{matchedEmp.name}</div>
            <div className="text-muted fs-12">{matchedEmp.email} · <Flag code={matchedEmp.homeMarket}/></div>
          </div>
          <button className="a-btn a-btn-ghost a-btn-sm" onClick={() => setEmpId('')}>更換</button>
        </div>
      ) : (
        <div style={{position:'relative',marginTop:6,marginBottom:14}}>
          <input className="a-input" placeholder="搜尋雇主名稱 / email / ID" value={empQ} onChange={e => setEmpQ(e.target.value)}/>
          {empSuggestions.length > 0 && (
            <div style={{
              position:'absolute',top:'100%',left:0,right:0,marginTop:4,zIndex:10,
              background:'#fff',border:'1px solid var(--a-line-strong)',borderRadius:6,
              boxShadow:'var(--a-shadow-md)',maxHeight:240,overflowY:'auto',
            }}>
              {empSuggestions.map(e => (
                <div key={e.id} onClick={() => { setEmpId(e.id); setEmpQ(''); }}
                     style={{padding:'8px 12px',cursor:'pointer',borderBottom:'1px solid var(--a-line)'}}
                     onMouseEnter={ev => ev.currentTarget.style.background = 'var(--a-bg)'}
                     onMouseLeave={ev => ev.currentTarget.style.background = ''}>
                  <div style={{fontSize:13,fontWeight:500}}>{e.name} · <Flag code={e.homeMarket}/></div>
                  <div className="text-muted fs-12">{e.email} · <Mono>{e.id}</Mono></div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Plan */}
      <label className="text-muted fs-12" style={{display:'block',marginTop:12}}>方案 *</label>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8,marginTop:6}}>
        {['standard','premium'].map(p => {
          const pm = ADMIN.plans.find(x => x.id === 'plan_' + p);
          return (
            <div key={p}
                 onClick={() => setPlan(p)}
                 style={{
                   padding:12,borderRadius:8,cursor:'pointer',
                   border: plan === p ? '2px solid var(--a-primary)' : '1px solid var(--a-line-strong)',
                   background: plan === p ? 'var(--a-primary-50)' : 'var(--a-paper)',
                 }}>
              <div className="flex items-center gap-2" style={{marginBottom:4}}>
                <PlanBadge plan={p}/>
                <span style={{fontWeight:600}}>NT${pm ? Math.round(pm.price/100) : '—'}</span>
              </div>
              <div className="text-muted fs-12">{pm?.durationDays} 天 · 聯絡上限 {pm?.maxContacts ?? '∞'}</div>
            </div>
          );
        })}
      </div>

      {/* Duration override */}
      <label className="text-muted fs-12" style={{display:'block',marginTop:14}}>有效天數</label>
      <div style={{display:'flex',gap:6,marginTop:6}}>
        {[7, 14, 30, 60, 90].map(d => (
          <button key={d} className={'a-btn a-btn-sm ' + (duration === d ? 'a-btn-primary' : 'a-btn-default')}
                  onClick={() => setDuration(d)}>{d} 天</button>
        ))}
        <input type="number" className="a-input a-input-sm" style={{width:80}} value={duration}
               onChange={e => setDuration(Number(e.target.value))}/>
      </div>

      {/* Summary */}
      <div style={{padding:12,background:'var(--a-bg)',borderRadius:6,marginTop:14,fontSize:13}}>
        <div className="flex" style={{justifyContent:'space-between',marginBottom:4}}>
          <span className="text-muted">金額</span>
          <span style={{fontFamily:'var(--a-mono)',fontWeight:600}}>NT${Math.round(amount/100)}</span>
        </div>
        <div className="flex" style={{justifyContent:'space-between',marginBottom:4}}>
          <span className="text-muted">開始</span>
          <span>{FMT.iso(startAt).slice(0,10)}</span>
        </div>
        <div className="flex" style={{justifyContent:'space-between'}}>
          <span className="text-muted">結束</span>
          <span>{FMT.iso(endAt).slice(0,10)}</span>
        </div>
      </div>

      {/* Note */}
      <label className="text-muted fs-12" style={{display:'block',marginTop:14}}>補單原因 *（將記錄於審計日誌）</label>
      <textarea className="a-textarea" value={note} onChange={e => setNote(e.target.value)}
                placeholder="例：客服通話後確認付款，對方 Stripe 連線失敗。Ref: CS-2026-04-123" style={{marginTop:6}}/>
    </AModal>
  );
};

// ============================================================
// PLANS PAGE
// ============================================================
const PlansPageReal = () => {
  const { t } = (window.useI18n ? window.useI18n() : { t: (k)=>k });
  const toast = useToast();
  const [plans, setPlans] = uS(() => ADMIN.plans.map(p => ({ ...p })));
  const [editId, setEditId] = uS(null);

  const editPlan = plans.find(p => p.id === editId);

  const update = (id, patch) => {
    setPlans(xs => xs.map(p => p.id === id ? { ...p, ...patch } : p));
    ADMIN.auditLogs.unshift({
      id: 'log_' + Math.random().toString(36).slice(2,8),
      at: new Date(), actor: 'Vincent Chen', action: 'PLAN_EDIT',
      targetType: 'Plan', targetId: id, diff: patch,
    });
  };

  return (
    <div className="a-page">
      <div className="a-page-header">
        <div>
          <h1 className="a-page-title"><AIcon name="briefcase"/> {t('admin.plans.title')}</h1>
          <p className="a-page-sub">{t('admin.plans.subtitle')}</p>
        </div>
      </div>

      <div style={{display:'grid',gridTemplateColumns:'repeat(3, 1fr)',gap:16}}>
        {plans.map(p => {
          const key = p.id.replace('plan_', '');
          return (
            <div key={p.id} className="a-card" style={{padding:0,overflow:'hidden',position:'relative'}}>
              <div style={{
                padding:'14px 18px',borderBottom:'1px solid var(--a-line)',
                background: key === 'premium' ? 'linear-gradient(135deg, #6941C6 0%, #9B72E0 100%)' :
                           key === 'standard' ? 'linear-gradient(135deg, #1F4C8F 0%, #3A6FBB 100%)' :
                           'var(--a-paper-2)',
                color: key === 'free' ? 'var(--a-ink)' : '#fff',
              }}>
                <div className="flex items-center" style={{justifyContent:'space-between'}}>
                  <div style={{fontSize:11,letterSpacing:1,textTransform:'uppercase',opacity:0.85}}>{p.nameZh}</div>
                  <StatusBadge status={p.active ? 'ACTIVE' : 'CANCELLED'}/>
                </div>
                <div style={{fontSize:20,fontWeight:700,marginTop:4}}>{p.name}</div>
                <div style={{marginTop:10,fontSize:26,fontWeight:700,fontFamily:'var(--a-mono)'}}>
                  NT${Math.round(p.price/100).toLocaleString()}
                  <span style={{fontSize:12,fontWeight:400,opacity:0.75,marginLeft:6}}>
                    / {p.durationDays || '∞'} 天
                  </span>
                </div>
              </div>
              <div className="a-card-body">
                <ul style={{margin:0,padding:0,listStyle:'none',fontSize:13}}>
                  <PlanFeat icon="eye"   label="影片觀看上限" value={p.maxVideoViews == null ? '無限' : p.maxVideoViews + ' 支'}/>
                  <PlanFeat icon="chat"  label="聯絡上限"     value={p.maxContacts == null ? '無限' : p.maxContacts + ' 次'}/>
                  <PlanFeat icon="briefcase" label="可發職缺"  value={p.maxJobPosts + ' 則'}/>
                  <PlanFeat icon="check" label="候選人比較"   value={p.canCompare ? '✓ 支援' : '—'}/>
                </ul>
              </div>
              <div className="a-card-footer" style={{justifyContent:'space-between'}}>
                <span className="text-muted fs-12">{subsForPlan(key)} 個使用中</span>
                <button className="a-btn a-btn-default a-btn-sm" onClick={() => setEditId(p.id)}>
                  <AIcon name="pencil" size={12}/> 編輯
                </button>
              </div>
            </div>
          );
        })}
      </div>

      <div style={{marginTop:32}}>
        <h3 style={{fontSize:14,fontWeight:600,marginBottom:10}}>方案調整歷史</h3>
        <div className="a-table-wrap">
          <table className="a-table a-table-compact">
            <thead><tr><th>時間</th><th>方案</th><th>變更內容</th><th>操作者</th></tr></thead>
            <tbody>
              {ADMIN.auditLogs.filter(l => l.targetType === 'Plan').slice(0, 10).map(l => (
                <tr key={l.id}>
                  <td className="a-table-mono">{FMT.iso(l.at)}</td>
                  <td><Mono>{l.targetId}</Mono></td>
                  <td style={{fontSize:12.5}}>
                    {Object.entries(l.diff || {}).map(([k, v]) => (
                      <div key={k}>
                        <strong>{k}</strong>: {typeof v === 'object' && v !== null && 'before' in v
                          ? <><span style={{textDecoration:'line-through',color:'var(--a-ink-muted)'}}>{String(v.before)}</span> → <span style={{color:'var(--a-success)'}}>{String(v.after)}</span></>
                          : <span>{String(v)}</span>}
                      </div>
                    ))}
                  </td>
                  <td>{l.actor}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {editPlan && (
        <EditPlanModal plan={editPlan} onClose={() => setEditId(null)} onSave={(patch, diff) => {
          update(editPlan.id, patch);
          toast.push({ kind: 'success', msg: '方案已更新' });
          setEditId(null);
        }}/>
      )}
    </div>
  );
};

const subsForPlan = (key) => {
  return ADMIN.subs.filter(s => s.plan === key && s.status === 'ACTIVE').length;
};

const PlanFeat = ({ icon, label, value }) => (
  <li style={{display:'flex',alignItems:'center',padding:'7px 0',borderBottom:'1px solid var(--a-line)'}}>
    <AIcon name={icon} size={13} style={{color:'var(--a-ink-muted)',marginRight:8}}/>
    <span className="text-muted" style={{fontSize:12.5,flex:1}}>{label}</span>
    <span style={{fontWeight:500}}>{value}</span>
  </li>
);

// ============================================================
// EDIT PLAN MODAL
// ============================================================
const EditPlanModal = ({ plan, onClose, onSave }) => {
  const [form, setForm] = uS({
    name: plan.name, nameZh: plan.nameZh, price: plan.price,
    durationDays: plan.durationDays,
    maxVideoViews: plan.maxVideoViews, maxContacts: plan.maxContacts,
    maxJobPosts: plan.maxJobPosts, canCompare: plan.canCompare, active: plan.active,
  });
  const diff = {};
  Object.keys(form).forEach(k => {
    if (form[k] !== plan[k]) diff[k] = { before: plan[k], after: form[k] };
  });
  const changed = Object.keys(diff).length > 0;

  return (
    <AModal open onClose={onClose} title={<>編輯方案 <Mono>{plan.id}</Mono></>} width={540} footer={
      <>
        <button className="a-btn a-btn-default" onClick={onClose}>取消</button>
        <button className="a-btn a-btn-primary" disabled={!changed}
                onClick={() => onSave(form, diff)}>
          <AIcon name="check" size={14}/> 儲存（{Object.keys(diff).length} 項變更）
        </button>
      </>
    }>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12}}>
        <Field label="英文名稱">
          <input className="a-input" value={form.name}
                 onChange={e => setForm({...form, name: e.target.value})}/>
        </Field>
        <Field label="中文名稱">
          <input className="a-input" value={form.nameZh}
                 onChange={e => setForm({...form, nameZh: e.target.value})}/>
        </Field>
        <Field label="定價 (NT$)">
          <input type="number" className="a-input" value={Math.round(form.price/100)}
                 onChange={e => setForm({...form, price: Number(e.target.value) * 100})}/>
        </Field>
        <Field label="有效天數">
          <input type="number" className="a-input" value={form.durationDays}
                 onChange={e => setForm({...form, durationDays: Number(e.target.value)})}/>
        </Field>
        <Field label="影片觀看上限（空=∞）">
          <input type="number" className="a-input" value={form.maxVideoViews ?? ''}
                 onChange={e => setForm({...form, maxVideoViews: e.target.value === '' ? null : Number(e.target.value)})}/>
        </Field>
        <Field label="聯絡上限（空=∞）">
          <input type="number" className="a-input" value={form.maxContacts ?? ''}
                 onChange={e => setForm({...form, maxContacts: e.target.value === '' ? null : Number(e.target.value)})}/>
        </Field>
        <Field label="可發職缺">
          <input type="number" className="a-input" value={form.maxJobPosts}
                 onChange={e => setForm({...form, maxJobPosts: Number(e.target.value)})}/>
        </Field>
        <Field label="候選人比較功能">
          <select className="a-select" value={form.canCompare ? '1' : '0'}
                  onChange={e => setForm({...form, canCompare: e.target.value === '1'})}>
            <option value="0">停用</option>
            <option value="1">啟用</option>
          </select>
        </Field>
      </div>

      <label style={{display:'flex',alignItems:'center',gap:8,marginTop:14,padding:10,background:'var(--a-bg)',borderRadius:6,cursor:'pointer'}}>
        <input type="checkbox" checked={form.active} onChange={e => setForm({...form, active: e.target.checked})}/>
        <div>
          <div style={{fontWeight:500,fontSize:13}}>對外上架</div>
          <div className="text-muted fs-12">關閉後雇主訂閱頁不會顯示此方案；既有訂閱不受影響。</div>
        </div>
      </label>

      {changed && (
        <div style={{marginTop:14,padding:12,background:'var(--a-primary-50)',border:'1px solid var(--a-primary-line)',borderRadius:6}}>
          <div style={{fontSize:12,fontWeight:600,color:'var(--a-primary)',marginBottom:6}}>即將變更 {Object.keys(diff).length} 項</div>
          {Object.entries(diff).map(([k, v]) => (
            <div key={k} style={{fontSize:12.5,lineHeight:1.6}}>
              <strong>{k}</strong>:{' '}
              <span style={{textDecoration:'line-through',color:'var(--a-ink-muted)'}}>{String(v.before)}</span>
              {' → '}
              <span style={{color:'var(--a-primary)',fontWeight:500}}>{String(v.after)}</span>
            </div>
          ))}
        </div>
      )}
    </AModal>
  );
};

const Field = ({ label, children }) => (
  <div>
    <label className="text-muted fs-12" style={{display:'block',marginBottom:4}}>{label}</label>
    {children}
  </div>
);

Object.assign(window, {
  SubscriptionsPageReal, PlansPageReal, PlanBadge,
});
