/* Shared job parts: summaries, filters, job card/row, detail modal, page header */

// ---------- item / summary helpers ----------
function unitWord(productId){ return productId === 'air' ? 'ชุด' : 'เครื่อง'; }

function itemLine(it){
  const p = CK.product(it.p);
  const btu = it.btu ? ` ${it.btu} BTU` : '';
  return `${p?p.th:'สินค้า'}${btu}${it.model?` ${it.model}`:''} ${it.qty||1} ${unitWord(it.p)}`;
}
function itemsShort(items){
  return items.map(it => {
    const p = CK.product(it.p);
    const btu = it.btu ? ` ${it.btu}` : '';
    return `${p?p.th:''}${btu} ×${it.qty||1}`;
  }).join(', ');
}

// summary grouped by jobType + product
function computeSummary(jobs){
  const map = new Map();
  let totalUnits = 0;
  jobs.forEach(j => {
    const jt = CK.jobType(j.jobType);
    j.items.forEach(it => {
      const p = CK.product(it.p);
      const key = j.jobType + '|' + it.p;
      const label = (jt?jt.th:'') + (p?p.th:'');
      const qty = (it.qty||1);
      const prev = map.get(key) || { label, qty:0, unit:unitWord(it.p) };
      prev.qty += qty; map.set(key, prev);
    });
    totalUnits += CK.jobUnits(j);
  });
  const lines = [...map.values()].sort((a,b)=>b.qty-a.qty);
  return { lines, totalJobs: jobs.length, totalUnits: Math.round(totalUnits*10)/10 };
}

// ---------- filtering ----------
function applyFilters(jobs, f){
  return jobs.filter(j => {
    if (f.date && j.date !== f.date) return false;
    if (f.branch && j.branch !== f.branch) return false;
    if (f.district && j.district !== f.district) return false;
    if (f.jobType && j.jobType !== f.jobType) return false;
    if (f.product && !j.items.some(it=>it.p===f.product)) return false;
    if (f.status && j.status !== f.status) return false;
    if (f.team && j.team !== f.team) return false;
    if (f.q){
      const q = f.q.toLowerCase();
      const hay = [j.customer, j.phone, j.district, j.code, ...j.items.map(i=>i.model||''), ...j.items.map(i=>i.brand||'')].join(' ').toLowerCase();
      if (!hay.includes(q)) return false;
    }
    return true;
  });
}

// ---------- Filter bar ----------
function FilterBar({ value, onChange, show=['q','branch','district','jobType','status','team'] }){
  const set = (k,v) => onChange({ ...value, [k]: v || undefined });
  const selCls = 'rounded-xl ring-1 ring-slate-300 bg-white px-3 py-2 text-[13px] font-light text-slate-700 focus:outline-none focus:ring-2 focus:ring-brand-500';
  const active = Object.entries(value).filter(([k,v])=>v && k!=='date').length;
  return (
    <div className="flex flex-wrap items-center gap-2">
      {show.includes('q') && (
        <div className="relative flex-1 min-w-[200px]">
          <span className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"><Icon name="Search" size={16} /></span>
          <input value={value.q||''} onChange={e=>set('q', e.target.value)} placeholder="ค้นหา ชื่อลูกค้า / เบอร์ / รุ่น"
            className="w-full rounded-xl ring-1 ring-slate-300 bg-white pl-9 pr-3 py-2 text-[13px] font-light focus:outline-none focus:ring-2 focus:ring-brand-500" />
        </div>
      )}
      {show.includes('branch') && (
        <select className={selCls} value={value.branch||''} onChange={e=>set('branch', e.target.value)}>
          <option value="">ทุกสาขา</option>
          {CK.BRANCHES.map(b=><option key={b.id} value={b.id}>{b.code} {b.name}</option>)}
        </select>
      )}
      {show.includes('district') && (
        <select className={selCls} value={value.district||''} onChange={e=>set('district', e.target.value)}>
          <option value="">ทุกอำเภอ</option>
          {CK.DISTRICTS.map(d=><option key={d} value={d}>อ.{d}</option>)}
        </select>
      )}
      {show.includes('jobType') && (
        <select className={selCls} value={value.jobType||''} onChange={e=>set('jobType', e.target.value)}>
          <option value="">ทุกประเภทงาน</option>
          {CK.JOB_TYPES.map(t=><option key={t.id} value={t.id}>{t.th}</option>)}
        </select>
      )}
      {show.includes('status') && (
        <select className={selCls} value={value.status||''} onChange={e=>set('status', e.target.value)}>
          <option value="">ทุกสถานะ</option>
          {Object.values(CK.STATUS).map(s=><option key={s.key} value={s.key}>{s.th}</option>)}
        </select>
      )}
      {show.includes('team') && (
        <select className={selCls} value={value.team||''} onChange={e=>set('team', e.target.value)}>
          <option value="">ทุกทีมช่าง</option>
          {CK.TEAMS.map(t=><option key={t.id} value={t.id}>{t.name}</option>)}
        </select>
      )}
      {active>0 && (
        <button onClick={()=>onChange({ date:value.date })} className="inline-flex items-center gap-1 text-[13px] text-slate-500 hover:text-brand-700 px-2 py-2">
          <Icon name="X" size={14} /> ล้าง ({active})
        </button>
      )}
    </div>
  );
}

