/* screens-req.jsx - R99 Task 3: the structured requisition form (create/edit).
   A four-section, full-screen sheet that mirrors the production /req-intake wizard, adapted to the
   prototype conventions (DS Field/Input/Select/Toggle, E8Store overlay, --ui-* tokens, no build).
   Opened via window.e8OpenReqForm({ jobId?, prefill? }) - the host lives in main.jsx. Persists a
   full req into D.jobDetails[jobId] via E8Store.setDetail and promotes a typed loc onto the job row.
   Loads after screens-job.jsx (reuses ReqSection / ReqLocationBlock / reqHas for the review) and
   before screens-capture.jsx (capMatchClient / capClientRow are read at runtime, guarded). */
const DSreq = window.Stand8DesignSystem_b5c975;
const REQFORM_WEEK = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const REQFORM_SECTIONS = [
  { id: 'position', label: 'Position & client', icon: 'work' },
  { id: 'comploc', label: 'Compensation & location', icon: 'payments' },
  { id: 'reqproc', label: 'Requirements & process', icon: 'checklist' },
  { id: 'details', label: 'Details & JD', icon: 'description' },
];
/* Which section each validated field belongs to, so a blocked Create can jump to the first gap. */
const REQFORM_FIELD_SECTION = {
  title: 0, client: 0, roleType: 0,
  billRate: 1, payRate: 1, duration: 1, salaryRange: 1, locType: 1, address: 1, onsiteDays: 1, timezone: 1,
  mustHaves: 2, interviewRounds: 2,
};

function reqNum(s) {
  if (s == null || String(s).trim() === '') return null;
  const n = parseFloat(String(s).replace(/[^0-9.]/g, ''));
  return isFinite(n) ? n : null;
}
function reqIsContract(roleType) { return roleType === 'contract' || roleType === 'c2h'; }
function reqRoleToJobType(roleType) { return roleType === 'direct' ? 'Direct hire' : roleType === 'c2h' ? 'Contract-to-hire' : 'Contract'; }
function reqJobTypeToRole(type) {
  const t = String(type || '').toLowerCase();
  if (t.indexOf('direct') !== -1 || t.indexOf('perm') !== -1) return 'direct';
  if (t.indexOf('hire') !== -1 || t.indexOf('c2h') !== -1) return 'c2h';
  return 'contract';
}
/* Best-effort city/state out of a street address so the list/header location summary can read them. */
function reqParseCityState(addr) {
  const parts = String(addr || '').split(',').map((s) => s.trim()).filter(Boolean);
  if (parts.length < 2) return { city: '', state: '' };
  const city = parts[parts.length - 2] || '';
  const tail = parts[parts.length - 1] || '';
  const st = (tail.match(/\b([A-Z]{2})\b/) || [])[1] || tail.split(/\s+/)[0] || '';
  return { city: city, state: st };
}
/* A compact location string kept on the job row so anything still reading job.location works. */
function reqLocString(loc) {
  if (!loc || loc.type === 'remote') return 'Remote';
  const place = [loc.city, loc.state].filter(Boolean).join(', ') || 'TBD';
  return place + ' · ' + loc.type;
}

/* Seed the flat form state from a prefill ({ job?, req?, loc? } from Edit, or the mapped shape the
   intake agent hands off). Reads job-row basics for title/client/openings and the req for the rest. */
function reqFormInit(prefill) {
  prefill = prefill || {};
  const job = prefill.job || {};
  const req = prefill.req || {};
  const loc = prefill.loc || req.loc || (job.loc) || {};
  const hm = req.hiringManager || {};
  const roleType = req.roleType || reqJobTypeToRole(job.type) || 'contract';
  const musts = (Array.isArray(req.mustHaves) && req.mustHaves.length) ? req.mustHaves.slice()
    : (Array.isArray(job.skills) && job.skills.length) ? job.skills.slice() : [''];
  const rounds = (Array.isArray(req.interviewRounds) && req.interviewRounds.length)
    ? req.interviewRounds.map((r) => ({ format: r.format || '', interviewer: r.interviewer || '' }))
    : [{ format: '', interviewer: '' }];
  const clientName0 = job.client || prefill.client || '';
  const matched0 = (typeof capMatchClient === 'function' && clientName0.trim()) ? capMatchClient(clientName0) : null;
  return {
    title: job.title || prefill.title || '',
    client: clientName0,
    clientCorpId: req.clientCorpId || (matched0 ? matched0.id : ''),
    hmName: hm.name || '', hmTitle: hm.title || '', hmEmail: hm.email || '', hmPhone: hm.phone || '',
    roleType: roleType,
    totalOpenings: req.totalOpenings != null ? String(req.totalOpenings) : (job.openings != null ? String(job.openings) : ''),
    reasonForOpening: req.reasonForOpening || '',
    competition: req.competition || '',
    howLongOpen: req.howLongOpen || '',
    candidatesInProcess: req.candidatesInProcess != null ? !!req.candidatesInProcess : false,
    // comp
    billRate: req.billRate != null ? String(req.billRate) : '',
    payRate: req.payRate != null ? String(req.payRate) : '',
    maxBill: req.maxBill != null ? String(req.maxBill) : '',
    flexRate: !!req.flexRate,
    extensionLikelihood: req.extensionLikelihood || '',
    duration: req.duration || job.duration || '',
    salaryRange: req.salaryRange || '',
    // location
    locType: loc.type || 'onsite',
    address: loc.address || '',
    city: loc.city || '', state: loc.state || '',
    onsiteDays: Array.isArray(loc.onsiteDays) ? loc.onsiteDays.slice() : [],
    timezone: loc.timezone || '',
    geo: loc.geo || '',
    flexNote: loc.flexNote || '',
    // schedule
    hoursPerWeek: req.hoursPerWeek != null ? String(req.hoursPerWeek) : '',
    shift: req.shift || '',
    equipmentProvided: req.equipmentProvided != null ? !!req.equipmentProvided : true,
    startTarget: req.startTarget || job.start || '',
    // requirements + process
    niceToHaves: (Array.isArray(req.niceToHaves) && req.niceToHaves.length) ? req.niceToHaves.slice() : [''],
    mustHaves: musts,
    workAuth: req.workAuth || job.workAuth || '',
    backgroundCheck: req.backgroundCheck != null ? !!req.backgroundCheck : false,
    screeningQuestions: req.screeningQuestions || '',
    interviewRounds: rounds,
    // details + JD
    jobDescription: req.jobDescription || prefill.jobDescription || '',
    projectDescription: req.projectDescription || '',
    sellingPoints: req.sellingPoints || '',
    advantages: req.advantages || '',
    referenceLinkedins: (Array.isArray(req.referenceLinkedins) ? req.referenceLinkedins.join('\n') : ''),
    activeMSA: !!req.activeMSA, sowSigned: !!req.sowSigned, reqApproved: !!req.reqApproved,
    nextMeeting: req.nextMeeting || '',
  };
}

