/* Viamar Ops — Quote review queue (accept / adjust / confirm) */

function minutesSince(value) {
  const then = value ? new Date(String(value).replace(' ', 'T') + (String(value).includes('Z') ? '' : 'Z')) : null;
  if (!then || Number.isNaN(then.getTime())) return 'just now';
  const mins = Math.max(0, Math.round((Date.now() - then.getTime()) / 60000));
  if (mins < 1) return 'just now';
  if (mins < 60) return mins + 'm ago';
  const hrs = Math.round(mins / 60);
  if (hrs < 24) return hrs + 'h ago';
  return Math.round(hrs / 24) + 'd ago';
}

function cargoLabelForQuote(row, payload) {
  if (payload && payload.cargo) return payload.cargo;
  const type = row.cargo_type || (payload && payload.cargo_type);
  if (type === 'car') return 'Vehicle shipment';
  if (type === 'bike') return 'Motorcycle shipment';
  if (type === 'ship') return 'Boat or oversized cargo';
  if (type === 'box') return 'Household goods';
  return 'Shipment';
}

function checksForQuote(q) {
  const isVehicle = q.cargoType === 'car' || q.cargoType === 'bike';
  const isEU = /Germany|Italy|Portugal|Spain|Greece|France|Europe|DE|IT|PT|ES|GR/i.test(q.to || '');
  if (isVehicle) return [['Vehicle paid in full', false], ['Ownership / registration', false], ['Bill of sale', false], ['Canadian ID', false]];
  const checks = [['Prohibited-items declaration', false], ['Prepayment authorised', false]];
  if (isEU) checks.unshift(['ICS2 consignee details', false]);
  else checks.unshift(['Destination contact details', false]);
  return checks;
}

function breakdownForPrice(price) {
  const p = Number(price) || 0;
  return [
    ['Ocean / line freight', Math.round(p * 0.62)],
    ['Door pickup & handling', Math.round(p * 0.18)],
    ['Documentation & customs', Math.round(p * 0.12)],
    ['Cargo insurance (est.)', Math.round(p * 0.08)],
  ];
}

function normalizeWorkerQuote(row, payment) {
  const payload = row.payload_json || {};
  const destination = payload.destination || {};
  const to = [row.destination_city || destination.city, row.destination_country || destination.country].filter(Boolean).join(', ') ||
    row.destination_port || destination.port || 'Destination pending';
  const price = Number(row.estimate_price || row.final_price || payload.estimate_price || payload.amount || 0);
  const paymentAmount = payment && Number(payment.amount_cents || 0);
  const q = {
    id: row.id,
    customer: row.customer_name || payload.customer_name || 'New customer',
    email: row.email || payload.email || 'No email yet',
    cargo: cargoLabelForQuote(row, payload),
    cargoType: row.cargo_type || payload.cargo_type || payload.cargoType || 'box',
    from: row.origin || payload.origin || payload.from || 'Toronto, ON',
    to,
    method: row.method || payload.method || 'Method pending',
    service: row.service || payload.service || 'intl',
    aiVol: payload.aiVol || payload.ai_volume || 'Pending',
    aiPrice: price,
    submitted: minutesSince(row.created_at),
    sla: row.status === 'confirmed' ? 'Sent' : 'New',
    breakdown: breakdownForPrice(price),
    checks: [],
    payment: payment ? {
      id: payment.id,
      provider: payment.provider || 'manual',
      status: payment.status || 'pending',
      method: payment.method || 'unknown',
      amount: paymentAmount ? Math.round(paymentAmount / 100) : 0,
      captureMethod: payment.capture_method || 'manual',
    } : null,
    consent: payload.consent || {},
    source: 'worker',
  };
  q.checks = checksForQuote(q);
  return q;
}