// ---------- Urgency / product icon ----------
function ProductIcon({ p, size=16, className='' }){
  const prod = CK.product(p);
  return <Icon name={prod?prod.icon:'Package'} size={size} className={className} />;
}

// ---------- Job card (mobile + card layout) ----------
function JobCard({ job, onOpen, seq }){
  const b = CK.branch(job.branch); const jt = CK.jobType(job.jobType); const team = CK.team(job.team);
  return (
    <Card as="button" onClick={onOpen} className="w-full text-left p-3.5 hover:ring-brand-300 transition">
      <div className="flex items-start gap-3">
        <div className="flex flex-col items-center gap-2 shrink-0">
          {seq!=null && <span className="grid place-items-center w-7 h-7 rounded-lg bg-slate-900 text-white text-[13px] font-medium tnum">{seq}</span>}
          <span className="grid place-items-center w-10 h-10 rounded-xl bg-brand-50 text-brand-600"><ProductIcon p={job.items[0]?.p} size={20} /></span>
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2 flex-wrap">
            <span className="text-[15px] font-medium text-slate-800 truncate">{job.customer}</span>
            {job.urgency==='urgent' && <span className="inline-flex items-center gap-1 text-[10px] font-normal text-brand-700 bg-brand-100 ring-1 ring-brand-200 rounded-full px-1.5 py-0.5"><Icon name="Flame" size={11}/>ด่วน</span>}
          </div>
          <div className="flex items-center gap-1.5 text-[12px] font-light text-slate-500 mt-0.5">
            <Icon name="MapPin" size={13} /> อ.{job.district}
            <span className="text-slate-300">•</span>
            <span className="inline-flex items-center gap-1 text-slate-600">{b?.code}</span>
            <span className="text-slate-300">•</span>
            <Icon name="Clock" size={13} /> {job.slot}
          </div>
          <div className="mt-2 flex items-center gap-2 flex-wrap">
            <span className="inline-flex items-center gap-1 text-[12px] font-normal text-slate-700 bg-slate-100 rounded-lg px-2 py-1">
              <Icon name={jt?jt.icon:'Wrench'} size={13} /> {jt?.th}
            </span>
            <span className="text-[12px] font-light text-slate-500">{itemsShort(job.items)}</span>
          </div>
          {job.routeNote && (
            <div className="mt-2 flex items-start gap-1.5 text-[11px] font-light text-amber-700 bg-amber-50 rounded-lg px-2 py-1">
              <Icon name="Info" size={12} className="mt-0.5 shrink-0" /> {job.routeNote}
            </div>
          )}
          <div className="mt-2.5 flex items-center justify-between gap-2">
            <StatusBadge status={job.status} />
            {team
              ? <span className="inline-flex items-center gap-1 text-[11px] font-light text-slate-500"><span className="w-2 h-2 rounded-full" style={{background:team.color}}/>{team.name.split('—')[0].trim()}</span>
              : <span className="text-[11px] font-light text-slate-400">ยังไม่มอบหมาย</span>}
          </div>
        </div>
      </div>
    </Card>
  );
}