/* The typed location object promoted onto the job row and mirrored into the req. */
function reqBuildLoc(v) {
  const type = v.locType || 'onsite';
  const loc = { type: type };
  if (type === 'remote') {
    if (v.timezone.trim()) loc.timezone = v.timezone.trim();
    if (v.geo.trim()) loc.geo = v.geo.trim();
    if (v.flexNote.trim()) loc.flexNote = v.flexNote.trim();
    return loc;
  }
  const addr = v.address.trim();
  if (addr) loc.address = addr;
  const cs = reqParseCityState(addr);
  const city = cs.city || v.city.trim();
  const state = cs.state || v.state.trim();
  if (city) loc.city = city;
  if (state) loc.state = state;
  if (type === 'hybrid') {
    loc.onsiteDays = REQFORM_WEEK.filter((d) => v.onsiteDays.indexOf(d) !== -1);
    loc.daysOnsite = loc.onsiteDays.length;
    if (v.flexNote.trim()) loc.flexNote = v.flexNote.trim();
  }
  return loc;
}

/* Build the requisition patch (only the keys the form owns - E8Store.setDetail shallow-merges, so
   seed-only fields like description/requirements/contacts are preserved). prov carries the drafted
   markers for AI-authored fields the user has not overridden. */
function reqBuildReq(v, prov, loc) {
  const contract = reqIsContract(v.roleType);
  const musts = v.mustHaves.map((s) => s.trim()).filter(Boolean);
  const nices = v.niceToHaves.map((s) => s.trim()).filter(Boolean);
  const rounds = v.interviewRounds
    .map((r) => ({ format: (r.format || '').trim(), interviewer: (r.interviewer || '').trim() }))
    .filter((r) => r.format);
  const refs = String(v.referenceLinkedins || '').split(/[\n,]+/).map((s) => s.trim()).filter(Boolean);
  const hm = {};
  if (v.hmName.trim()) hm.name = v.hmName.trim();
  if (v.hmTitle.trim()) hm.title = v.hmTitle.trim();
  if (v.hmEmail.trim()) hm.email = v.hmEmail.trim();
  if (v.hmPhone.trim()) hm.phone = v.hmPhone.trim();
  const req = {
    jobDescription: v.jobDescription.trim(),
    projectDescription: v.projectDescription.trim(),
    roleType: v.roleType,
    hoursPerWeek: reqNum(v.hoursPerWeek),
    shift: v.shift.trim(),
    equipmentProvided: v.equipmentProvided,
    mustHaves: musts,
    niceToHaves: nices,
    workAuth: v.workAuth.trim(),
    backgroundCheck: v.backgroundCheck,
    screeningQuestions: v.screeningQuestions.trim(),
    interviewRounds: rounds,
    sellingPoints: v.sellingPoints.trim(),
    advantages: v.advantages.trim(),
    competition: v.competition.trim(),
    reasonForOpening: v.reasonForOpening,
    howLongOpen: v.howLongOpen.trim(),
    candidatesInProcess: v.candidatesInProcess,
    clientCorpId: v.clientCorpId || null,
    totalOpenings: reqNum(v.totalOpenings),
    startTarget: v.startTarget.trim(),
    nextMeeting: v.nextMeeting.trim(),
    activeMSA: v.activeMSA, sowSigned: v.sowSigned, reqApproved: v.reqApproved,
    duration: v.duration.trim(),
    hiringManager: Object.keys(hm).length ? hm : null,
    referenceLinkedins: refs,
    loc: loc,
    prov: Object.keys(prov || {}).length ? prov : null,
  };
  if (contract) {
    req.billRate = reqNum(v.billRate); req.payRate = reqNum(v.payRate); req.maxBill = reqNum(v.maxBill);
    req.flexRate = v.flexRate; req.extensionLikelihood = v.extensionLikelihood || null;
  } else {
    req.salaryRange = v.salaryRange.trim();
  }
  return req;
}

