// Dashboard, Jobs List, Job Detail, Archive, Notifications

const { useState, useMemo, useEffect } = React;

function getById(arr, id) {return arr.find((x) => x.id === id);}
function customerOf(job, data) {return getById(data.CUSTOMERS, job.customerId);}
function engineerOf(job, data) {return getById(data.USERS, (job.engineerIds || [])[0]);}
function approverOf(job, data) {return getById(data.USERS, (job.approverIds || [])[0]);}
function engineersOf(job, data) {return (job.engineerIds || []).map((id) => getById(data.USERS, id)).filter(Boolean);}
function approversOf(job, data) {return (job.approverIds || []).map((id) => getById(data.USERS, id)).filter(Boolean);}

function progressFor(job) {
  const grs = job.groupResults || [];
  const total = grs.length;
  const done = grs.filter((r) => r.status === 'Complete').length;
  const inProg = grs.filter((r) => r.status === 'In Progress').length;
  return { total, done, inProg, pct: total ? Math.round(done / total * 100) : 0 };
}

function isMyJob(job, user) {
  return (job.engineerIds || []).includes(user.id) || job.assignedEngineerId === user.id;
}
function isMyApproval(job, user) {
  return (job.approverIds || []).includes(user.id) || job.approverId === user.id;
}

// stack of avatars (overlapping) for engineer/approver columns
function AvatarStack({ users, size = 22, max = 3 }) {
  const shown = users.slice(0, max);
  const extra = users.length - shown.length;
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center' }}>
      {shown.map((u, i) => (
        <div key={u.id} style={{ marginLeft: i === 0 ? 0 : -6, border: '1.5px solid var(--page-bg)', borderRadius: '50%', lineHeight: 0 }}>
          <Avatar user={u} size={size} />
        </div>
      ))}
      {extra > 0 && (
        <span style={{ marginLeft: 4, fontSize: 10.5, color: 'var(--body-text)', fontWeight: 600 }}>+{extra}</span>
      )}
    </div>
  );
}

