// orders.jsx — the ordering flow. This is where the clicks live.
// Two clinically trivial decisions ("restart the ACEi", "adjust the vanc") are
// run through the real shape of an Epic order: search a formulary of 18
// near-identical products, complete a 14-field composer, clear a stack of
// interruptive alerts, hit a hard stop for a field that was below the fold,
// then cosign. Nothing here is exaggerated for effect.
// Exports on window: OrdersPane

const COMPOSER_FIELDS = {
  lisinopril: [
    { key:'dose',      label:'Dose',                  req:true,  type:'select', opts:['2.5 mg','5 mg','10 mg','20 mg','40 mg'] },
    { key:'route',     label:'Route',                 req:true,  type:'select', opts:['PO','PO/NG','NG tube','Per feeding tube'] },
    { key:'freq',      label:'Frequency',             req:true,  type:'select', opts:['Daily','BID','TID','QHS','Every other day','Daily at 0900'] },
    { key:'prn',       label:'PRN',                   req:true,  type:'radio',  opts:['No','Yes'] },
    { key:'startDate', label:'Start date',            req:true,  type:'select', opts:['04/30/2026 (today)','05/01/2026','05/02/2026'] },
    { key:'startTime', label:'Start time',            req:true,  type:'select', opts:['0900 (next admin)','Now','1200','2100'] },
    { key:'duration',  label:'Duration',              req:true,  type:'select', opts:['Until discontinued','7 days','14 days','30 days','Single dose'] },
    { key:'dispense',  label:'Dispense qty',          req:true,  type:'text',   fill:'30' },
    { key:'refills',   label:'Refills',               req:true,  type:'select', opts:['0','1','2','3','5','11'] },
    { key:'admin',     label:'Admin instructions',    req:false, type:'text',   fill:'Hold for SBP < 100. Recheck BMP in 48 hours.' },
    { key:'priority',  label:'Priority',              req:true,  type:'select', opts:['Routine','STAT','Now','Timed'] },
    { key:'provider',  label:'Ordering provider',     req:true,  type:'select', opts:['Okonkwo, Daniel, MD','Weaver, Margaret R, MD','Okonkwo, D. [legacy]'] },
    { key:'dept',      label:'Department',            req:true,  type:'select', opts:['MGH White 7 — Nephrology','MGH White 7 — General Medicine','MGH Ambulatory Nephrology'] },
    // Last in the list, therefore below the fold, therefore the hard stop.
    { key:'indication',label:'Indication',            req:true,  type:'select', belowFold:true, opts:['Hypertension','Diabetic nephropathy','Proteinuria','Heart failure','CKD — renoprotection'] },
  ],
  vancomycin: [
    { key:'dose',      label:'Dose',                  req:true,  type:'select', opts:['750 mg','1,000 mg','1,250 mg','1,500 mg'] },
    { key:'route',     label:'Route',                 req:true,  type:'select', opts:['IV','IV piggyback','Central line'] },
    { key:'freq',      label:'Frequency',             req:true,  type:'select', opts:['q24h','q12h','q8h','Per pharmacy'] },
    { key:'infusion',  label:'Infusion time',         req:true,  type:'select', opts:['60 min','90 min','120 min','Per protocol'] },
    { key:'startTime', label:'Start time',            req:true,  type:'select', opts:['2000 (next dose)','Now','0800'] },
    { key:'monitor',   label:'Level monitoring',      req:true,  type:'select', opts:['Trough before 4th dose','Trough before 5th dose','Peak and trough','None'] },
    { key:'priority',  label:'Priority',              req:true,  type:'select', opts:['Routine','STAT','Now'] },
    { key:'provider',  label:'Ordering provider',     req:true,  type:'select', opts:['Okonkwo, Daniel, MD','Weaver, Margaret R, MD'] },
    { key:'indication',label:'Indication',            req:true,  type:'select', opts:['Healthcare-associated pneumonia','MRSA bacteraemia','Empiric coverage','Surgical prophylaxis'] },
  ],
};

const ALERT_SEQUENCE = {
  lisinopril: ['bpa', 'duplicate', 'allergy', 'interaction', 'formulary'],
  vancomycin: ['renal', 'formulary'],
};