/* All blocking validation, keyed by field (message). Mirrors the production wizard's conditional
   rules: contract needs bill > pay > 0 + duration; direct needs a salary; onsite needs an address;
   hybrid needs an address + on-site days; remote needs a timezone; >= 1 must-have + interview round. */
function reqFormErrors(v) {
  const e = {};
  const contract = reqIsContract(v.roleType);
  if (!v.title.trim()) e.title = 'Job title is required';
  if (!v.client.trim()) e.client = 'Client is required';
  if (!v.roleType) e.roleType = 'Role type is required';
  if (contract) {
    const bill = reqNum(v.billRate), pay = reqNum(v.payRate);
    if (!(bill > 0)) e.billRate = 'Bill rate is required';
    if (!(pay > 0)) e.payRate = 'Pay rate is required';
    else if (bill > 0 && pay >= bill) e.payRate = 'Pay rate must be below the bill rate';
    if (!v.duration.trim()) e.duration = 'Duration is required';
  } else {
    if (!v.salaryRange.trim()) e.salaryRange = 'Salary range is required';
  }
  if (!v.locType) e.locType = 'Location type is required';
  else if (v.locType === 'onsite') { if (!v.address.trim()) e.address = 'Office address is required'; }
  else if (v.locType === 'hybrid') {
    if (!v.address.trim()) e.address = 'Office address is required';
    if (!v.onsiteDays.length) e.onsiteDays = 'Pick at least one on-site day';
  } else if (v.locType === 'remote') { if (!v.timezone.trim()) e.timezone = 'Timezone or working hours is required'; }
  if (!v.mustHaves.some((s) => s.trim())) e.mustHaves = 'Add at least one must-have';
  if (!v.interviewRounds.some((r) => (r.format || '').trim())) e.interviewRounds = 'Add at least one interview round';
  return e;
}

/* ---- Small building blocks ---- */
function ReqToggleRow({ label, help, checked, onChange }) {
  return (
    <div className="e8-reqform-toggle">
      <div style={{ minWidth: 0 }}>
        <div className="e8-reqform-toggle-label">{label}</div>
        {help ? <div className="e8-reqform-toggle-help">{help}</div> : null}
      </div>
      <DSreq.Toggle checked={checked} onChange={onChange} />
    </div>
  );
}

/* Add/remove text rows (must-haves, nice-to-haves). */
function ReqRowList({ label, required, rows, onChange, placeholder, error, addLabel }) {
  const setRow = (i, val) => { const n = rows.slice(); n[i] = val; onChange(n); };
  const addRow = () => onChange(rows.concat(['']));
  const removeRow = (i) => { const n = rows.slice(); n.splice(i, 1); onChange(n.length ? n : ['']); };
  return (
    <DSreq.Field label={label + (required ? ' *' : '')} error={error}>
      <div className="e8-reqform-rows">
        {rows.map((r, i) => (
          <div key={i} className="e8-reqform-row">
            <DSreq.Input value={r} placeholder={placeholder} onChange={(ev) => setRow(i, ev.target.value)} wrapStyle={{ flex: 1 }} />
            <DSreq.Button variant="ghost" size="sm" icon="close" iconOnly title="Remove" onClick={() => removeRow(i)} />
          </div>
        ))}
        <div><DSreq.Button variant="ghost" size="sm" icon="add" onClick={addRow}>{addLabel || 'Add row'}</DSreq.Button></div>
      </div>
    </DSreq.Field>
  );
}

/* Add/remove interview rounds ({ format, interviewer }). */
function ReqRoundList({ rows, onChange, error }) {
  const setRow = (i, key, val) => { const n = rows.map((r) => Object.assign({}, r)); n[i][key] = val; onChange(n); };
  const addRow = () => onChange(rows.concat([{ format: '', interviewer: '' }]));
  const removeRow = (i) => { const n = rows.slice(); n.splice(i, 1); onChange(n.length ? n : [{ format: '', interviewer: '' }]); };
  return (
    <DSreq.Field label="Interview rounds *" error={error} help="At least one round. The candidate sees this as the process.">
      <div className="e8-reqform-rows">
        {rows.map((r, i) => (
          <div key={i} className="e8-reqform-round">
            <span className="e8-reqform-round-num tnum">{i + 1}</span>
            <DSreq.Input value={r.format} placeholder="Round (e.g. Technical panel)" onChange={(ev) => setRow(i, 'format', ev.target.value)} wrapStyle={{ flex: 1.3 }} />
            <DSreq.Input value={r.interviewer} placeholder="Interviewer" onChange={(ev) => setRow(i, 'interviewer', ev.target.value)} wrapStyle={{ flex: 1 }} />
            <DSreq.Button variant="ghost" size="sm" icon="close" iconOnly title="Remove round" onClick={() => removeRow(i)} />
          </div>
        ))}
        <div><DSreq.Button variant="ghost" size="sm" icon="add" onClick={addRow}>Add round</DSreq.Button></div>
      </div>
    </DSreq.Field>
  );
}

/* Live review of the whole requisition, reusing the Task 2 display helpers so it reads exactly like
   the job Overview tab it will become. */