// =================== DASHBOARD ===================
function Dashboard({ data, currentUser, onOpenJob, onNewJob, onGoTab }) {
  const myJobs = data.JOBS.filter((j) => isMyJob(j, currentUser) || isMyApproval(j, currentUser));
  const counts = {
    inProgress: data.JOBS.filter((j) => j.status === 'In Progress').length,
    forApproval: data.JOBS.filter((j) => j.status === 'For Approval').length,
    rejected: data.JOBS.filter((j) => j.status === 'Rejected').length,
    approved: data.JOBS.filter((j) => j.status === 'Approved').length
  };
  const isApproverOrAdmin = currentUser.role === 'Approver' || currentUser.role === 'Admin';
  const queue = isApproverOrAdmin ?
  data.JOBS.filter((j) => j.status === 'For Approval') :
  data.JOBS.filter((j) => isMyJob(j, currentUser) && (j.status === 'In Progress' || j.status === 'Rejected' || j.status === 'Planned'));

  return (
    <div>
      <div className="page-header">
        <div>
          <h1>Welcome back, {currentUser.name.split(' ')[0]}</h1>
          <div className="sub">{data.fmtDate(new Date('2026-04-29'))} · Components Lab — AS6171A Counterfeit Risk Mitigation</div>
        </div>
        <div className="actions">
          {(currentUser.role === 'Test Engineer' || currentUser.role === 'Admin') &&
          <button className="btn primary" onClick={onNewJob}>
              <Icon name="plus" size={14} /> New Job
            </button>
          }
        </div>
      </div>

      <div className="stat-grid">
        <div className="stat accent">
          <div className="label">In Progress</div>
          <div className="value">{counts.inProgress}</div>
          <div className="delta">Active test work across the lab</div>
          <div className="ico"><Icon name="flask" size={20} /></div>
        </div>
        <div className="stat">
          <div className="label">For Approval</div>
          <div className="value">{counts.forApproval}</div>
          <div className="delta">{isApproverOrAdmin ? 'Awaiting your review' : 'Pending approver review'}</div>
          <div className="ico" style={{ color: 'var(--amber)' }}><Icon name="clock" size={20} /></div>
        </div>
        <div className="stat">
          <div className="label">Rejected</div>
          <div className="value">{counts.rejected}</div>
          <div className="delta">Returned for revision</div>
          <div className="ico" style={{ color: 'var(--red)' }}><Icon name="reject" size={20} /></div>
        </div>
        <div className="stat">
          <div className="label">Approved · Awaiting Issue</div>
          <div className="value">{counts.approved}</div>
          <div className="delta">Ready to release to customer</div>
          <div className="ico" style={{ color: 'var(--green)' }}><Icon name="check-circle" size={20} /></div>
        </div>
      </div>

      <div className="two-col">
        <div className="card">
          <div className="card-header">
            <h3>{isApproverOrAdmin ? 'Approval queue' : 'My active jobs'}</h3>
            <button className="btn ghost sm" onClick={() => onGoTab('jobs')}>View all <Icon name="arrow-right" size={12} /></button>
          </div>
          <div className="card-body tight">
            {queue.length === 0 ?
            <div className="empty"><div className="big">Nothing waiting</div>You're all caught up.</div> :

            <table className="tbl">
                <thead><tr>
                  <th>Report</th><th>Customer / Part</th><th>Status</th>
                  <th className="num">Progress</th><th>{isApproverOrAdmin ? 'Submitted by' : 'Approver'}</th>
                </tr></thead>
                <tbody>
                  {queue.map((j) => {
                  const p = progressFor(j);
                  const cust = customerOf(j, data);
                  const eng = engineerOf(j, data);
                  const apv = approverOf(j, data);
                  return (
                    <tr key={j.id} className="row-clickable" onClick={() => onOpenJob(j.id)}>
                        <td>
                          <div className="lead">{j.reportNumber}</div>
                          <div style={{ fontSize: 10.5, color: 'var(--body-text)', marginTop: 2 }}>Ref {j.customerJobRef}</div>
                        </td>
                        <td>
                          <div className="lead">{cust.name}</div>
                          <div style={{ fontSize: 10.5, color: 'var(--body-text)', marginTop: 2 }}>{j.partNumber} · {j.manufacturer} · DC {j.dateCode}</div>
                        </td>
                        <td><StatusPill status={j.status} /></td>
                        <td className="num">
                          <div style={{ display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'flex-end' }}>
                            <div style={{ width: 80, height: 6, background: 'var(--canvas)', borderRadius: 100, overflow: 'hidden' }}>
                              <div style={{ height: '100%', width: `${p.pct}%`, background: 'var(--light-blue)' }} />
                            </div>
                            <span style={{ fontVariantNumeric: 'tabular-nums', minWidth: 38 }}>{p.done}/{p.total}</span>
                          </div>
                        </td>
                        <td>
                          {isApproverOrAdmin ?
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Avatar user={eng} size={22} /><span style={{ fontSize: 11.5, color: 'var(--dark-blue)' }}>{eng.name}</span></div> :
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Avatar user={apv} size={22} /><span style={{ fontSize: 11.5, color: 'var(--dark-blue)' }}>{apv.name}</span></div>}
                        </td>
                      </tr>);

                })}
                </tbody>
              </table>
            }
          </div>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
          <div className="card">
            <div className="card-header"><h3>Notifications</h3></div>
            <div className="card-body" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              {data.NOTIFICATIONS.map((n) =>
              <div key={n.id} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', cursor: 'pointer' }} onClick={() => onOpenJob(n.jobId)}>
                  <div style={{
                  width: 28, height: 28, borderRadius: 6,
                  background: n.kind === 'rejection' ? 'var(--red-soft)' : 'var(--green-soft)',
                  color: n.kind === 'rejection' ? 'var(--red)' : 'var(--green)',
                  display: 'grid', placeItems: 'center', flexShrink: 0
                }}><Icon name={n.kind === 'rejection' ? 'reject' : 'check-circle'} size={14} /></div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 12, color: 'var(--dark-blue)', fontWeight: 600 }}>{n.title}</div>
                    <div style={{ fontSize: 11, color: 'var(--body-text)', marginTop: 2, lineHeight: 1.4 }}>{n.body}</div>
                    <div style={{ fontSize: 10, color: 'var(--body-text)', marginTop: 4 }}>{n.when}</div>
                  </div>
                </div>
              )}
            </div>
          </div>

          <div className="card">
            <div className="card-header"><h3>Quick actions</h3></div>
            <div className="card-body" style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              <button className="btn" onClick={onNewJob}><Icon name="plus" size={12} /> Create new job</button>
              <button className="btn" onClick={() => onGoTab('jobs')}><Icon name="jobs" size={12} /> Browse all jobs</button>
              <button className="btn" onClick={() => onGoTab('archive')}><Icon name="archive" size={12} /> Search issued reports</button>
            </div>
          </div>
        </div>
      </div>
    </div>);

}

