/* ============================================================
   components.jsx — UI ส่วนกลาง
   ============================================================ */

// ---- Icon set (simple line icons) ----
const ICON_PATHS = {
  calendar:'M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z',
  clock:'M12 7v5l3 2 M12 21a9 9 0 1 1 0-18 9 9 0 0 1 0 18z',
  check:'M20 6 9 17l-5-5',
  checkCircle:'M22 11.08V12a10 10 0 1 1-5.93-9.14 M22 4 12 14.01l-3-3',
  x:'M18 6 6 18M6 6l12 12',
  xCircle:'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M15 9l-6 6 M9 9l6 6',
  bell:'M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9 M10.3 21a1.94 1.94 0 0 0 3.4 0',
  user:'M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2 M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  users:'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75',
  swap:'M16 3h5v5 M21 3l-7 7 M8 21H3v-5 M3 21l7-7',
  send:'M22 2 11 13 M22 2l-7 20-4-9-9-4 20-7z',
  arrowLeft:'M19 12H5M12 19l-7-7 7-7',
  plus:'M12 5v14M5 12h14',
  layers:'M12 2 2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5',
  briefcase:'M20 7H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16',
  thermometer:'M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z',
  flag:'M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z M4 22V15',
  clipboard:'M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2 M9 2h6a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z',
  inbox:'M22 12h-6l-2 3h-4l-2-3H2 M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z',
  shield:'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
  filter:'M22 3H2l8 9.46V19l4 2v-8.54L22 3z',
  chevronRight:'M9 18l6-6-6-6',
  hourglass:'M5 22h14M5 2h14M17 22v-4.17a2 2 0 0 0-.59-1.42L12 12l-4.41 4.41A2 2 0 0 0 7 17.83V22M7 2v4.17a2 2 0 0 0 .59 1.42L12 12l4.41-4.41A2 2 0 0 0 17 6.17V2',
  edit:'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z',
  info:'M12 16v-4M12 8h.01 M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z',
};
function Icon({name, size=18, sw=2, style, className}){
  const d = ICON_PATHS[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
      style={style} className={className} aria-hidden="true">
      {d.split(' M').map((seg,i)=> <path key={i} d={(i?'M':'')+seg} />)}
    </svg>
  );
}

function Avatar({t, size='md'}){
  if(!t) return null;
  return <div className={`av av-${size}`} style={{background:t.color}}>{t.init}</div>;
}

function Card({children, className=''}){ return <div className={`card ${className}`}>{children}</div>; }
function CardHead({icon, title, sub, right}){
  return (
    <div className="card-hd">
      {icon && <span className="ic"><Icon name={icon} size={20}/></span>}
      <div className="grow">
        <h3>{title}</h3>
        {sub && <div className="sub">{sub}</div>}
      </div>
      {right}
    </div>
  );
}

function Btn({variant='primary', size, icon, iconRight, children, block, ...rest}){
  const cls = `btn btn-${variant} ${size==='sm'?'btn-sm':''} ${block?'btn-block':''}`;
  return (
    <button className={cls} {...rest}>
      {icon && <Icon name={icon} size={size==='sm'?15:17}/>}
      {children}
      {iconRight && <Icon name={iconRight} size={size==='sm'?15:17}/>}
    </button>
  );
}

function StatusBadge({status}){
  if(status==='acknowledged') return <span className="badge b-ack"><span className="b-dot"/>รับทราบแล้ว</span>;
  if(status==='rejected')     return <span className="badge b-reject"><span className="b-dot"/>ปฏิเสธ</span>;
  if(status==='done')         return <span className="badge b-done"><span className="b-dot"/>เสร็จสิ้น</span>;
  return <span className="badge b-pending"><span className="b-dot"/>รอรับทราบ</span>;
}

function ReasonTag({reason, withIcon=true}){
  const r = REASONS.find(x=>x.id===reason);
  if(!r) return null;
  return <span className={`reason-tag ${r.tag}`}>{withIcon && <Icon name={r.icon} size={13}/>}{r.label}</span>;
}

function Empty({icon='inbox', title, desc}){
  return (
    <div className="empty">
      <div className="ic"><Icon name={icon} size={52} sw={1.4}/></div>
      <div className="t">{title}</div>
      {desc && <div className="d">{desc}</div>}
    </div>
  );
}

function Toast({msg, icon='checkCircle'}){
  if(!msg) return null;
  return <div className="toast"><span className="ic"><Icon name={icon} size={20}/></span>{msg}</div>;
}