function OrdersPane({ state, actions }) {
  const {
    view, drug, query, results, product, fields, openField,
    activeAlert, hardStop, cosign, pending, signed,
  } = state;

  return (
    <div style={op.body}>
      {view === 'list' && <OrderList pending={pending} signed={signed} actions={actions} />}
      {view === 'search' && <OrderSearch query={query} results={results} actions={actions} />}
      {view === 'composer' && (
        <OrderComposer drug={drug} product={product} fields={fields} openField={openField} actions={actions} />
      )}

      {activeAlert && (
        <window.AlertModal
          alert={window.ALERTS[activeAlert]}
          onAccept={actions.acceptAlert}
          onCancel={actions.cancelOrder}
        />
      )}
      {hardStop && <window.HardStopModal onReturn={actions.returnFromHardStop} />}
      {cosign && <window.CosignModal onSign={actions.completeSign} onCancel={actions.cancelCosign} />}
    </div>
  );
}

function OrderList({ pending, signed, actions }) {
  return (
    <>
      <div style={op.toolbar}>
        <button style={op.btnNew} data-gc="order-new" onClick={actions.newOrder}>+ New Order</button>
        <button style={op.btnTool}>Order Sets</button>
        <button style={op.btnTool}>Reconcile</button>
        <div style={{ flex: 1 }} />
        <button
          style={{ ...op.btnSign, ...(pending.length ? {} : op.btnSignOff) }}
          data-gc="order-sign"
          onClick={() => pending.length && actions.startSign()}>
          Sign Orders {pending.length ? `(${pending.length})` : ''}
        </button>
      </div>
      <div style={op.listWrap}>
        {pending.length === 0 && signed.length === 0 && (
          <div style={op.empty}>No unsigned orders for this encounter.</div>
        )}
        {pending.length > 0 && (
          <>
            <div style={op.listHead}>UNSIGNED ({pending.length})</div>
            {pending.map((o, i) => (
              <div key={i} style={op.orderRow}>
                <span style={op.pillUnsigned}>UNSIGNED</span>
                <span style={op.orderName}>{o.product}</span>
                <span style={op.orderSig}>{o.sig}</span>
              </div>
            ))}
          </>
        )}
        {signed.length > 0 && (
          <>
            <div style={op.listHead}>SIGNED TODAY ({signed.length})</div>
            {signed.map((o, i) => (
              <div key={i} style={op.orderRow}>
                <span style={op.pillSigned}>SIGNED</span>
                <span style={op.orderName}>{o.product}</span>
                <span style={op.orderSig}>{o.sig}</span>
              </div>
            ))}
          </>
        )}
      </div>
    </>
  );
}

function OrderSearch({ query, results, actions }) {
  return (
    <>
      <div style={op.toolbar}>
        <span style={op.searchLabel}>Order search</span>
        <input
          data-gc="order-search-input"
          style={op.searchInput}
          value={query}
          placeholder="Type at least 3 characters…"
          onChange={e => actions.setQuery(e.target.value)}
        />
        <button style={op.btnNew} data-gc="order-search-go" onClick={actions.runSearch}>Search</button>
        <div style={{ flex: 1 }} />
        <button style={op.btnTool} data-gc="order-search-cancel" onClick={actions.backToList}>Cancel</button>
      </div>
      <div style={op.listWrap}>
        {results.length === 0 && <div style={op.empty}>Enter a search term and press Search.</div>}
        {results.length > 0 && (
          <>
            <div style={op.listHead}>{results.length} MATCHING RECORDS — SELECT ONE</div>
            {results.map((r, i) => (
              <div key={i} style={op.resultRow} data-gc={`order-result-${i}`} onClick={() => actions.pickProduct(r)}>
                <span style={op.resultIdx}>{i + 1}</span>
                <span style={op.resultName}>{r}</span>
              </div>
            ))}
          </>
        )}
      </div>
    </>
  );
}