// ---------- Job row (table layout) ----------
function JobRow({ job, seq, onOpen }){
  const b = CK.branch(job.branch); const jt = CK.jobType(job.jobType); const team = CK.team(job.team);
  return (
    <tr onClick={onOpen} className="border-b border-slate-100 hover:bg-brand-50/40 cursor-pointer">
      <td className="px-3 py-2.5 text-center text-slate-400 tnum text-[13px]">{seq}</td>
      <td className="px-3 py-2.5">
        <div className="flex items-center gap-1.5 text-[14px] text-slate-800 font-normal">
          {job.urgency==='urgent' && <span className="text-brand-600"><Icon name="Flame" size={13}/></span>}
          {job.customer}
        </div>
        <div className="text-[12px] font-light text-slate-400">{job.phone}</div>
      </td>
      <td className="px-3 py-2.5 text-[13px] font-light text-slate-600">อ.{job.district}</td>
      <td className="px-3 py-2.5 text-[13px] font-light text-slate-600">{b?.code}</td>
      <td className="px-3 py-2.5">
        <span className="inline-flex items-center gap-1 text-[13px] text-slate-700"><Icon name={jt?jt.icon:'Wrench'} size={13}/>{jt?.th}</span>
      </td>
      <td className="px-3 py-2.5 text-[13px] font-light text-slate-600">{itemsShort(job.items)}</td>
      <td className="px-3 py-2.5 text-[13px] font-light text-slate-600 whitespace-nowrap">{job.slot}</td>
      <td className="px-3 py-2.5"><StatusBadge status={job.status} /></td>
      <td className="px-3 py-2.5 text-[12px] font-light text-slate-600 whitespace-nowrap">
        {team ? <span className="inline-flex items-center gap-1"><span className="w-2 h-2 rounded-full" style={{background:team.color}}/>{team.name.split('—')[0].trim()}</span> : <span className="text-slate-300">—</span>}
      </td>
    </tr>
  );
}

// ---------- Page header (desktop) ----------
function PageHeader({ icon, title, sub, children }){
  return (
    <div className="flex flex-wrap items-end justify-between gap-3 mb-5">
      <div className="flex items-center gap-3">
        {icon && <span className="grid place-items-center w-11 h-11 rounded-2xl bg-brand-600 text-white shadow-sm"><Icon name={icon} size={22} /></span>}
        <div>
          <h1 className="text-[22px] font-medium text-slate-900 leading-tight">{title}</h1>
          {sub && <p className="text-[13px] font-light text-slate-500">{sub}</p>}
        </div>
      </div>
      {children && <div className="flex items-center gap-2">{children}</div>}
    </div>
  );
}

// ---------- Summary bar ----------
function SummaryBar({ jobs, className='' }){
  const s = computeSummary(jobs);
  return (
    <div className={`flex flex-wrap items-center gap-x-5 gap-y-2 ${className}`}>
      {s.lines.slice(0,6).map((l,i)=>(
        <span key={i} className="inline-flex items-baseline gap-1.5 text-[13px]">
          <span className="font-light text-slate-500">{l.label}</span>
          <span className="font-medium text-slate-800 tnum">{l.qty}</span>
          <span className="font-light text-slate-400">{l.unit}</span>
        </span>
      ))}
      <span className="inline-flex items-baseline gap-1.5 text-[13px] ml-auto">
        <span className="font-light text-slate-500">งานทั้งหมด</span>
        <span className="font-medium text-brand-700 tnum text-[15px]">{s.totalJobs}</span>
        <span className="font-light text-slate-400">งาน</span>
        <span className="text-slate-300 mx-1">·</span>
        <span className="font-light text-slate-500">โหลด</span>
        <span className="font-medium text-slate-800 tnum">{s.totalUnits}</span>
        <span className="font-light text-slate-400">unit</span>
      </span>
    </div>
  );
}

// ---------- Job detail modal ----------
function InfoRow({ icon, label, children }){
  return (
    <div className="flex items-start gap-2.5 py-1.5">
      <span className="text-slate-400 mt-0.5"><Icon name={icon} size={15} /></span>
      <span className="text-[12px] font-light text-slate-400 w-20 shrink-0 mt-0.5">{label}</span>
      <span className="text-[13px] font-normal text-slate-700 flex-1">{children}</span>
    </div>
  );
}