// =================== JOBS LIST ===================
function JobsList({ data, currentUser, onOpenJob, onNewJob, archive = false }) {
  const [filter, setFilter] = useState('all');
  const [q, setQ] = useState('');
  const list = useMemo(() => {
    let l = archive ? data.JOBS.filter((j) => j.status === 'Complete') : data.JOBS.filter((j) => j.status !== 'Complete');
    if (filter !== 'all') l = l.filter((j) => j.status === filter);
    if (q.trim()) {
      const s = q.toLowerCase();
      l = l.filter((j) =>
      j.reportNumber.toLowerCase().includes(s) ||
      j.customerJobRef.toLowerCase().includes(s) ||
      j.partNumber.toLowerCase().includes(s) ||
      customerOf(j, data).name.toLowerCase().includes(s) ||
      j.manufacturer.toLowerCase().includes(s));
    }
    return l;
  }, [filter, q, archive, data]);

  const filters = archive ?
  ['all'] :
  ['all', 'Planned', 'In Progress', 'For Approval', 'Rejected', 'Approved'];

  return (
    <div>
      <div className="page-header">
        <div>
          <h1>{archive ? 'Archive — Issued Reports' : 'Jobs'}</h1>
          <div className="sub">{archive ?
            'Issued AS6171A reports — searchable, read-only.' :
            'Active and recently-completed AS6171A jobs.'}
          </div>
        </div>
        {!archive && (currentUser.role === 'Test Engineer' || currentUser.role === 'Admin') &&
        <div className="actions">
            <button className="btn primary" onClick={onNewJob}><Icon name="plus" size={14} /> New Job</button>
          </div>
        }
      </div>

      <div className="list-toolbar">
        <input className="search" placeholder="Search by report number, part, customer, lot…" value={q} onChange={(e) => setQ(e.target.value)} />
        {!archive &&
        <div className="filters">
            {filters.map((f) =>
          <button key={f} className={`chip ${filter === f ? 'active' : ''}`} onClick={() => setFilter(f)}>
                {f === 'all' ? 'All statuses' : f}
              </button>
          )}
          </div>
        }
        <div className="right">
          <button className="btn ghost sm"><Icon name="filter" size={12} /> More filters</button>
          <button className="btn ghost sm"><Icon name="download" size={12} /> Export</button>
        </div>
      </div>

      <div className="card" style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
        <table className="tbl">
          <thead><tr>
            <th>Report number</th>
            <th>Customer / Job ref</th>
            <th>Part / Manufacturer</th>
            <th>Risk · Model</th>
            <th>Status</th>
            <th>Progress</th>
            <th>Engineer</th>
            <th>Approver</th>
            <th>{archive ? 'Issued' : 'Target issue'}</th>
          </tr></thead>
          <tbody>
            {list.map((j) => {
              const p = progressFor(j);
              const cust = customerOf(j, data);
              const eng = engineerOf(j, data);
              const apv = approverOf(j, data);
              return (
                <tr key={j.id} className="row-clickable" onClick={() => onOpenJob(j.id)}>
                  <td>
                    <div className="lead">{j.reportNumber}</div>
                    <div style={{ fontSize: 10.5, color: 'var(--body-text)', marginTop: 2 }}>Created {data.fmtDate(j.createdAt)}</div>
                  </td>
                  <td>
                    <div className="lead">{cust.name}</div>
                    <div style={{ fontSize: 10.5, color: 'var(--body-text)', marginTop: 2 }}>{j.customerJobRef}</div>
                  </td>
                  <td>
                    <div className="lead">{j.partNumber}</div>
                    <div style={{ fontSize: 10.5, color: 'var(--body-text)', marginTop: 2 }}>{j.manufacturer} · DC {j.dateCode}</div>
                  </td>
                  <td><span className="tag">{(j.groupResults || []).length} groups</span></td>
                  <td><StatusPill status={j.status} /></td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <div style={{ width: 70, height: 6, background: 'var(--canvas)', borderRadius: 100, overflow: 'hidden' }}>
                        <div style={{ height: '100%', width: `${p.pct}%`, background: 'var(--light-blue)' }} />
                      </div>
                      <span style={{ fontSize: 11.5, fontVariantNumeric: 'tabular-nums' }}>{p.done}/{p.total}</span>
                    </div>
                  </td>
                  <td><div style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Avatar user={eng} size={22} /><span style={{ fontSize: 11.5 }}>{eng.name.split(' ').map((s, i, a) => i === 0 ? s[0] + '.' : s).join(' ')}</span></div></td>
                  <td><div style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Avatar user={apv} size={22} /><span style={{ fontSize: 11.5 }}>{apv.name.split(' ').map((s, i, a) => i === 0 ? s[0] + '.' : s).join(' ')}</span></div></td>
                  <td className="muted">{archive ? data.fmtDate(j.issuedAt) : data.fmtDate(j.targetIssueDate)}</td>
                </tr>);

            })}
            {list.length === 0 &&
            <tr><td colSpan={9}><div className="empty"><div className="big">No matching jobs</div>Try clearing filters or searching differently.</div></td></tr>
            }
          </tbody>
        </table>
      </div>
    </div>);

}