function OrderComposer({ drug, product, fields, openField, actions }) {
  const defs = COMPOSER_FIELDS[drug] || [];
  const filled = defs.filter(f => fields[f.key]).length;
  // Epic composes orders in a cramped modal, not a roomy page. The window is
  // deliberately shorter than its own contents: you cannot see the whole order
  // at once, and Indication — the field that blocks signing — sits below the fold.
  return (
    <div style={op.overlay}>
      <div style={op.modal}>
        <div style={op.modalHead}>
          <span style={op.composerTitle}>{product}</span>
          <span style={op.composerMeta}>{filled} of {defs.length} fields complete</span>
        </div>
        <div style={op.composerScroll} data-gc="composer-scroll">
          {defs.map(f => (
            <ComposerField
              key={f.key}
              def={f}
              value={fields[f.key]}
              open={openField === f.key}
              actions={actions}
            />
          ))}
          <div style={op.composerFoot}>
            Order will route to: MGH Inpatient Pharmacy · Verified by pharmacist before first administration
          </div>
        </div>
        <div style={op.modalFoot}>
          <span style={op.scrollHint}>▾ scroll for more fields</span>
          <div style={{ flex: 1 }} />
          <button style={op.btnTool} data-gc="composer-cancel" onClick={actions.cancelOrder}>Cancel</button>
          <button style={op.btnNew} data-gc="composer-accept" onClick={actions.acceptOrder}>Accept</button>
        </div>
      </div>
    </div>
  );
}

function ComposerField({ def, value, open, actions }) {
  return (
    <div style={{ ...op.field, position: 'relative' }}>
      <div style={op.fieldLabel}>
        {def.label}{def.req && <span style={op.req}> *</span>}
      </div>

      {def.type === 'radio' && (
        <div style={op.radioRow}>
          {def.opts.map((o, i) => (
            <span key={o} style={op.radioItem} data-gc={`opt-${def.key}-${i}`}
              onClick={() => actions.setField(def.key, o)}>
              <span style={{ ...op.radio, ...(value === o ? op.radioOn : {}) }} />
              <span style={op.radioLabel}>{o}</span>
            </span>
          ))}
        </div>
      )}

      {def.type === 'text' && (
        <input
          data-gc={`field-${def.key}`}
          style={{ ...op.input, ...(value ? {} : def.req ? op.inputEmpty : {}) }}
          value={value || ''}
          placeholder="—"
          onChange={e => actions.setField(def.key, e.target.value)}
          onClick={() => { if (!value) actions.setField(def.key, def.fill); }}
        />
      )}

      {def.type === 'select' && (
        <>
          <div
            data-gc={`field-${def.key}`}
            style={{ ...op.select, ...(value ? {} : def.req ? op.inputEmpty : {}) }}
            onClick={() => actions.toggleField(def.key)}>
            <span style={{ color: value ? '#111827' : '#9CA3AF' }}>{value || 'Select…'}</span>
            <span style={op.caret}>▾</span>
          </div>
          {open && (
            <div style={op.dropdown}>
              {def.opts.map((o, i) => (
                <div key={o} style={op.dropItem} data-gc={`opt-${def.key}-${i}`}
                  onClick={() => actions.setField(def.key, o)}>{o}</div>
              ))}
            </div>
          )}
        </>
      )}
    </div>
  );
}