function ReqFormReview({ v }) {
  const loc = window.jobLocDetail ? window.jobLocDetail(reqBuildLoc(v)) : null;
  const contract = reqIsContract(v.roleType);
  const bill = reqNum(v.billRate), pay = reqNum(v.payRate);
  const margin = contract && bill > 0 && pay > 0 && pay < bill ? Math.round(((bill - pay) / bill) * 100) : null;
  const musts = v.mustHaves.filter((s) => s.trim());
  const rounds = v.interviewRounds.filter((r) => (r.format || '').trim());
  const compliance = [['Active MSA', v.activeMSA], ['SOW signed', v.sowSigned], ['Req approved', v.reqApproved]];
  return (
    <div className="e8-reqform-review">
      <div className="e8-reqform-review-title">{v.title.trim() || 'Untitled requisition'}</div>
      <div className="e8-reqform-review-sub">
        {(v.client.trim() || 'No client') + ' · ' + reqRoleToJobType(v.roleType) + (v.totalOpenings ? ' · ' + v.totalOpenings + ' opening' + (Number(v.totalOpenings) === 1 ? '' : 's') : '')}
      </div>
      {loc ? <div style={{ marginTop: 12 }}><ReqLocationBlock loc={loc} /></div> : null}
      <div className="e8-req-grid" style={{ marginTop: 14 }}>
        {contract ? (
          <React.Fragment>
            <ReqFact k="Bill rate" v={bill != null ? '$' + bill + '/hr' : null} tnum />
            <ReqFact k="Pay rate" v={pay != null ? '$' + pay + '/hr' : null} tnum />
            {margin != null ? (
              <div className="e8-req-fact">
                <div className="e8-req-k">Margin</div>
                <div className="e8-req-v tnum" style={{ color: 'var(--ui-success-text)' }}>{margin}% <span className="e8-req-computed">computed</span></div>
              </div>
            ) : null}
            <ReqFact k="Duration" v={v.duration.trim() || null} />
          </React.Fragment>
        ) : (
          <ReqFact k="Salary range" v={v.salaryRange.trim() || null} tnum />
        )}
        <ReqFact k="Must-haves" v={musts.length ? String(musts.length) : null} tnum />
        <ReqFact k="Interview rounds" v={rounds.length ? String(rounds.length) : null} tnum />
      </div>
      <div className="e8-req-status" style={{ marginTop: 14 }}>
        {compliance.map(([label, ok]) => (
          <span key={label} className={'e8-req-tag ' + (ok ? 'ok' : 'missing')}>
            <span className="material-symbols-outlined">{ok ? 'check' : 'error'}</span>{label}
          </span>
        ))}
      </div>
    </div>
  );
}