function QuoteListItem({ q, active, handled, onClick }) {
  const handledState = handled && typeof handled === 'object' ? handled : null;
  const handledLabel = handledState && handledState.status === 'error' ? 'Capture failed' : handledState && handledState.status === 'capturing' ? 'Capturing' : 'Booked';
  const handledTone = handledState && handledState.status === 'error' ? T.red : handledState && handledState.status === 'capturing' ? T.amber : T.green;
  const handledBg = handledState && handledState.status === 'error' ? 'rgba(221,28,36,0.1)' : handledState && handledState.status === 'capturing' ? 'rgba(224,146,47,0.12)' : 'rgba(46,139,111,0.1)';
  return (
    <div onClick={onClick} style={{
      background: active ? '#fff' : 'transparent', borderRadius: 14, padding: 14, cursor: 'pointer',
      border: active ? '2px solid ' + T.red : '2px solid transparent',
      boxShadow: active ? '0 8px 22px rgba(221,28,36,0.1)' : 'none',
    }}
    onMouseEnter={e => { if (!active) e.currentTarget.style.background = '#fff'; }}
    onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 10 }}>
        <div style={{ width: 38, height: 38, borderRadius: 11, background: T.paper, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <Icon name={q.cargoType} size={20} color={T.navy} stroke={1.9} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: FB, fontWeight: 700, fontSize: 13.5, color: T.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{q.customer}</div>
          <div style={{ fontFamily: FM, fontSize: 10.5, color: T.muted }}>{q.id} · {q.to}</div>
        </div>
        {handled
          ? <span style={{ fontFamily: FM, fontSize: 9.5, fontWeight: 700, color: handledTone, background: handledBg, padding: '4px 8px', borderRadius: 999, textTransform: 'uppercase' }}>{handledLabel}</span>
          : <span style={{ fontFamily: FM, fontSize: 9.5, fontWeight: 700, color: q.sla.includes('1h') ? T.red : T.amber, background: q.sla.includes('1h') ? 'rgba(221,28,36,0.1)' : 'rgba(224,146,47,0.12)', padding: '4px 8px', borderRadius: 999, textTransform: 'uppercase' }}>{q.sla}</span>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <span style={{ fontFamily: FB, fontSize: 12, color: T.body, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 150 }}>{q.cargo}</span>
        <span style={{ fontFamily: FD, fontWeight: 800, fontSize: 15, color: T.ink, fontStretch: '110%' }}>${q.aiPrice.toLocaleString()}</span>
      </div>
    </div>
  );
}

function QuoteReview({ q, handled, onConfirm, onToast }) {
  const [price, setPrice] = React.useState(q.aiPrice);
  React.useEffect(() => { setPrice(q.aiPrice); }, [q.id]);
  const cost = q.breakdown.reduce((a, [, v]) => a + v, 0);
  const margin = price > 0 ? Math.round(((price - cost) / price) * 100) : 0;
  const payment = q.payment;
  const paymentReady = payment && payment.provider === 'stripe' && payment.status === 'requires_capture';
  const paymentDone = payment && payment.status === 'succeeded';
  const paymentTone = paymentDone ? T.green : paymentReady ? T.green : payment ? T.amber : T.red;
  const paymentBg = paymentDone || paymentReady ? 'rgba(46,139,111,0.08)' : payment ? 'rgba(224,146,47,0.09)' : 'rgba(221,28,36,0.08)';
  const paymentCopy = payment
    ? `${payment.provider} · ${payment.status}${payment.amount ? ' · $' + payment.amount.toLocaleString() : ''}`
    : 'No payment authorization on file yet';
  const consent = q.consent || {};
  const consentOk = consent.terms_accepted === true;
  const consentCopy = consentOk
    ? 'Terms accepted' + (consent.accepted_at ? ' · ' + consent.accepted_at : '')
    : consent.missing_reason
      ? 'Missing consent · ' + consent.missing_reason
      : 'Missing terms acceptance';
  const handledState = handled && typeof handled === 'object' ? handled : null;
  const isHandled = !!handled;
  const isWorking = handledState && handledState.status === 'capturing';
  const isError = handledState && handledState.status === 'error';
  const capture = handledState && handledState.payment_capture;
  const captureLabel = capture && capture.status
    ? 'Payment captured · ' + capture.status
    : capture === null
      ? 'No Stripe authorization found · booked without capture'
      : isError
        ? handledState.message || 'Confirmation failed'
        : 'Payment capture handled by backend';

  return (
    <div key={q.id} className="fadein" style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
      {/* header */}
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
        <div>
          <div style={{ fontFamily: FM, fontSize: 11, color: T.muted, letterSpacing: 0.5, marginBottom: 5 }}>{q.id} · submitted {q.submitted}</div>
          <Display size={24} color={T.ink}>{q.customer}</Display>
          <div style={{ fontFamily: FB, fontSize: 13, color: T.body, marginTop: 4 }}>{q.cargo} · {q.from} → {q.to}</div>
          <div style={{ fontFamily: FM, fontSize: 11.5, color: T.muted, marginTop: 3 }}>{q.email} · {q.method} · AI volume {q.aiVol}</div>
        </div>
        {isHandled
          ? <span style={{ fontFamily: FM, fontSize: 11, fontWeight: 700, color: isError ? T.red : isWorking ? T.amber : T.green, background: isError ? 'rgba(221,28,36,0.1)' : isWorking ? 'rgba(224,146,47,0.12)' : 'rgba(46,139,111,0.1)', padding: '7px 13px', borderRadius: 999, textTransform: 'uppercase', whiteSpace: 'nowrap' }}>{isError ? 'Capture failed' : isWorking ? 'Capturing...' : '✓ Booked'}</span>
          : <span style={{ fontFamily: FM, fontSize: 11, fontWeight: 700, color: T.red, background: 'rgba(221,28,36,0.1)', padding: '7px 13px', borderRadius: 999, textTransform: 'uppercase', whiteSpace: 'nowrap' }}>{q.sla}</span>}
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 18, alignItems: 'start' }}>
        {/* price editor */}
        <div style={{ background: T.navy, borderRadius: 18, padding: 22 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
            <Kicker color={T.red}>Confirm price</Kicker>
            <span style={{ fontFamily: FM, fontSize: 10.5, color: 'rgba(255,255,255,0.5)' }}>AI suggested ${q.aiPrice.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 14, padding: '14px 16px' }}>
            <span style={{ fontFamily: FD, fontWeight: 900, fontSize: 26, color: '#fff' }}>$</span>
            <input type="number" value={price} disabled={isHandled && !isError} onChange={e => setPrice(Number(e.target.value) || 0)}
              style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontFamily: FD, fontWeight: 900, fontSize: 30, color: '#fff', fontStretch: '120%', width: '100%' }} />
            <span style={{ fontFamily: FM, fontSize: 12, color: 'rgba(255,255,255,0.5)' }}>CAD</span>
          </div>
          <div style={{ display: 'flex', gap: 10, marginTop: 14 }}>
            <div style={{ flex: 1, background: 'rgba(255,255,255,0.06)', borderRadius: 12, padding: '11px 13px' }}>
              <div style={{ fontFamily: FM, fontSize: 8.5, letterSpacing: 0.8, color: 'rgba(255,255,255,0.45)', textTransform: 'uppercase' }}>Line cost</div>
              <div style={{ fontFamily: FB, fontWeight: 700, fontSize: 15, color: '#fff', marginTop: 3 }}>${cost.toLocaleString()}</div>
            </div>
            <div style={{ flex: 1, background: 'rgba(255,255,255,0.06)', borderRadius: 12, padding: '11px 13px' }}>
              <div style={{ fontFamily: FM, fontSize: 8.5, letterSpacing: 0.8, color: 'rgba(255,255,255,0.45)', textTransform: 'uppercase' }}>Margin</div>
              <div style={{ fontFamily: FB, fontWeight: 700, fontSize: 15, color: margin < 10 ? T.amber : T.green, marginTop: 3 }}>{margin}%</div>
            </div>
          </div>
          {!isHandled && (
            <div style={{ display: 'flex', gap: 7, marginTop: 12 }}>
              {[-100, -50, 50, 100].map(d => (
                <div key={d} onClick={() => setPrice(p => Math.max(0, p + d))} style={{ flex: 1, textAlign: 'center', padding: '7px 0', borderRadius: 9, background: 'rgba(255,255,255,0.08)', cursor: 'pointer', fontFamily: FM, fontSize: 11, fontWeight: 700, color: '#fff' }}>{d > 0 ? '+' : ''}{d}</div>
              ))}
            </div>
          )}
        </div>

        {/* compliance checks */}
        <div>
          <Kicker color={T.navy3} style={{ marginBottom: 10 }}>Compliance</Kicker>
          <Card pad={0} style={{ overflow: 'hidden' }}>
            {q.checks.map(([t, ok], i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', borderTop: i ? '1px solid ' + T.line2 : 'none' }}>
                <Icon name={ok ? 'checkC' : 'clock'} size={17} color={ok ? T.green : T.amber} stroke={2} />
                <span style={{ flex: 1, fontFamily: FB, fontWeight: 600, fontSize: 12.5, color: T.ink }}>{t}</span>
                {!ok && <span onClick={() => onToast('Reminder sent to ' + q.customer)} style={{ fontFamily: FM, fontSize: 9.5, fontWeight: 700, color: T.red, cursor: 'pointer', textTransform: 'uppercase' }}>Request</span>}
              </div>
            ))}
          </Card>
          <div style={{ marginTop: 14 }}>
            <Kicker color={T.navy3} style={{ marginBottom: 10 }}>Payment status</Kicker>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: paymentBg, border: '1px solid ' + (payment ? 'rgba(46,139,111,0.18)' : 'rgba(221,28,36,0.18)'), borderRadius: 14, padding: '12px 14px' }}>
              <Icon name={paymentDone || paymentReady ? 'checkC' : payment ? 'clock' : 'bell'} size={18} color={paymentTone} stroke={2} />
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: FB, fontWeight: 700, fontSize: 12.5, color: T.ink }}>{paymentReady ? 'Ready to capture' : paymentDone ? 'Captured' : payment ? 'Payment pending' : 'Needs payment setup'}</div>
                <div style={{ fontFamily: FB, fontSize: 11.5, color: T.body, marginTop: 2 }}>{paymentCopy}</div>
              </div>
            </div>
          </div>
          <div style={{ marginTop: 14 }}>
            <Kicker color={T.navy3} style={{ marginBottom: 10 }}>Consent record</Kicker>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: consentOk ? 'rgba(46,139,111,0.08)' : 'rgba(221,28,36,0.08)', border: '1px solid ' + (consentOk ? 'rgba(46,139,111,0.18)' : 'rgba(221,28,36,0.18)'), borderRadius: 14, padding: '12px 14px' }}>
              <Icon name={consentOk ? 'checkC' : 'bell'} size={18} color={consentOk ? T.green : T.red} stroke={2} />
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: FB, fontWeight: 700, fontSize: 12.5, color: T.ink }}>{consentOk ? 'Accepted' : 'Needs confirmation'}</div>
                <div style={{ fontFamily: FB, fontSize: 11.5, color: T.body, marginTop: 2 }}>{consentCopy}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* breakdown */}
      <div>
        <Kicker color={T.navy3} style={{ marginBottom: 10 }}>AI estimate breakdown</Kicker>
        <Card pad={0} style={{ overflow: 'hidden' }}>
          {q.breakdown.map(([l, v], i) => (
            <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '11px 16px', borderTop: i ? '1px solid ' + T.line2 : 'none' }}>
              <span style={{ fontFamily: FB, fontSize: 13, color: T.body }}>{l}</span>
              <span style={{ fontFamily: FM, fontSize: 12.5, fontWeight: 700, color: T.ink }}>${v.toLocaleString()}</span>
            </div>
          ))}
        </Card>
      </div>

      {/* actions */}
      {!isHandled || isError ? (
        <div style={{ display: 'flex', gap: 12 }}>
          <Btn variant="primary" icon="checkC" disabled={isWorking} onClick={() => onConfirm(q.id, price)}>{isError ? 'Retry capture & book' : 'Capture payment & book shipment'}</Btn>
          <Btn variant="ghost" icon="phone" onClick={() => onToast('Info request sent to ' + q.customer)}>Request info</Btn>
          <Btn variant="ghost" onClick={() => onToast('Quote ' + q.id + ' declined')} style={{ color: T.red, boxShadow: 'inset 0 0 0 1.5px rgba(221,28,36,0.3)' }}>Decline</Btn>
        </div>
      ) : (
        <div style={{ display: 'flex', alignItems: 'center', gap: 11, background: isWorking ? 'rgba(224,146,47,0.08)' : 'rgba(46,139,111,0.08)', border: '1px solid ' + (isWorking ? 'rgba(224,146,47,0.22)' : 'rgba(46,139,111,0.2)'), borderRadius: 14, padding: '14px 16px' }}>
          <Icon name={isWorking ? 'clock' : 'checkC'} size={20} color={isWorking ? T.amber : T.green} stroke={2} />
          <span style={{ fontFamily: FB, fontSize: 13, color: T.body }}>Confirmed at <span style={{ color: T.ink, fontWeight: 700 }}>${price.toLocaleString()}</span>. {captureLabel}. Shipment is <span style={{ fontWeight: 700 }}>{isWorking ? 'being booked' : 'Booked'}</span>.</span>
        </div>
      )}
    </div>
  );
}

