/* ============================================================
   IMTRACK — Procurement Plan module
   ============================================================ */
(function () {
  const E = window.IMTRACK_ENGINE;
  const { useState } = React;

  function picLabel(store, userIds) {
    if (!userIds || userIds.length === 0) return <span className="dash">—</span>;
    return userIds.map((uid) => {
      const u = store.users.find((u) => u.id === uid);
      return u ? u.name : uid;
    }).join(', ');
  }

  function picBadges(store, userIds) {
    if (!userIds || userIds.length === 0) return <span className="dash">—</span>;
    return userIds.map((uid) => {
      const u = store.users.find((u) => u.id === uid);
      return u
        ? <span key={uid} className="badge badge-user" title={u.email} style={{ marginRight: 4 }}>{u.initials} {u.name}</span>
        : null;
    });
  }

  function userName(store, uid) {
    if (!uid) return '—';
    const u = store.users.find((u) => u.id === uid);
    return u ? u.name : uid;
  }

  function formatDt(dt) {
    if (!dt) return '—';
    return new Date(dt).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' });
  }
  function daysSince(dt) {
    if (!dt) return null;
    return Math.floor((Date.now() - new Date(dt).getTime()) / 86400000);
  }

  function ProcurementModule() {
    const ctx = window.useStore();
    const { store, navigate, can, currentUser } = ctx;
    const toast = window.useToast();
    const [q, setQ] = useState('');
    const [fCode, setFCode] = useState('');
    const [fMethod, setFMethod] = useState('');
    const [fPr, setFPr] = useState('');
    const [fTs, setFTs] = useState('');
    const [fEntity, setFEntity] = useState('');
    const [fDept, setFDept] = useState('');
    const [fImported, setFImported] = useState(false);
    const [sort, setSort] = useState({ col: 'ppNo', dir: 'asc' });
    const [linkOpen, setLinkOpen] = useState(null);
    const [linkTarget, setLinkTarget] = useState('');
    const [editId, setEditId] = useState(null);
    const [editData, setEditData] = useState(null);
    const [deleteConfirm, setDeleteConfirm] = useState(null);

    const badgeRetentionDays = (store.systemConfig || {}).badgeRetentionDays || 14;

    let rows = store.procurementPlan.filter((p) => {
      if (p.deletedAt) return false;
      if (q && !(p.title.toLowerCase().includes(q.toLowerCase()) || p.ppNo.toLowerCase().includes(q.toLowerCase()))) return false;
      if (fCode && p.code !== fCode) return false;
      if (fMethod && p.method !== fMethod) return false;
      if (fPr && p.prStatus !== fPr) return false;
      if (fTs && p.tenderStatus !== fTs) return false;
      if (fEntity && p.entityId !== fEntity) return false;
      if (fDept && p.departmentId !== fDept) return false;
      if (fImported) {
        if (!p.importedAt) return false;
        const days = daysSince(p.importedAt);
        if (days === null || days > badgeRetentionDays) return false;
      }
      return true;
    });
    rows = window.sortRows(rows, sort, { ppNo: (p) => p.ppNo, title: (p) => p.title, estValue: (p) => p.estValue, contractStart: (p) => p.contractStart });
    if (currentUser && currentUser.entityScope !== 'all') rows = rows.filter((p) => (currentUser.entityScope || []).includes(p.entityId));
    if (currentUser && currentUser.departmentScope !== 'all') rows = rows.filter((p) => (currentUser.departmentScope || []).includes(p.departmentId));

    const doExport = () => {
      window.exportCsv('imtrack_procurement_plan.csv',
        ['ProcPlan No', 'Title', 'Method', 'Code', 'Est Value', 'Currency', 'Est Start', 'Est End', 'PIC', 'Tender Status', 'PR Number', 'PR Status', 'Linked Contract', 'Tender Document'],
        rows.map((p) => [p.ppNo, p.title, E.lkLabel(store, 'procMethod', p.method), E.lkLabel(store, 'procPlanCode', p.code), p.estValue, p.cur, p.contractStart, p.contractEnd, picLabel(store, p.pic), E.lkLabel(store, 'tenderStatus', p.tenderStatus), p.pr, E.lkLabel(store, 'prStatus', p.prStatus), p.linkedContract ? (store.contracts.find((c) => c.id === p.linkedContract) || {}).no : '', p.tenderDocLink || '']));
      toast('Exported ' + rows.length + ' procurement plan records', 'good');
    };

    const doLink = () => {
      if (!linkTarget) { toast('Select a contract to link', 'warn'); return; }
      ctx.actions.updateProcPlan(linkOpen, { linkedContract: linkTarget });
      toast('Linked to contract ' + (store.contracts.find((c) => c.id === linkTarget) || {}).no, 'good');
      setLinkOpen(null);
      setLinkTarget('');
    };

    const doUnlink = (id) => {
      if (!confirm('Unlink this procurement plan record from its contract?')) return;
      ctx.actions.updateProcPlan(id, { linkedContract: null });
      toast('Contract link removed', 'good');
    };

    return (
      <div className="page page-wide">
        <PageHeader title="Procurement Plan" subtitle={rows.length + ' pre-award pipeline records'}>
          {can('procurement', 'import') && <button className="btn btn-secondary" onClick={() => navigate('import', { back: 'procurement', type: 'pp' })}><Icon name="upload" size={16} />Import</button>}
          <button className="btn btn-secondary" onClick={doExport}><Icon name="download" size={16} />Export CSV</button>
        </PageHeader>
        <div className="filterbar">
          <div className="search-box"><Icon name="search" size={15} /><input className="input" placeholder="Search title, ProcPlan no…" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 260 }} /></div>
          <select className="select" value={fCode} onChange={(e) => setFCode(e.target.value)}><option value="">All codes</option>{store.lookups.procPlanCode.map((s) => <option key={s.id} value={s.id}>{s.code} · {s.label}</option>)}</select>
          <select className="select" value={fMethod} onChange={(e) => setFMethod(e.target.value)}><option value="">All methods</option>{store.lookups.procMethod.map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select>
          <select className="select" value={fPr} onChange={(e) => setFPr(e.target.value)}><option value="">All PR statuses</option>{store.lookups.prStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select>
          <select className="select" value={fTs} onChange={(e) => setFTs(e.target.value)}><option value="">All tender stages</option>{store.lookups.tenderStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select>
          <select className="select" value={fEntity} onChange={(e) => setFEntity(e.target.value)}><option value="">All entities</option>{store.lookups.entity.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).filter((s) => s.active && (!currentUser || currentUser.entityScope === 'all' || (currentUser.entityScope || []).includes(s.id))).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select>
          <select className="select" value={fDept} onChange={(e) => setFDept(e.target.value)}><option value="">All departments</option>{store.lookups.department.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).filter((s) => s.active && (!currentUser || currentUser.departmentScope === 'all' || (currentUser.departmentScope || []).includes(s.id))).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select>
          <label className="toggle-label" style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, whiteSpace: 'nowrap' }}>
            <input type="checkbox" checked={fImported} onChange={(e) => setFImported(e.target.checked)} />
            Show Imported Only
          </label>
        </div>
        <div className="card" style={{ overflow: 'hidden' }}>
          <div className="tbl-wrap">
            <table className="tbl tbl-compact">
              <thead style="position: sticky; top: 0; z-index: 1; background: var(--bg-default)"><tr>
                <SortHead label="ProcPlan No" col="ppNo" sort={sort} setSort={setSort} />
                <SortHead label="Tender / Contract Title" col="title" sort={sort} setSort={setSort} />
                <th>Method</th><th>Code</th>
                <SortHead label="Est Value" col="estValue" sort={sort} setSort={setSort} numeric />
                <th>Cur</th>
                <SortHead label="Est Start" col="contractStart" sort={sort} setSort={setSort} />
                <th>Est End</th><th>PIC</th><th>Tender Stage</th><th>PR Number</th><th>PR Status</th><th>Tender Doc</th><th>Contract</th><th style={{ width: 60 }}></th>
              </tr></thead>
              <tbody>
                {rows.map((p) => {
                  const lc = p.linkedContract ? store.contracts.find((c) => c.id === p.linkedContract) : null;
                  return (
                    <tr key={p.id} id={'pprow-' + p.id}>
                      <td className="mono">
                        {p.ppNo}
                        {p.importedAt && <SourceBadge source="import" />}
                      </td>
                      <td style={{ maxWidth: 240, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={p.title}>{p.title}</td>
                      <td><StatusBadge store={store} list="procMethod" id={p.method} /></td>
                      <td><StatusBadge store={store} list="procPlanCode" id={p.code} dot /></td>
                      <td className="num-col"><Money v={p.estValue} cur={p.cur} /></td>
                      <td>{p.cur}</td>
                      <td className="num" style={{ fontSize: 12 }}>{p.contractStart || '—'}</td>
                      <td className="num" style={{ fontSize: 12 }}>{p.contractEnd || '—'}</td>
                      <td style={{ maxWidth: 160, overflow: 'hidden' }}>{picBadges(store, p.pic)}</td>
                      <td>{can('procurement', 'edit') && !p.deletedAt
                        ? <select className="select" style={{ height: 26, fontSize: 11, minWidth: 135 }} value={p.tenderStatus || ''}
                            onChange={(e) => { ctx.actions.updateProcPlan(p.id, { tenderStatus: e.target.value, updatedBy: 'u1', updatedAt: new Date().toISOString(), version: (p.version || 1) + 1 }); toast('Tender Stage → ' + E.lkLabel(store, 'tenderStatus', e.target.value), 'good'); }}>
                            {store.lookups.tenderStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).filter((s) => s.active).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}
                          </select>
                        : <StatusBadge store={store} list="tenderStatus" id={p.tenderStatus} />}</td>
                      <td className="mono" style={{ fontSize: 12 }}>{p.pr || <span className="dash">—</span>}</td>
                      <td>{can('procurement', 'edit') && !p.deletedAt
                        ? <select className="select" style={{ height: 26, fontSize: 11, minWidth: 145 }} value={p.prStatus || ''}
                            onChange={(e) => { ctx.actions.updateProcPlan(p.id, { prStatus: e.target.value, updatedBy: 'u1', updatedAt: new Date().toISOString(), version: (p.version || 1) + 1 }); toast('PR Status → ' + E.lkLabel(store, 'prStatus', e.target.value), 'good'); }}>
                            {store.lookups.prStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}
                          </select>
                        : <StatusBadge store={store} list="prStatus" id={p.prStatus} />}</td>
                      <td>{p.tenderDocLink ? <span className="link" onClick={() => window.open(p.tenderDocLink, '_blank', 'noopener,noreferrer')}><Icon name="external-link" size={13} />Open</span> : <span className="dash">—</span>}</td>
                      <td>
                        {lc
                          ? <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                              <span className="link" title={lc.no + ' · ' + lc.vendor} onClick={() => navigate('contract', { id: lc.id })}><Icon name="link-2" size={14} /> {lc.no}</span>
                              {can('procurement', 'edit') && <button className="btn btn-ghost btn-sm" style={{ padding: '1px 4px', fontSize: 10, lineHeight: 1.2 }} onClick={() => doUnlink(p.id)} title="Unlink contract"><Icon name="x" size={12} /></button>}
                            </span>
                          : can('procurement', 'edit')
                            ? <button className="btn btn-ghost btn-sm" style={{ padding: '2px 6px', fontSize: 11 }} onClick={() => { setLinkOpen(p.id); setLinkTarget(''); }}><Icon name="link-2" size={12} />Link</button>
                            : <span className="dash">—</span>}
                      </td>
                      <td style={{ whiteSpace: 'nowrap' }}>
                        {can('procurement', 'edit') && <button className="btn btn-ghost btn-sm" style={{ padding: '2px 5px', fontSize: 11 }} onClick={() => { setEditId(p.id); setEditData({ ...p }); }} title="Edit"><Icon name="pencil" size={12} /></button>}
                        {can('procurement', 'delete') && <button className="btn btn-ghost btn-sm" style={{ padding: '2px 5px', fontSize: 11 }} onClick={() => setDeleteConfirm(p)} title="Soft delete"><Icon name="trash-2" size={12} /></button>}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
            {rows.length === 0 && <EmptyState icon="clipboard-list" title="No procurement records match" sub="Adjust filters or import the latest Procurement Plan export." />}
          </div>
          <div className="table-meta"><span>{rows.length} rows</span><span>Unlinked records have no matching contract yet</span></div>
        </div>

        {linkOpen && <Modal title="Link to Contract" subtitle="Associate this procurement plan record with an awarded contract" onClose={() => setLinkOpen(null)}
          footer={<><button className="btn btn-secondary" onClick={() => setLinkOpen(null)}>Cancel</button><button className="btn btn-primary" onClick={doLink}>Link contract</button></>}>
          <Field label="Contract" req>
            <Select value={linkTarget} onChange={setLinkTarget} placeholder="Select contract…" options={store.contracts.filter((c) => { const already = store.procurementPlan.find((p) => p.linkedContract === c.id); return !already || already.id === linkOpen; }).map((c) => ({ value: c.id, label: c.no + ' · ' + c.vendor }))} />
          </Field>
        </Modal>}

        {editId && editData && <Modal title="Edit Procurement Record" subtitle={editData.ppNo} onClose={() => { setEditId(null); setEditData(null); }}
          footer={<><button className="btn btn-secondary" onClick={() => { setEditId(null); setEditData(null); }}>Cancel</button><button className="btn btn-primary" onClick={() => { ctx.actions.updateProcPlan(editId, { title: editData.title, scope: editData.scope, estValue: editData.estValue, remarks: editData.remarks, prStatus: editData.prStatus, tenderStatus: editData.tenderStatus, tenderDocLink: editData.tenderDocLink, linkedContract: editData.linkedContract, pic: editData.pic, updatedBy: ctx.currentUser ? ctx.currentUser.id : 'u1', updatedAt: new Date().toISOString(), version: (editData.version || 1) + 1 }); toast('Record updated', 'good'); setEditId(null); setEditData(null); }}>Save</button></>}>
          <Field label="ProcPlan No"><span className="mono">{editData.ppNo}</span></Field>
          <Field label="Title"><input className="input" value={editData.title} onChange={(e) => setEditData({ ...editData, title: e.target.value })} /></Field>
          <Field label="Brief Scope"><input className="input" value={editData.scope} onChange={(e) => setEditData({ ...editData, scope: e.target.value })} /></Field>
          <Field label="Est Value"><input className="input" type="number" value={editData.estValue} onChange={(e) => setEditData({ ...editData, estValue: Number(e.target.value) })} /></Field>
          <Field label="Linked Contract">
            <select className="select" value={editData.linkedContract || ''} onChange={(e) => setEditData({ ...editData, linkedContract: e.target.value || null })}>
              <option value="">— Unlinked —</option>
              {store.contracts.map((c) => <option key={c.id} value={c.id}>{c.no} · {c.vendor}</option>)}
            </select>
          </Field>
          <Field label="PIC"><input className="input" value={(editData.pic || []).join(', ')} onChange={(e) => setEditData({ ...editData, pic: e.target.value.split(',').map((s) => s.trim()).filter(Boolean) })} placeholder="u1, u3" /></Field>
          <Field label="PR Status"><select className="select" value={editData.prStatus || ''} onChange={(e) => setEditData({ ...editData, prStatus: e.target.value })}><option value="">—</option>{store.lookups.prStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select></Field>
          <Field label="Tender Stage"><select className="select" value={editData.tenderStatus || ''} onChange={(e) => setEditData({ ...editData, tenderStatus: e.target.value })}><option value="">—</option>{store.lookups.tenderStatus.sort((a,b)=> (a.sort_order||99)-(b.sort_order||99)).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select></Field>
          <Field label="Tender Document Link"><input className="input mono" value={editData.tenderDocLink || ''} onChange={(e) => setEditData({ ...editData, tenderDocLink: e.target.value })} placeholder="https://epcms.company.internal/tender/..." /></Field>
          <Field label="Remarks"><textarea className="input" rows={3} value={editData.remarks} onChange={(e) => setEditData({ ...editData, remarks: e.target.value })} /></Field>
          <div className="hr" style={{ margin: '12px 0' }} />
          <div style={{ fontSize: 11, color: 'var(--text-muted)', lineHeight: 1.6 }}>
            <div>Created by <strong>{userName(store, editData.createdBy)}</strong> on {formatDt(editData.createdAt)}</div>
            <div>Last updated by <strong>{userName(store, editData.updatedBy)}</strong> on {formatDt(editData.updatedAt)}</div>
            {editData.importedAt && <div>Imported on {formatDt(editData.importedAt)}</div>}
            <div className="mt4" style={{ fontSize: 10, color: 'var(--color-slate-400)' }}>Version {editData.version} · ID: {editData.id}</div>
          </div>
        </Modal>}

        {deleteConfirm && <Modal title="Soft Delete Procurement Record" subtitle={deleteConfirm.ppNo || ''} onClose={() => setDeleteConfirm(null)}
          footer={<><button className="btn btn-secondary" onClick={() => setDeleteConfirm(null)}>Cancel</button><button className="btn btn-destructive" onClick={() => { ctx.actions.updateProcPlan(deleteConfirm.id, { deletedAt: new Date().toISOString() }); toast('Record soft-deleted. Admin can recover within ' + ((store.systemConfig || {}).recoveryWindowDays || 7) + ' days.', 'warn'); setDeleteConfirm(null); }}>Soft delete</button></>}>
          <p style={{ fontSize: 13, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
            This record will be soft-deleted and hidden from the list. An Admin can recover it within {(store.systemConfig || {}).recoveryWindowDays || 7} days from the Recently Deleted view in Settings.
          </p>
        </Modal>}
      </div>
    );
  }

  window.ProcurementModule = ProcurementModule;
})();