function JobDetailModal({ jobId, onClose }){
  const { jobs, setStatus, assign, role } = useCK();
  const job = jobs.find(j=>j.id===jobId);
  const [note,setNote] = React.useState('');
  const [pickStatus,setPickStatus] = React.useState(false);
  if (!job) return null;
  const b = CK.branch(job.branch); const jt = CK.jobType(job.jobType); const team = CK.team(job.team);
  const idx = CK.STATUS_FLOW.indexOf(job.status);
  const nextStatus = idx>=0 && idx < CK.STATUS_FLOW.length-1 ? CK.STATUS_FLOW[idx+1] : null;
  const canEditStatus = ['hq','admin','tech'].includes(role);

  return (
    <Modal open onClose={onClose} maxW="max-w-xl"
      title={null}>
      <div className="px-5 py-4 border-b border-slate-100 flex items-start justify-between gap-3 sticky top-0 bg-white z-10">
        <div className="flex items-center gap-3">
          <span className="grid place-items-center w-11 h-11 rounded-2xl bg-brand-50 text-brand-600"><ProductIcon p={job.items[0]?.p} size={22} /></span>
          <div>
            <div className="flex items-center gap-2">
              <h3 className="text-[17px] font-medium text-slate-900">{job.customer}</h3>
              {job.urgency==='urgent' && <span className="inline-flex items-center gap-1 text-[10px] font-normal text-brand-700 bg-brand-100 ring-1 ring-brand-200 rounded-full px-1.5 py-0.5"><Icon name="Flame" size={11}/>ด่วน</span>}
            </div>
            <div className="text-[12px] font-light text-slate-400 font-mono">{job.code} · {CK.thDate(job.date,{withDow:true})}</div>
          </div>
        </div>
        <button onClick={onClose} className="text-slate-400 hover:text-slate-700"><Icon name="X" size={20} /></button>
      </div>

      <div className="p-5 space-y-5">
        <div className="flex items-center justify-between gap-2 flex-wrap">
          <StatusBadge status={job.status} size="md" />
          <div className="flex items-center gap-2">
            <a href={'tel:'+job.phone} className="inline-flex items-center gap-1.5 rounded-xl bg-green-50 text-green-700 ring-1 ring-green-200 px-3 py-1.5 text-[13px] hover:bg-green-100"><Icon name="Phone" size={14}/>โทร</a>
            <button className="inline-flex items-center gap-1.5 rounded-xl bg-blue-50 text-blue-700 ring-1 ring-blue-200 px-3 py-1.5 text-[13px] hover:bg-blue-100"><Icon name="Map" size={14}/>แผนที่</button>
          </div>
        </div>

        <div className="grid sm:grid-cols-2 gap-x-6 gap-y-1">
          <div>
            <div className="text-[12px] font-medium text-slate-500 mb-1">ข้อมูลลูกค้า</div>
            <InfoRow icon="Phone" label="เบอร์โทร">{job.phone}</InfoRow>
            <InfoRow icon="MapPin" label="ที่อยู่">{job.addr}</InfoRow>
            {job.routeNote && <InfoRow icon="Info" label="เส้นทาง"><span className="text-amber-700">{job.routeNote}</span></InfoRow>}
          </div>
          <div>
            <div className="text-[12px] font-medium text-slate-500 mb-1">นัดหมาย</div>
            <InfoRow icon="Clock" label="ช่วงเวลา">{job.slot}</InfoRow>
            <InfoRow icon="Store" label="สาขา">{b?.code} {b?.name}</InfoRow>
            <InfoRow icon="UserRound" label="ผู้บันทึก">{job.createdBy}</InfoRow>
          </div>
        </div>

        <div>
          <div className="text-[12px] font-medium text-slate-500 mb-2">รายการสินค้า / งาน</div>
          <div className="rounded-xl ring-1 ring-slate-200 divide-y divide-slate-100">
            {job.items.map((it,i)=>(
              <div key={i} className="flex items-center gap-3 px-3 py-2.5">
                <span className="grid place-items-center w-8 h-8 rounded-lg bg-slate-100 text-slate-500"><ProductIcon p={it.p} size={16}/></span>
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] text-slate-700">{itemLine(it)}</div>
                  <div className="text-[11px] font-light text-slate-400">{it.brand} {jt?('· '+jt.th):''}</div>
                </div>
                <span className="text-[13px] font-medium text-slate-700 tnum">×{it.qty||1}</span>
              </div>
            ))}
          </div>
        </div>

        {/* Attachments */}
        <div>
          <div className="text-[12px] font-medium text-slate-500 mb-2">ไฟล์แนบ</div>
          <div className="grid grid-cols-4 gap-2">
            <PhotoSlot label="ใบงาน" filled={job.prepared} h={70} />
            <PhotoSlot label="ใบเสร็จ" filled={job.prepared} h={70} />
            <PhotoSlot label="ใบรับประกัน" h={70} />
            <PhotoSlot label="หน้างาน" filled={job.status==='completed'} h={70} />
          </div>
        </div>

        {/* Assign team */}
        {['hq','admin'].includes(role) && (
          <div>
            <div className="text-[12px] font-medium text-slate-500 mb-2">ทีมช่าง</div>
            <div className="flex flex-wrap gap-2">
              {CK.TEAMS.map(t=>(
                <button key={t.id} onClick={()=>assign(job.id,t.id)}
                  className={`inline-flex items-center gap-2 rounded-xl px-3 py-2 text-[13px] ring-1 transition ${job.team===t.id?'bg-slate-900 text-white ring-slate-900':'bg-white text-slate-600 ring-slate-300 hover:bg-slate-50'}`}>
                  <span className="w-2.5 h-2.5 rounded-full" style={{background:t.color}}/>{t.name.split('—')[0].trim()}
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Status timeline */}
        <div>
          <div className="text-[12px] font-medium text-slate-500 mb-2">ประวัติสถานะ</div>
          <div className="space-y-0">
            {(job.log||[]).map((l,i)=>(
              <div key={i} className="flex gap-3">
                <div className="flex flex-col items-center">
                  <span className="w-2.5 h-2.5 rounded-full mt-1.5" style={{background: CK.STATUS[l.to]?.dot||'#cbd5e1'}}/>
                  {i < job.log.length-1 && <span className="w-px flex-1 bg-slate-200 my-1" />}
                </div>
                <div className="pb-3">
                  <div className="text-[13px] text-slate-700">
                    {l.from!=='—' ? <>เปลี่ยน <b className="font-medium">{CK.STATUS[l.from]?.th||l.from}</b> → </> : ''}
                    <b className="font-medium text-slate-800">{CK.STATUS[l.to]?.th||l.to}</b>
                  </div>
                  <div className="text-[11px] font-light text-slate-400">{l.by} · {l.at}{l.note?(' · '+l.note):''}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Sticky action bar */}
      {canEditStatus && (
        <div className="sticky bottom-0 bg-white border-t border-slate-100 p-4 space-y-2.5">
          {pickStatus ? (
            <div className="space-y-2">
              <input value={note} onChange={e=>setNote(e.target.value)} placeholder="หมายเหตุ (ถ้ามี)" className={inputCls + ' text-[13px] py-2'} />
              <div className="flex flex-wrap gap-1.5">
                {Object.values(CK.STATUS).map(s=>(
                  <button key={s.key} onClick={()=>{ setStatus(job.id,s.key,note); setNote(''); setPickStatus(false); }}
                    className={`text-[12px] px-2.5 py-1.5 rounded-lg ring-1 ${s.cls} hover:brightness-95`}>{s.th}</button>
                ))}
              </div>
            </div>
          ) : (
            <div className="flex items-center gap-2">
              {nextStatus && (
                <Btn variant="primary" size="lg" className="flex-1" icon="ArrowRight" onClick={()=>setStatus(job.id,nextStatus)}>
                  เปลี่ยนเป็น "{CK.STATUS[nextStatus].th}"
                </Btn>
              )}
              <Btn variant="outline" size="lg" icon="ListChecks" onClick={()=>setPickStatus(true)}>{nextStatus?'':'เปลี่ยนสถานะ'}</Btn>
            </div>
          )}
        </div>
      )}
    </Modal>
  );
}

// ---------- day capacity status ----------
function computeDayStatus(jobs, date){
  const cap = CK.CAPACITY[date] || { max:10, closed:false };
  const dayJobs = jobs.filter(j=>j.date===date && j.status!=='cancelled');
  const used = Math.round(dayJobs.reduce((s,j)=>s+CK.jobUnits(j),0)*10)/10;
  let status = 'open';
  if (cap.closed) status = 'closed';
  else if (used >= cap.max) status = 'full';
  else if (used >= cap.max*0.8) status = 'almost';
  const air = dayJobs.reduce((s,j)=>s+j.items.filter(i=>i.p==='air').reduce((a,i)=>a+(i.qty||1),0),0);
  const service = dayJobs.filter(j=>j.jobType!=='install').length;
  return { used, max:cap.max, closed:cap.closed, status, count:dayJobs.length, air, service, pct: Math.min(100, Math.round(used/cap.max*100)) };
}

Object.assign(window, {
  unitWord, itemLine, itemsShort, computeSummary, applyFilters, FilterBar, computeDayStatus,
  ProductIcon, JobCard, JobRow, PageHeader, SummaryBar, JobDetailModal, InfoRow,
});