const op = {
  body: { flex:1, display:'flex', flexDirection:'column', overflow:'hidden', position:'relative' },
  toolbar: { height:34, borderBottom:'1px solid #E5E7EB', display:'flex', alignItems:'center', gap:6, padding:'0 10px', background:'#EBF1F8', flexShrink:0 },
  btnNew: { fontSize:11, fontWeight:600, padding:'4px 10px', background:'#0066CC', color:'#fff', border:'1px solid #0066CC', borderRadius:2, cursor:'pointer' },
  btnTool: { fontSize:11, padding:'4px 9px', background:'#fff', color:'#4B5563', border:'1px solid #CBD5E1', borderRadius:2, cursor:'pointer' },
  btnSign: { fontSize:11, fontWeight:700, padding:'4px 12px', background:'#166534', color:'#fff', border:'1px solid #166534', borderRadius:2, cursor:'pointer' },
  btnSignOff: { background:'#CBD5E1', borderColor:'#CBD5E1', color:'#6B7280', cursor:'not-allowed' },
  searchLabel: { fontSize:11, fontWeight:700, color:'#4B5563' },
  searchInput: { width:250, border:'1px solid #9CA3AF', borderRadius:2, padding:'4px 7px', fontSize:11.5, fontFamily:'inherit' },
  listWrap: { flex:1, overflowY:'auto' },
  listHead: { fontSize:9.5, fontWeight:800, letterSpacing:0.7, color:'#6B7280', padding:'7px 10px 4px', background:'#F8FAFC', borderBottom:'1px solid #F3F4F6' },
  empty: { padding:'24px 10px', fontSize:11, color:'#9CA3AF', textAlign:'center' },
  orderRow: { display:'flex', alignItems:'center', gap:8, padding:'6px 10px', borderBottom:'1px solid #F3F4F6' },
  orderName: { fontSize:11, fontWeight:600, color:'#111827' },
  orderSig: { fontSize:11, color:'#6B7280' },
  pillUnsigned: { fontSize:9, fontWeight:700, background:'#FEF9C3', color:'#92400E', padding:'1px 5px', borderRadius:2 },
  pillSigned: { fontSize:9, fontWeight:700, background:'#DCFCE7', color:'#166534', padding:'1px 5px', borderRadius:2 },
  resultRow: { display:'flex', alignItems:'center', gap:9, padding:'5px 10px', borderBottom:'1px solid #F3F4F6', cursor:'pointer', fontSize:11 },
  resultIdx: { fontSize:10, color:'#9CA3AF', minWidth:14 },
  resultName: { color:'#0066CC' },
  composerTitle: { fontSize:12, fontWeight:700, color:'#111827' },
  composerMeta: { fontSize:10.5, color:'#9CA3AF', marginLeft:8 },
  overlay: { position:'absolute', inset:0, background:'rgba(17,24,39,0.42)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:700 },
  modal: { width:560, maxHeight:400, display:'flex', flexDirection:'column', background:'#fff', border:'1px solid #9CA3AF', borderRadius:4, boxShadow:'0 16px 48px rgba(0,0,0,0.3)', overflow:'hidden', borderTop:'3px solid #8B1A1A' },
  modalHead: { display:'flex', alignItems:'baseline', padding:'9px 12px', borderBottom:'1px solid #D1D5DB', background:'#D1D5DB', flexShrink:0 },
  modalFoot: { display:'flex', alignItems:'center', gap:7, padding:'8px 12px', borderTop:'1px solid #E5E7EB', background:'#F9FAFB', flexShrink:0 },
  scrollHint: { fontSize:10, color:'#9CA3AF' },
  composerScroll: { flex:1, overflowY:'auto', padding:'11px 13px', display:'flex', flexDirection:'column', gap:9 },
  field: { display:'flex', flexDirection:'column', gap:3 },
  fieldLabel: { fontSize:10.5, fontWeight:700, color:'#4B5563' },
  req: { color:'#DC2626' },
  select: { border:'1px solid #9CA3AF', borderRadius:2, padding:'4px 7px', fontSize:11, display:'flex', alignItems:'center', cursor:'pointer', background:'#fff', minHeight:23 },
  input: { border:'1px solid #9CA3AF', borderRadius:2, padding:'4px 7px', fontSize:11, fontFamily:'inherit', minHeight:23, color:'#111827' },
  inputEmpty: { background:'#FEF9C3', borderColor:'#D97706' },
  caret: { marginLeft:'auto', fontSize:9, color:'#6B7280' },
  dropdown: { position:'absolute', top:'100%', left:0, right:0, background:'#fff', border:'1px solid #9CA3AF', maxHeight:132, overflowY:'auto', zIndex:30, boxShadow:'0 4px 12px rgba(0,0,0,0.12)' },
  dropItem: { fontSize:11, padding:'5px 7px', cursor:'pointer', borderBottom:'1px solid #F3F4F6', color:'#111827' },
  radioRow: { display:'flex', gap:14, minHeight:23, alignItems:'center' },
  radioItem: { display:'flex', alignItems:'center', gap:5, cursor:'pointer' },
  radio: { width:11, height:11, borderRadius:'50%', border:'1.5px solid #9CA3AF' },
  radioOn: { border:'3.5px solid #0066CC' },
  radioLabel: { fontSize:11, color:'#111827' },
  composerFoot: { marginTop:14, paddingTop:9, borderTop:'1px solid #F3F4F6', fontSize:10, color:'#9CA3AF' },
};

Object.assign(window, { OrdersPane, COMPOSER_FIELDS, ALERT_SEQUENCE });