function RequisitionForm({ jobId, prefill, onClose }) {
  const { showToast } = React.useContext(E8Ctx);
  const D = window.E8DATA || {};
  const editing = !!jobId;
  const existingJob = editing ? (D.jobs || []).find((j) => j.id === jobId) : null;
  const sheetRef = React.useRef(null);
  const dirtyRef = React.useRef(false);
  const [confirming, setConfirming] = React.useState(false);
  const [section, setSection] = React.useState(0);
  const [tried, setTried] = React.useState({}); // section index -> attempted (reveals its errors)
  const [v, setV] = React.useState(() => reqFormInit(prefill));
  /* Provenance for AI-drafted fields; a user edit to a drafted field clears its badge. */
  const [prov, setProv] = React.useState(() => Object.assign({}, (prefill && prefill.req && prefill.req.prov) || (prefill && prefill.prov) || {}));

  window.useDialog(true, sheetRef);

  const set = (key, val) => { dirtyRef.current = true; setV((p) => Object.assign({}, p, { [key]: val })); };
  /* Client field: resolve the matched corp id alongside the typed name (cleared when unmatched). */
  const setClient = (raw) => {
    const matched = (typeof capMatchClient === 'function' && String(raw).trim()) ? capMatchClient(raw) : null;
    dirtyRef.current = true;
    setV((p) => Object.assign({}, p, { client: raw, clientCorpId: matched ? matched.id : '' }));
  };
  /* Edit to a field carrying a drafted badge -> it is now human-reviewed, so drop the marker. */
  const setProse = (key, val) => { if (prov[key]) setProv((p) => { const n = Object.assign({}, p); delete n[key]; return n; }); set(key, val); };
  const toggleDay = (d) => { dirtyRef.current = true; setV((p) => { const on = p.onsiteDays.indexOf(d) !== -1; return Object.assign({}, p, { onsiteDays: on ? p.onsiteDays.filter((x) => x !== d) : p.onsiteDays.concat([d]) }); }); };

  const errors = reqFormErrors(v);
  const sectionErrs = (i) => Object.keys(errors).filter((k) => REQFORM_FIELD_SECTION[k] === i);
  const sectionHasError = (i) => sectionErrs(i).length > 0;
  const err = (key) => (tried[REQFORM_FIELD_SECTION[key]] ? errors[key] : undefined);

  const requestClose = React.useCallback(() => { if (dirtyRef.current) setConfirming(true); else onClose(); }, [onClose]);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape' && !confirming) { e.preventDefault(); requestClose(); } };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [confirming, requestClose]);

  const goToSection = (i) => {
    if (i <= section) { setSection(i); return; }
    if (!sectionHasError(section)) { setSection(i); return; }
    setTried((t) => Object.assign({}, t, { [section]: true }));
  };
  const onNext = () => {
    if (sectionHasError(section)) { setTried((t) => Object.assign({}, t, { [section]: true })); return; }
    setSection((s) => Math.min(REQFORM_SECTIONS.length - 1, s + 1));
  };

  const submit = () => {
    const keys = Object.keys(errors);
    if (keys.length) {
      setTried({ 0: true, 1: true, 2: true, 3: true });
      const firstSec = Math.min.apply(null, keys.map((k) => REQFORM_FIELD_SECTION[k]));
      setSection(firstSec);
      return;
    }
    const loc = reqBuildLoc(v);
    const req = reqBuildReq(v, prov, loc);
    const contract = reqIsContract(v.roleType);
    const bill = reqNum(v.billRate);
    const rateStr = contract ? (bill != null ? '$' + bill + '/hr' : 'TBD') : (v.salaryRange.trim() || 'TBD');
    const openings = Math.max(1, parseInt(v.totalOpenings, 10) || 1);
    const skills = v.mustHaves.map((s) => s.trim()).filter(Boolean);

    if (editing && existingJob) {
      const prevDetail = window.E8Store.snapshotDetail(jobId);
      const jobPatch = {
        title: v.title.trim(), client: v.client.trim(), loc: loc, location: reqLocString(loc),
        type: reqRoleToJobType(v.roleType), rate: rateStr, openings: openings, skills: skills,
        start: v.startTarget.trim(), duration: v.duration.trim(), workAuth: v.workAuth.trim(),
        hiringManager: v.hmName.trim(),
      };
      const prevJob = window.E8Store.snapshot('jobs', jobId, Object.keys(jobPatch));
      window.E8Store.set('jobs', jobId, jobPatch);
      window.E8Store.setDetail(jobId, req);
      if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Edited requisition', target: jobId + ' · ' + v.title.trim(), route: 'job/' + jobId + '/overview' });
      if (window.E8Events) window.E8Events.emit('job:updated', { id: jobId });
      dirtyRef.current = false;
      onClose();
      if (showToast) showToast('Requisition updated for ' + v.title.trim(), 'Undo', () => {
        if (prevJob) window.E8Store.set('jobs', jobId, prevJob);
        if (prevDetail) window.E8Store.setDetail(jobId, prevDetail);
        if (window.E8Events) window.E8Events.emit('job:updated', { id: jobId });
      });
      return;
    }

    /* New requisition: mint a job id (same JO-<44900+n> probe as capJobRow), create the client row
       when the named client matches nothing, then add the job + its requisition detail. */
    const clientRaw = v.client.trim();
    const matched = (typeof capMatchClient === 'function') ? capMatchClient(clientRaw) : null;
    const clientName = matched ? matched.name : clientRaw;
    const newClient = (!matched && clientRaw && typeof capClientRow === 'function') ? capClientRow(clientRaw) : null;
    let jn = 44900 + ((D.jobs || []).length);
    while ((D.jobs || []).some((r) => r.id === 'JO-' + jn)) jn++;
    const id = 'JO-' + jn;
    const row = {
      id: id, title: v.title.trim(), client: clientName, location: reqLocString(loc), loc: loc,
      type: reqRoleToJobType(v.roleType), rate: rateStr, day: 0, days: 30, openings: openings, filled: 0,
      priority: 2, owner: (D.user || {}).name || 'You', skills: skills,
      start: v.startTarget.trim(), duration: v.duration.trim(), workAuth: v.workAuth.trim(), hiringManager: v.hmName.trim(),
      pipeline: Object.fromEntries((D.pipelineStages || []).map((s) => [s.key, 0])),
      health: { label: 'New', tone: 'info', note: 'Created from the requisition form - sourcing not started' },
      next: { label: 'Kick off sourcing', toast: 'Matching queued for ' + (v.title.trim() || 'this role') },
    };
    if (newClient) {
      window.E8Store.add('clients', newClient);
      if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Created client from requisition', target: newClient.name, route: 'client/' + newClient.id });
    }
    window.E8Store.add('jobs', row);
    window.E8Store.setDetail(id, req);
    if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Created requisition', target: id + ' · ' + row.title, route: 'job/' + id + '/overview' });
    if (window.E8Events) window.E8Events.emit('job:created', { id: id });
    dirtyRef.current = false;
    onClose();
    if (showToast) showToast('Created ' + row.title + ' for ' + row.client, 'Open', () => navigate('job/' + id + '/overview'));
  };

  const contract = reqIsContract(v.roleType);
  const bill = reqNum(v.billRate), pay = reqNum(v.payRate);
  const margin = contract && bill > 0 && pay > 0 && pay < bill ? Math.round(((bill - pay) / bill) * 100) : null;
  const lastSection = section === REQFORM_SECTIONS.length - 1;

  return (
    <React.Fragment>
      <div className="e8-reqform-overlay is-open" onMouseDown={(e) => { if (e.target === e.currentTarget) requestClose(); }}>
        <div ref={sheetRef} className="e8-reqform-sheet" role="dialog" aria-modal="true" aria-label={editing ? 'Edit requisition' : 'New requisition'}>
          <div className="e8-reqform-head">
            <div style={{ minWidth: 0 }}>
              <b>{editing ? 'Edit requisition' : 'New requisition'}</b>
              <div className="e8-reqform-hint">{editing ? (existingJob ? existingJob.id + ' · ' + (v.client.trim() || 'client') : 'Requisition') : 'Structured intake · four sections'}</div>
            </div>
            <DSreq.Button variant="ghost" size="sm" icon="close" iconOnly title="Close" onClick={requestClose} />
          </div>

          <div className="e8-reqform-steps" role="tablist" aria-label="Requisition sections">
            {REQFORM_SECTIONS.map((s, i) => (
              <button
                type="button" key={s.id} role="tab" aria-selected={section === i}
                className={'e8-reqform-step' + (section === i ? ' on' : '') + (i < section ? ' done' : '')}
                onClick={() => goToSection(i)}
              >
                <span className="e8-reqform-step-num">
                  {i < section && !sectionHasError(i) ? <span className="material-symbols-outlined">check</span> : (i + 1)}
                </span>
                <span className="e8-reqform-step-label">{s.label}</span>
              </button>
            ))}
          </div>

          <div className="e8-reqform-body">
            {/* Section 1: Position & client */}
            {section === 0 ? (
              <div className="e8-reqform-sec">
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Job title *" error={err('title')}>
                    <DSreq.Input value={v.title} placeholder="e.g. Senior Java developer" onChange={(e) => set('title', e.target.value)} />
                  </DSreq.Field>
                  <DSreq.Field label="Client *" error={err('client')} help={reqClientNote(v.client)}>
                    <DSreq.Input value={v.client} placeholder="e.g. FedEx" onChange={(e) => setClient(e.target.value)} />
                  </DSreq.Field>
                </div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Role type *" error={err('roleType')}>
                    <DSreq.Select value={v.roleType} onChange={(e) => set('roleType', e.target.value)} options={[
                      { value: 'contract', label: 'Contract' },
                      { value: 'c2h', label: 'Contract-to-hire' },
                      { value: 'direct', label: 'Direct hire' },
                    ]} />
                  </DSreq.Field>
                  <DSreq.Field label="Total openings">
                    <DSreq.Input value={v.totalOpenings} inputMode="numeric" placeholder="1" onChange={(e) => set('totalOpenings', e.target.value)} />
                  </DSreq.Field>
                </div>
                <div className="e8-reqform-subhead">Hiring manager</div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Name"><DSreq.Input value={v.hmName} placeholder="e.g. Janet Moss" onChange={(e) => set('hmName', e.target.value)} /></DSreq.Field>
                  <DSreq.Field label="Title"><DSreq.Input value={v.hmTitle} placeholder="e.g. Platform engineering lead" onChange={(e) => set('hmTitle', e.target.value)} /></DSreq.Field>
                </div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Email"><DSreq.Input type="email" value={v.hmEmail} placeholder="name@company.com" onChange={(e) => set('hmEmail', e.target.value)} /></DSreq.Field>
                  <DSreq.Field label="Phone"><DSreq.Input value={v.hmPhone} placeholder="(901) 555-0110" onChange={(e) => set('hmPhone', e.target.value)} /></DSreq.Field>
                </div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Reason for opening">
                    <DSreq.Select value={v.reasonForOpening} onChange={(e) => set('reasonForOpening', e.target.value)} options={[
                      { value: '', label: 'Not specified' }, { value: 'backfill', label: 'Backfill' }, { value: 'growth', label: 'Growth' }, { value: 'new project', label: 'New project' },
                    ]} />
                  </DSreq.Field>
                  <DSreq.Field label="Competition" help="Other vendors on the req, if known">
                    <DSreq.Input value={v.competition} placeholder="e.g. 2 other vendors" onChange={(e) => set('competition', e.target.value)} />
                  </DSreq.Field>
                </div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="How long open" help="How long the position has been open, if reopened or transferred">
                    <DSreq.Input value={v.howLongOpen} placeholder="e.g. 3 weeks" onChange={(e) => set('howLongOpen', e.target.value)} />
                  </DSreq.Field>
                </div>
                <ReqToggleRow label="Candidates already in process" help="The client is already talking to candidates" checked={v.candidatesInProcess} onChange={(e) => set('candidatesInProcess', e.target.checked)} />
              </div>
            ) : null}

            {/* Section 2: Compensation & location */}
            {section === 1 ? (
              <div className="e8-reqform-sec">
                <div className="e8-reqform-subhead">Compensation <span className="e8-reqform-subnote">{reqRoleToJobType(v.roleType)}</span></div>
                {contract ? (
                  <React.Fragment>
                    <div className="e8-reqform-grid">
                      <DSreq.Field label="Bill rate ($/hr) *" error={err('billRate')}><DSreq.Input value={v.billRate} inputMode="decimal" placeholder="e.g. 95" onChange={(e) => set('billRate', e.target.value)} /></DSreq.Field>
                      <DSreq.Field label="Pay rate ($/hr) *" error={err('payRate')}><DSreq.Input value={v.payRate} inputMode="decimal" placeholder="e.g. 68" onChange={(e) => set('payRate', e.target.value)} /></DSreq.Field>
                    </div>
                    {(bill > 0 && pay > 0) ? (
                      <div className={'e8-reqform-margin' + (pay >= bill ? ' bad' : '')}>
                        <span className="material-symbols-outlined">{pay >= bill ? 'error' : 'insights'}</span>
                        {pay >= bill
                          ? <span>Pay rate must be below the bill rate to leave a margin.</span>
                          : <span>Margin <b className="tnum">{margin}%</b> <span className="e8-req-computed">computed</span> · <span className="tnum">${bill - pay}/hr</span> spread</span>}
                      </div>
                    ) : null}
                    <div className="e8-reqform-grid">
                      <DSreq.Field label="Max bill ($/hr)"><DSreq.Input value={v.maxBill} inputMode="decimal" placeholder="e.g. 102" onChange={(e) => set('maxBill', e.target.value)} /></DSreq.Field>
                      <DSreq.Field label="Duration *" error={err('duration')}><DSreq.Input value={v.duration} placeholder="e.g. 12 months" onChange={(e) => set('duration', e.target.value)} /></DSreq.Field>
                    </div>
                    <div className="e8-reqform-grid">
                      <DSreq.Field label="Extension likelihood">
                        <DSreq.Select value={v.extensionLikelihood} onChange={(e) => set('extensionLikelihood', e.target.value)} options={[
                          { value: '', label: 'Not specified' }, { value: 'high', label: 'High' }, { value: 'medium', label: 'Medium' }, { value: 'low', label: 'Low' },
                        ]} />
                      </DSreq.Field>
                      <div style={{ display: 'flex', alignItems: 'flex-end' }}>
                        <ReqToggleRow label="Flexible rate" help="Rate is negotiable for the right profile" checked={v.flexRate} onChange={(e) => set('flexRate', e.target.checked)} />
                      </div>
                    </div>
                  </React.Fragment>
                ) : (
                  <div className="e8-reqform-grid">
                    <DSreq.Field label="Salary range *" error={err('salaryRange')} help="Direct-hire base salary band">
                      <DSreq.Input value={v.salaryRange} placeholder="e.g. $140k - $165k" onChange={(e) => set('salaryRange', e.target.value)} />
                    </DSreq.Field>
                  </div>
                )}

                <div className="e8-reqform-subhead" style={{ marginTop: 6 }}>Location</div>
                <DSreq.Field label="Location type *" error={err('locType')}>
                  <div className="e8-reqform-seg" role="radiogroup" aria-label="Location type">
                    {[['onsite', 'Onsite', 'location_on'], ['hybrid', 'Hybrid', 'sync_alt'], ['remote', 'Remote', 'home_work']].map(([val, lbl, icon]) => (
                      <button type="button" key={val} role="radio" aria-checked={v.locType === val} className={'e8-reqform-seg-btn' + (v.locType === val ? ' on' : '')} onClick={() => set('locType', val)}>
                        <span className="material-symbols-outlined">{icon}</span>{lbl}
                      </button>
                    ))}
                  </div>
                </DSreq.Field>
                {(v.locType === 'onsite' || v.locType === 'hybrid') ? (
                  <DSreq.Field label="Office address *" error={err('address')} help="Street, city, state - powers the location summary on the list and header">
                    <DSreq.Input icon="location_on" value={v.address} placeholder="e.g. 3610 Hacks Cross Rd, Memphis, TN 38125" onChange={(e) => set('address', e.target.value)} />
                  </DSreq.Field>
                ) : null}
                {v.locType === 'hybrid' ? (
                  <DSreq.Field label="On-site days *" error={err('onsiteDays')} help="Toggle the days on-site - the rest are remote">
                    <div className="e8-reqform-days" role="group" aria-label="On-site days">
                      {REQFORM_WEEK.map((d) => {
                        const on = v.onsiteDays.indexOf(d) !== -1;
                        return <button type="button" key={d} className={'e8-reqform-day' + (on ? ' on' : '')} aria-pressed={on} onClick={() => toggleDay(d)}>{d}</button>;
                      })}
                    </div>
                  </DSreq.Field>
                ) : null}
                {v.locType === 'remote' ? (
                  <div className="e8-reqform-grid">
                    <DSreq.Field label="Timezone / working hours *" error={err('timezone')}><DSreq.Input value={v.timezone} placeholder="e.g. CST core hours" onChange={(e) => set('timezone', e.target.value)} /></DSreq.Field>
                    <DSreq.Field label="Geographic restriction" help="Optional"><DSreq.Input value={v.geo} placeholder="e.g. US only" onChange={(e) => set('geo', e.target.value)} /></DSreq.Field>
                  </div>
                ) : null}
                {(v.locType === 'hybrid' || v.locType === 'remote') ? (
                  <DSreq.Field label="Flexibility note" help="Optional"><DSreq.Input value={v.flexNote} placeholder="e.g. Onsite cadence negotiable after ramp" onChange={(e) => set('flexNote', e.target.value)} /></DSreq.Field>
                ) : null}

                <div className="e8-reqform-subhead" style={{ marginTop: 6 }}>Schedule</div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Hours / week"><DSreq.Input value={v.hoursPerWeek} inputMode="numeric" placeholder="40" onChange={(e) => set('hoursPerWeek', e.target.value)} /></DSreq.Field>
                  <DSreq.Field label="Shift"><DSreq.Input value={v.shift} placeholder="e.g. Day (9-5 CST)" onChange={(e) => set('shift', e.target.value)} /></DSreq.Field>
                </div>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Target start"><DSreq.Input value={v.startTarget} placeholder="e.g. Aug 2026" onChange={(e) => set('startTarget', e.target.value)} /></DSreq.Field>
                  <div style={{ display: 'flex', alignItems: 'flex-end' }}>
                    <ReqToggleRow label="Equipment provided" help="Client supplies the hardware" checked={v.equipmentProvided} onChange={(e) => set('equipmentProvided', e.target.checked)} />
                  </div>
                </div>
              </div>
            ) : null}

            {/* Section 3: Requirements & process */}
            {section === 2 ? (
              <div className="e8-reqform-sec">
                <ReqRowList label="Must-haves" required rows={v.mustHaves} onChange={(n) => set('mustHaves', n)} placeholder="e.g. Spring Boot 3 in production" error={err('mustHaves')} addLabel="Add must-have" />
                <ReqRowList label="Nice to have" rows={v.niceToHaves} onChange={(n) => set('niceToHaves', n)} placeholder="e.g. Terraform" addLabel="Add nice-to-have" />
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Work authorization"><DSreq.Input value={v.workAuth} placeholder="e.g. US citizen or green card - W2 only" onChange={(e) => set('workAuth', e.target.value)} /></DSreq.Field>
                  <div style={{ display: 'flex', alignItems: 'flex-end' }}>
                    <ReqToggleRow label="Background / drug screen" help="Required before start" checked={v.backgroundCheck} onChange={(e) => set('backgroundCheck', e.target.checked)} />
                  </div>
                </div>
                <DSreq.Field label="Screening questions">
                  <textarea className="e8-reqform-textarea" rows={3} value={v.screeningQuestions} placeholder="What to ask on the recruiter screen" onChange={(e) => set('screeningQuestions', e.target.value)} />
                </DSreq.Field>
                <ReqRoundList rows={v.interviewRounds} onChange={(n) => set('interviewRounds', n)} error={err('interviewRounds')} />
              </div>
            ) : null}

            {/* Section 4: Details & JD */}
            {section === 3 ? (
              <div className="e8-reqform-sec">
                <DSreq.Field label="Job description" help="The full JD candidates see">
                  {prov.jobDescription === 'drafted' ? <div style={{ marginBottom: 6 }}><DSreq.ProvenanceBadge kind="drafted" /> <span className="e8-reqform-subnote">Drafted by the intake agent - review and edit</span></div> : null}
                  <textarea className="e8-reqform-textarea" rows={7} value={v.jobDescription} placeholder="Describe the role, the team, and the day to day." onChange={(e) => setProse('jobDescription', e.target.value)} />
                </DSreq.Field>
                <DSreq.Field label="Project description">
                  <textarea className="e8-reqform-textarea" rows={3} value={v.projectDescription} placeholder="What is the team building and why" onChange={(e) => set('projectDescription', e.target.value)} />
                </DSreq.Field>
                <DSreq.Field label="Selling points">
                  <textarea className="e8-reqform-textarea" rows={2} value={v.sellingPoints} placeholder="Why a strong candidate should want this" onChange={(e) => set('sellingPoints', e.target.value)} />
                </DSreq.Field>
                <DSreq.Field label="Our advantage">
                  <textarea className="e8-reqform-textarea" rows={2} value={v.advantages} placeholder="Why we win this req (MSA, fast feedback, conversion history)" onChange={(e) => set('advantages', e.target.value)} />
                </DSreq.Field>
                <DSreq.Field label="Reference LinkedIns" help="One per line">
                  <textarea className="e8-reqform-textarea" rows={2} value={v.referenceLinkedins} placeholder="linkedin.com/in/..." onChange={(e) => set('referenceLinkedins', e.target.value)} />
                </DSreq.Field>
                <div className="e8-reqform-grid">
                  <DSreq.Field label="Next meeting"><DSreq.Input value={v.nextMeeting} placeholder="e.g. Jul 22 - pipeline review" onChange={(e) => set('nextMeeting', e.target.value)} /></DSreq.Field>
                </div>
                <div className="e8-reqform-subhead" style={{ marginTop: 6 }}>Compliance</div>
                <div className="e8-reqform-compliance">
                  <ReqToggleRow label="Active MSA" checked={v.activeMSA} onChange={(e) => set('activeMSA', e.target.checked)} />
                  <ReqToggleRow label="SOW signed" checked={v.sowSigned} onChange={(e) => set('sowSigned', e.target.checked)} />
                  <ReqToggleRow label="Req approved" checked={v.reqApproved} onChange={(e) => set('reqApproved', e.target.checked)} />
                </div>
                <div className="e8-reqform-subhead" style={{ marginTop: 6 }}>Review</div>
                <ReqFormReview v={v} />
              </div>
            ) : null}
          </div>

          <div className="e8-reqform-foot">
            <DSreq.Button variant="ghost" size="sm" icon="arrow_back" disabled={section === 0} onClick={() => setSection((s) => Math.max(0, s - 1))}>Back</DSreq.Button>
            <span className="e8-reqform-foot-hint">Section {section + 1} of {REQFORM_SECTIONS.length} · {REQFORM_SECTIONS[section].label}</span>
            {lastSection ? (
              <DSreq.Button variant="primary" size="sm" icon={editing ? 'save' : 'add_task'} onClick={submit}>{editing ? 'Save requisition' : 'Create requisition'}</DSreq.Button>
            ) : (
              <DSreq.Button variant="primary" size="sm" icon="arrow_forward" onClick={onNext}>Next</DSreq.Button>
            )}
          </div>
        </div>
      </div>
      {confirming ? (
        <ConfirmDialog
          title="Discard this requisition?"
          body="You have unsaved changes. Closing will discard them."
          confirmLabel="Discard" cancelLabel="Keep editing" tone="danger" icon="delete"
          onClose={() => setConfirming(false)}
          onConfirm={() => { dirtyRef.current = false; setConfirming(false); onClose(); }}
        />
      ) : null}
    </React.Fragment>
  );
}

/* Inline client fuzzy-match note (mirrors the capture agent's link/new-client hint). */
function reqClientNote(clientRaw) {
  const raw = String(clientRaw || '').trim();
  if (!raw) return undefined;
  const matched = (typeof capMatchClient === 'function') ? capMatchClient(raw) : null;
  return matched ? 'Links to existing client ' + matched.name : 'New client "' + raw + '" will be created';
}

Object.assign(window, { RequisitionForm });