function QuoteQueueScreen({ onToast }) {
  const [quotes, setQuotes] = React.useState(OPS_QUOTES);
  const [sel, setSel] = React.useState(OPS_QUOTES[0].id);
  const [handled, setHandled] = React.useState({});
  const [liveState, setLiveState] = React.useState(window.ViamarAPI && ViamarAPI.configured() && ViamarAPI.hasToken() ? 'loading' : 'mock');
  React.useEffect(() => {
    let alive = true;
    const loadLive = () => {
      if (!(window.ViamarAPI && ViamarAPI.configured() && ViamarAPI.hasToken())) {
        setLiveState(window.ViamarAPI && ViamarAPI.configured() ? 'token' : 'mock');
        return;
      }
      setLiveState('loading');
      Promise.all([
        ViamarAPI.listQuotes('submitted'),
        ViamarAPI.listPayments().catch(() => ({ payments: [] })),
      ])
        .then(([data, paymentData]) => {
          if (!alive) return;
          const paymentsByQuote = {};
          (paymentData.payments || []).forEach(p => {
            if (!p.quote_id || paymentsByQuote[p.quote_id]) return;
            paymentsByQuote[p.quote_id] = p;
          });
          const live = (data.quotes || []).map(row => normalizeWorkerQuote(row, paymentsByQuote[row.id]));
          if (live.length) {
            setQuotes(live);
            setSel(live[0].id);
            setLiveState('live');
          } else {
            setLiveState('empty');
          }
        })
        .catch(err => {
          if (!alive) return;
          setLiveState('mock');
          onToast('Live quote API unavailable — showing demo queue');
        });
    };
    loadLive();
    window.addEventListener('viamar:api-config', loadLive);
    return () => {
      alive = false;
      window.removeEventListener('viamar:api-config', loadLive);
    };
  }, []);
  const q = quotes.find(x => x.id === sel) || quotes[0] || OPS_QUOTES[0];
  const confirm = (id, price) => {
    const qq = quotes.find(x => x.id === id);
    const consent = qq && qq.consent ? qq.consent : {};
    const consentOk = consent.terms_accepted === true;
    let consentOverrideReason = '';
    if (qq && qq.source === 'worker' && !consentOk) {
      consentOverrideReason = window.prompt('Consent is missing for this quote. Enter the manual confirmation note before booking/capture.', 'Confirmed terms with customer by phone/email');
      if (!consentOverrideReason || !consentOverrideReason.trim()) {
        onToast('Booking cancelled — consent confirmation is required');
        return;
      }
    }
    setHandled(h => ({ ...h, [id]: { price, status: 'capturing' } }));
    const markDone = (result) => {
      setHandled(h => ({ ...h, [id]: { price, status: 'booked', payment_capture: result && result.payment_capture } }));
      if (window.ViamarStore && qq) ViamarStore.addConfirmedShipment ? ViamarStore.addConfirmedShipment(qq, price) : ViamarStore.confirmQuote(qq, price);
      onToast('Quote ' + id + ' booked at $' + price.toLocaleString() + (result && result.payment_capture && result.payment_capture.status ? ' · payment ' + result.payment_capture.status : ''));
    };
    const markError = (err) => {
      const message = (err && err.message) || 'Payment capture failed';
      setHandled(h => ({ ...h, [id]: { price, status: 'error', message } }));
      onToast('Quote ' + id + ' could not be booked: ' + message);
    };

    if (window.ViamarAPI && qq && qq.source === 'worker') {
      ViamarAPI.confirmQuote(id, price, { confirmed_by: 'ops-console', consent_override_reason: consentOverrideReason }).then(markDone).catch(markError);
    } else if (window.ViamarStore && qq) {
      ViamarStore.confirmQuote(qq, price);
      setHandled(h => ({ ...h, [id]: { price, status: 'booked', payment_capture: null } }));
      onToast('Quote ' + id + ' booked at $' + price.toLocaleString());
    }
    if (window.ViamarAnalytics && qq) ViamarAnalytics.track('shipment_advanced', {
      shipment_id: id,
      from_stage: 'quote_review',
      to_stage: 'booked',
      cargo_type: qq.cargoType,
      method: qq.method,
      price: price,
    });
  };
  return (
    <div style={{ display: 'flex', height: '100%' }}>
      <div style={{ width: 340, flexShrink: 0, borderRight: '1px solid ' + T.line, background: '#FBFBFC', display: 'flex', flexDirection: 'column' }}>
        <div style={{ padding: '26px 20px 12px' }}>
          <Display size={21} color={T.ink}>Quote queue</Display>
          <div style={{ fontFamily: FM, fontSize: 11, color: T.muted, marginTop: 4 }}>
            {quotes.filter(x => !handled[x.id]).length} awaiting review · {liveState === 'live' ? 'live API' : liveState === 'loading' ? 'loading live API' : liveState === 'empty' ? 'live API empty' : liveState === 'token' ? 'token needed' : 'demo data'}
          </div>
        </div>
        <div className="vscroll" style={{ flex: 1, overflowY: 'auto', padding: '6px 14px 20px', display: 'flex', flexDirection: 'column', gap: 6 }}>
          {quotes.map(x => <QuoteListItem key={x.id} q={x} active={sel === x.id} handled={handled[x.id]} onClick={() => setSel(x.id)} />)}
        </div>
      </div>
      <div className="vscroll" style={{ flex: 1, overflowY: 'auto', padding: '28px 34px 44px' }}>
        <QuoteReview q={q} handled={!!handled[q.id]} onConfirm={confirm} onToast={onToast} />
      </div>
    </div>
  );
}

Object.assign(window, { QuoteQueueScreen });