// =================== JOB DETAIL ===================
function JobDetail({ data, jobId, currentUser, onOpenTest, onBack, onSubmitForApproval,
  onApprove, onReject, onIssue, onPreviewPdf }) {
  const [tab, setTab] = useState('tests');
  const job = getById(data.JOBS, jobId);
  if (!job) return null;
  const cust = customerOf(job, data);
  const eng = engineerOf(job, data);
  const apv = approverOf(job, data);
  const p = progressFor(job);
  const myJob = isMyJob(job, currentUser);
  const myApproval = isMyApproval(job, currentUser) && job.status === 'For Approval';
  const role = currentUser.role;
  const engineers = engineersOf(job, data);
  const approvers = approversOf(job, data);

  const allComplete = (job.groupResults || []).every((r) => r.status === 'Complete');
  const canSubmit = (myJob || role === 'Admin') && allComplete && (job.status === 'In Progress' || job.status === 'Rejected');
  const canIssue = (role === 'Approver' || role === 'Admin') && job.status === 'Approved';

  const banner = (() => {
    if (job.status === 'Rejected') {
      return (
        <div className="approval-banner rejected">
          <Icon name="reject" size={18} />
          <div>
            <div style={{ fontWeight: 700 }}>Returned for revision by {data.USERS.find((u) => u.id === job.rejectedById)?.name} on {job.rejectedAt}</div>
            <div style={{ fontSize: 11.5, marginTop: 3, opacity: 0.95 }}>{job.rejectionReason}</div>
          </div>
          {canSubmit && <div className="actions"><button className="btn primary" onClick={onSubmitForApproval}><Icon name="send" size={12} /> Resubmit for approval</button></div>}
        </div>);

    }
    if (job.status === 'For Approval' && isMyApproval) {
      return (
        <div className="approval-banner action">
          <Icon name="alert" size={18} />
          <div>
            <div style={{ fontWeight: 700 }}>Awaiting your review — submitted {job.submittedForApprovalAt}</div>
            <div style={{ fontSize: 11.5, marginTop: 3 }}>Submitted by {eng.name}. {p.total} groups, {(job.groupResults || []).filter((r) => r.groupOutcome === 'Failed').length} failed / {(job.groupResults || []).filter((r) => (r.tests || []).some((t) => (t.suspect || []).length > 0)).length} contain suspect devices.</div>
          </div>
          <div className="actions">
            <button className="btn" onClick={onPreviewPdf}><Icon name="eye" size={12} /> Preview PDF</button>
            <button className="btn danger" onClick={onReject}><Icon name="x" size={12} /> Reject</button>
            <button className="btn success" onClick={onApprove}><Icon name="check" size={12} /> Approve</button>
          </div>
        </div>);

    }
    if (job.status === 'For Approval') {
      return (
        <div className="approval-banner info">
          <Icon name="clock" size={18} />
          <div>
            <div style={{ fontWeight: 700 }}>Submitted for approval — awaiting {apv.name}</div>
            <div style={{ fontSize: 11.5, marginTop: 3 }}>Submitted {job.submittedForApprovalAt}. You'll be notified when reviewed.</div>
          </div>
        </div>);

    }
    if (job.status === 'Approved') {
      return (
        <div className="approval-banner approved">
          <Icon name="check-circle" size={18} />
          <div>
            <div style={{ fontWeight: 700 }}>Approved by {apv.name} on {job.approvedAt}</div>
            <div style={{ fontSize: 11.5, marginTop: 3 }}>Ready to issue to customer. Issuing locks the report and moves it to the archive.</div>
          </div>
          <div className="actions">
            <button className="btn" onClick={onPreviewPdf}><Icon name="eye" size={12} /> Preview PDF</button>
            {canIssue && <button className="btn primary" onClick={onIssue}><Icon name="send" size={12} /> Issue report</button>}
          </div>
        </div>);

    }
    if (job.status === 'Complete') {
      return (
        <div className="approval-banner approved">
          <Icon name="check-circle" size={18} />
          <div>
            <div style={{ fontWeight: 700 }}>Issued to customer on {job.issuedAt}</div>
            <div style={{ fontSize: 11.5, marginTop: 3 }}>Report is locked. Stored in the archive (read-only).</div>
          </div>
          <div className="actions">
            <button className="btn" onClick={onPreviewPdf}><Icon name="pdf" size={12} /> View PDF</button>
            <button className="btn"><Icon name="download" size={12} /> Download</button>
          </div>
        </div>);

    }
    return null;
  })();

  return (
    <div>
      <button className="btn ghost sm" onClick={onBack} style={{ marginBottom: 8 }}>
        <Icon name="arrow-left" size={12} /> Back to jobs
      </button>

      <div className="job-header">
        <div className="top">
          <div style={{ flex: 1 }}>
            <div className="crumb">Jobs / {cust.name}</div>
            <div className="title-row">
              <h1>{job.partNumber} <span style={{ color: 'var(--body-text)', fontWeight: 500, fontSize: 16 }}>· {job.manufacturer}</span></h1>
              <span className="report-no">Report {job.reportNumber}</span>
            </div>
            <div style={{ fontSize: 12, color: 'var(--body-text)', marginTop: 4 }}>{job.title}</div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 8 }}>
            <StatusPill status={job.status} />
            <div style={{ display: 'flex', gap: 6 }}>
              {canSubmit && job.status === 'In Progress' &&
              <button className="btn primary" onClick={onSubmitForApproval}><Icon name="send" size={12} /> Submit for approval</button>
              }
              <button className="btn"><Icon name="more" size={12} /></button>
            </div>
          </div>
        </div>
        <div className="meta-row">
          <div className="cell"><div className="k">Customer</div><div className="v">{cust.name}</div></div>
          <div className="cell"><div className="k">Customer Job Ref</div><div className="v">{job.customerJobRef}</div></div>
          <div className="cell"><div className="k">Test plan</div><div className="v">{p.total} group{p.total === 1 ? '' : 's'}</div></div>
          <div className="cell"><div className="k">Date / Lot Code</div><div className="v">{job.dateCode} / {job.lotCode}</div></div>
          <div className="cell"><div className="k">Qty Received / Sample</div><div className="v">{job.quantityReceived} / {job.sampleQty}</div></div>
          <div className="cell"><div className="k">Target Issue</div><div className="v">{data.fmtDate(job.targetIssueDate)}</div></div>
          <div className="cell"><div className="k">Engineers</div><div className="v" style={{ display: 'flex', alignItems: 'center', gap: 6 }}><AvatarStack users={engineers} size={20} />{engineers.length === 1 ? engineers[0].name : `${engineers.length} assigned`}</div></div>
          <div className="cell"><div className="k">Approvers</div><div className="v" style={{ display: 'flex', alignItems: 'center', gap: 6 }}><AvatarStack users={approvers} size={20} />{approvers.length === 1 ? approvers[0].name : `${approvers.length} assigned`}</div></div>
          <div className="cell"><div className="k">Received</div><div className="v">{data.fmtDate(job.receivedDate)}</div></div>
          <div className="cell"><div className="k">Created</div><div className="v">{job.createdAt}</div></div>
          <div className="cell"><div className="k">Submitted</div><div className="v">{job.submittedForApprovalAt || '—'}</div></div>
          <div className="cell"><div className="k">{job.status === 'Complete' ? 'Issued' : 'Approved'}</div><div className="v">{job.issuedAt || job.approvedAt || '—'}</div></div>
        </div>
      </div>

      {banner}

      <div className="tabs">
        <button className={`tab ${tab === 'tests' ? 'active' : ''}`} onClick={() => setTab('tests')}>Test sequence <span className="count">{p.done}/{p.total}</span></button>
        <button className={`tab ${tab === 'cover' ? 'active' : ''}`} onClick={() => setTab('cover')}>Cover page</button>
        <button className={`tab ${tab === 'samples' ? 'active' : ''}`} onClick={() => setTab('samples')}>Samples</button>
        <button className={`tab ${tab === 'activity' ? 'active' : ''}`} onClick={() => setTab('activity')}>Activity</button>
      </div>

      {tab === 'tests' &&
      <div className="card">
          <div className="card-header">
            <h3>AS6171A Test Plan — Groups ({p.total})</h3>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <span style={{ fontSize: 11, color: 'var(--body-text)' }}>{p.done} of {p.total} complete</span>
              <button className="btn ghost sm" onClick={onPreviewPdf}><Icon name="eye" size={12} /> Preview PDF</button>
            </div>
          </div>
          <div className="card-body tight">
            <div className="seq-list">
              {(job.groupResults || []).map((r) => {
                const g = data.TEST_GROUPS.find((x) => x.id === r.groupId);
                if (!g) return null;
                const tester = getById(data.USERS, r.testerId);
                const suspects = (r.tests || []).reduce((s, t) => s + (t.suspect || []).length, 0);
                const fails    = (r.tests || []).reduce((s, t) => s + (t.notAccepted || []).length, 0);
                return (
                  <div key={r.groupId} className={`seq-item ${r.status === 'Complete' ? 'complete' : r.status === 'In Progress' ? 'inprogress' : ''}`} onClick={() => onOpenTest(jobId, r.groupId)}>
                    <div className="step-num">{g.number}</div>
                    <div className="test-meta">
                      <div className="test-name">{g.name}</div>
                      <div className="test-cat">
                        <span>{g.category}</span>
                        <span>·</span>
                        <span>{g.tests.length} test{g.tests.length === 1 ? '' : 's'}</span>
                        {tester && <span>·</span>}
                        {tester && <span>{tester.initials}</span>}
                      </div>
                    </div>
                    <div className="qty-tag">
                      {suspects > 0 && <span style={{ color: '#8b5500', fontWeight: 700 }}>{suspects} suspect</span>}
                      {suspects > 0 && fails > 0 && ' · '}
                      {fails > 0 && <span style={{ color: 'var(--red)', fontWeight: 700 }}>{fails} failed</span>}
                    </div>
                    <OutcomePill outcome={r.groupOutcome === 'Passed' ? 'Acceptable' : r.groupOutcome === 'Failed' ? 'Not Acceptable' : r.groupOutcome === 'N/A' ? null : null} />
                    <StatusPill status={r.status} />
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      }

      {tab === 'cover' &&
      <CoverPageEditor data={data} job={job} />
      }

      {tab === 'samples' &&
      <div className="card">
          <div className="card-header"><h3>Sample register</h3></div>
          <div className="card-body tight">
            <table className="tbl">
              <thead><tr>
                <th>Sample ID</th><th>Specimen</th><th>Allocated to</th>
                <th>Status</th><th>Notes</th>
              </tr></thead>
              <tbody>
                {Array.from({ length: job.sampleQty }, (_, i) => {
                const sId = `D-${String(i + 1).padStart(2, '0')}`;
                const allocated = `Available for all groups`;
                const status = i === 6 && job.id === 'j1' ? 'Flagged — Suspect' : 'In stock';
                return (
                  <tr key={i}>
                      <td><div className="lead">{sId}</div></td>
                      <td>{job.partNumber}</td>
                      <td>{allocated}</td>
                      <td>{status === 'Flagged — Suspect' ? <span className="outcome-pill suspect">Flagged</span> : <span className="pill complete"><span className="dot" />{status}</span>}</td>
                      <td className="muted">{i === 6 && job.id === 'j1' ? 'Marking transfer observed in RES (Test 4)' : '—'}</td>
                    </tr>);

              })}
              </tbody>
            </table>
          </div>
        </div>
      }

      {tab === 'activity' &&
      <div className="card">
          <div className="card-header"><h3>Activity</h3></div>
          <div className="card-body">
            <div className="audit-timeline">
              {(data.JOB_AUDIT[job.id] || []).map((row, i) => {
              const u = getById(data.USERS, row.userId);
              return (
                <div key={i} className="audit-row">
                    <div className="marker" />
                    <div className="body">
                      <div className="what">{row.what}</div>
                      <div className="who"><Avatar user={u} size={14} style={{ display: 'inline-block', verticalAlign: 'middle' }} /> {u?.name}</div>
                    </div>
                    <div className="when">{row.when}</div>
                  </div>);

            })}
            </div>
          </div>
        </div>
      }
    </div>);

}

// Cover page editor (placeholder UI — Phase 1 spec mentions editable cover/result text)
function CoverPageEditor({ data, job }) {
  const [exec, setExec] = useState(
    `The 10 specimens received from the customer were subjected to AS6171A Moderate Risk — Model 2 testing. Tests 1 through 4 were non-destructive examinations, Tests 5 and 6 were internal/non-destructive imaging, Tests 7 and 8 were destructive die analyses on a sub-sample of 5, and Test 9 was electrical parametric verification.

Findings: ${(job.groupResults || []).filter((r) => (r.tests || []).some((t) => (t.suspect || []).length > 0)).length} group(s) returned a Suspect outcome; ${(job.groupResults || []).filter((r) => r.groupOutcome === 'Failed').length} returned Failed. See per-group sections for detail and supporting figures.`
  );
  const [chain, setChain] = useState(data.STANDARD_RESPONSES.find((s) => s.id === 'sr8').body);
  const [limit, setLimit] = useState(data.STANDARD_RESPONSES.find((s) => s.id === 'sr7').body);
  const [insertedSr, setInsertedSr] = useState(null);

  return (
    <div className="two-col-3-2">
      <div className="card">
        <div className="card-header"><h3>Report content</h3>
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="btn ghost sm"><Icon name="rotate" size={12} /> Reset to template</button>
          </div>
        </div>
        <div className="card-body">
          <div className="field">
            <label>Executive summary</label>
            <textarea value={exec} onChange={(e) => setExec(e.target.value)} rows={6} />
            <div className="hint">Shown on page 1 of the issued PDF, beneath the report header.</div>
          </div>
          <div className="field">
            <label>Chain of custody</label>
            <textarea value={chain} onChange={(e) => setChain(e.target.value)} rows={4} />
          </div>
          <div className="field">
            <label>Limitations & liability</label>
            <textarea value={limit} onChange={(e) => setLimit(e.target.value)} rows={4} />
          </div>
        </div>
      </div>
      <div className="card">
        <div className="card-header"><h3>Standard responses</h3></div>
        <div className="card-body" style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{ fontSize: 11, color: 'var(--body-text)' }}>Click to insert at cursor in the active field.</div>
          {data.STANDARD_RESPONSES.filter((sr) => sr.category === 'Cover Page').map((sr) =>
          <div key={sr.id} style={{ border: '1px solid var(--line)', borderRadius: 4, padding: 10 }}>
              <div style={{ fontSize: 10, color: 'var(--body-text)', textTransform: 'uppercase', letterSpacing: 0.5, fontWeight: 600 }}>{sr.category}</div>
              <div style={{ fontSize: 12.5, color: 'var(--dark-blue)', fontWeight: 600, marginTop: 2 }}>{sr.title}</div>
              <div style={{ fontSize: 11, color: 'var(--body-text)', marginTop: 4, lineHeight: 1.4 }}>{sr.body}</div>
              <div style={{ marginTop: 6, display: 'flex', gap: 6 }}>
                <button className="btn ghost sm" onClick={() => setInsertedSr(sr.id)}><Icon name="plus" size={11} /> Insert</button>
              </div>
              {insertedSr === sr.id && <div style={{ fontSize: 10.5, color: 'var(--green)', marginTop: 6 }}>Inserted at end of summary.</div>}
            </div>
          )}
          <div style={{ borderTop: '1px solid var(--line)', paddingTop: 10, marginTop: 4, fontSize: 11, color: 'var(--body-text)' }}>
            Manage the full library in <strong>Admin → Standard Responses</strong>.
          </div>
        </div>
      </div>
    </div>);

}

window.Dashboard = Dashboard;
window.JobsList = JobsList;
window.JobDetail = JobDetail;