function PeriodSlot({entry, selected, children, onClick, selectable}){
  return (
    <div className={`slot ${selected?'sel':''}`} onClick={onClick} style={{cursor:selectable?'pointer':'default'}}>
      <div className="pno"><b className="num">{entry.period}</b><span>คาบ</span></div>
      <div className="info">
        <div className="s1">{entry.subject}</div>
        <div className="s2">
          <span className="num" style={{color:'var(--brand-600)',fontWeight:500}}>{entry.code}</span>
          <span className="c">ชั้น {entry.className}</span>
          <span style={{color:'var(--ink-3)'}}>{entry.time}</span>
        </div>
      </div>
      {children}
    </div>
  );
}

function ApprovalStepper({approval}){
  if(!approval) return null;
  const labels = {deputy_academic:'รองฯ วิชาการ', deputy_personnel:'รองฯ บุคคล', director:'ผู้อำนวยการ'};
  const stLabel = {pending:'รอพิจารณา', approved:'ผ่าน', rejected:'ไม่อนุญาต'};
  return (
    <div className="appr-steps">
      {approval.chain.map((s,i)=>{
        const cur = approval.final==='pending' && approval.current===i;
        return (
          <React.Fragment key={i}>
            <div className={`as-node ${s.status} ${cur?'cur':''}`}>
              <span className="as-ic">{s.status==='approved'?'✓':s.status==='rejected'?'✕':i+1}</span>
              <span className="as-lb">{labels[s.role]}</span>
              <span className="as-st">{cur?'กำลังพิจารณา':stLabel[s.status]}</span>
            </div>
            {i<approval.chain.length-1 && <span className={`as-bar ${s.status==='approved'?'on':''}`}/>}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// ---- Makeup slot picker ----
// เลือกวัน/คาบที่ครูสอนแทนมีคาบในห้องเดียวกัน เพื่อให้สลับคาบกันได้โดยไม่กระทบตารางนักเรียน
function MakeupPicker({schedules, substituteId, leaveDate, className, value, onPick}){
  const subSched = substituteId ? (schedules[substituteId] || teacherById(substituteId)?.schedule) : null;
  const slots = React.useMemo(()=> findMakeupSlots(subSched, leaveDate || BASE_DATE, className, 30), [subSched, leaveDate, className]);
  const sub = substituteId ? teacherById(substituteId) : null;
  const valueKey = value?.makeupDate && value?.makeupPeriod ? `${value.makeupDate}#${value.makeupPeriod}` : '';

  if(!substituteId){
    return (
      <div className="inp" style={{display:'flex',alignItems:'center',color:'var(--ink-3)',background:'var(--bg-2)',fontSize:13}}>
        <Icon name="info" size={15} style={{marginRight:6}}/>เลือกครูสอนแทนก่อน เพื่อจับคู่คาบสอนชดเชยตามตารางของท่าน
      </div>
    );
  }
  if(slots.length===0){
    return (
      <div className="inp" style={{display:'flex',alignItems:'center',color:'var(--amber)',background:'var(--amber-bg)',borderColor:'var(--amber-line)',fontSize:13}}>
        <Icon name="info" size={15} style={{marginRight:6}}/>ไม่พบคาบที่ {sub?fullTitle(sub):'ครูสอนแทน'} สอนชั้น {className} ใน 30 วันทำการข้างหน้า — กรุณานัดหมายกันเอง
      </div>
    );
  }
  return (
    <select className="sel" value={valueKey} onChange={e=>{
      const v = e.target.value;
      if(!v){ onPick({makeupDate:'', makeupPeriod:0}); return; }
      const [iso,p] = v.split('#');
      onPick({makeupDate:iso, makeupPeriod:+p});
    }}>
      <option value="">— เลือกคาบสอนชดเชย —</option>
      {slots.map(s=>(
        <option key={`${s.iso}#${s.period}`} value={`${s.iso}#${s.period}`}>
          {`วัน${s.day}ที่ ${formatThaiDate(s.iso)} · คาบ ${s.period}${s.time?` (${s.time})`:''}`}
        </option>
      ))}
    </select>
  );
}

Object.assign(window, {
  Icon, Avatar, Card, CardHead, Btn, StatusBadge, ReasonTag, Empty, Toast, PeriodSlot, ApprovalStepper, MakeupPicker,
});
