/* global React, I, fmt, fmt0, SEED, Badge, Button, PhoneShell, api */
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ─── Debounce utility for API saves ────────────────────────────
function useDebouncedSave(saveFn, delay = 800) {
  const timeoutRef = useRef(null);
  const savingRef = useRef(false);
  const [saving, setSaving] = useState(false);

  const debouncedSave = useCallback((data) => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }
    timeoutRef.current = setTimeout(async () => {
      if (savingRef.current) return;
      savingRef.current = true;
      setSaving(true);
      try {
        await saveFn(data);
      } catch (err) {
        console.error('Auto-save failed:', err);
      } finally {
        savingRef.current = false;
        setSaving(false);
      }
    }, delay);
  }, [saveFn, delay]);

  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  return { debouncedSave, saving };
}

// ─── Pricing Builder ──────────────────────────────────────────
// Pricing model:
//   manufacturerCost = sum(hardware) + sum(extras) (read-only here)
//   target = manufacturerCost × multiplier (default 4)
//   user adjusts: materials lines, labour hours, profit (slider)
//   labour = hours × rate × crew
//   internalCost = manufacturer + materials + labour
//   finalCustomerPrice = internalCost + profit  (i.e. profit is the explicit margin)
//   gross margin % = profit / finalPrice
//   minimum recommended = (materials + labour) × 1.5  applied to the non-hardware portion

function PricingScreen({ onBack, onContinue, hardwareTotal, multiplier, setMultiplier, progress, quoteId }) {
  const [loading, setLoading] = useState(!!quoteId);
  const [loadError, setLoadError] = useState(null);
  // Quoted Materials = hardwareTotal (fixed, doesn't scale)
  // At ×3.5 default: total = hardware × 3.5
  //   Quoted Materials: hardware (28.57%)
  //   Gross Profit: 28.57% of total
  //   Sundry Materials: 7%
  //   Subcontractors: 3%
  //   Labour: ~32.86% (remainder)

  const baseTotal = hardwareTotal * 3.5;
  const initial = useMemo(() => ({
    profit: baseTotal * 0.2857,
    sundries: baseTotal * 0.07,
    subs: baseTotal * 0.03,
    labour: baseTotal - hardwareTotal - baseTotal * 0.2857 - baseTotal * 0.07 - baseTotal * 0.03
  }), [hardwareTotal, baseTotal]);

  const [profit, setProfit] = useState(initial.profit);
  const [sundries, setSundries] = useState(initial.sundries);
  const [subs, setSubs] = useState(initial.subs);
  const [labour, setLabour] = useState(initial.labour);
  const [activeBucket, setActiveBucket] = useState('master');

  // API integration: save pricing changes with debounce
  const savePricing = useCallback(async (pricingData) => {
    if (!quoteId || typeof api === 'undefined') return;
    await api.updatePricing(quoteId, pricingData);
  }, [quoteId]);

  const { debouncedSave, saving } = useDebouncedSave(savePricing, 800);

  // Auto-save when values change
  useEffect(() => {
    if (!quoteId || loading) return;
    const currentTotal = hardwareTotal + profit + sundries + subs + labour;
    const currentMultiplier = hardwareTotal > 0 ? currentTotal / hardwareTotal : 0;
    debouncedSave({ profit, sundries, subs, labour, multiplier: currentMultiplier });
  }, [profit, sundries, subs, labour, quoteId, loading, hardwareTotal]);

  // Load real pricing data from API
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const data = await api.getPricing(quoteId);
        if (cancelled) return;
        if (data.profit !== undefined) setProfit(data.profit);
        if (data.sundries !== undefined) setSundries(data.sundries);
        if (data.subs !== undefined) setSubs(data.subs);
        if (data.labour !== undefined) setLabour(data.labour);
      } catch (err) {
        if (!cancelled) setLoadError(err.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId]);

  const total = hardwareTotal + profit + sundries + subs + labour;
  const liveMultiplier = hardwareTotal > 0 ? total / hardwareTotal : 0;

  // Master slider: scale all non-hardware buckets uniformly to hit a new target multiplier
  const setMasterMultiplier = (newMult) => {
    const newTotal = hardwareTotal * newMult;
    const targetNonHardware = Math.max(0, newTotal - hardwareTotal);
    const currentNonHardware = profit + sundries + subs + labour;
    if (currentNonHardware <= 0) return;
    const k = targetNonHardware / currentNonHardware;
    setProfit(profit * k);
    setSundries(sundries * k);
    setSubs(subs * k);
    setLabour(labour * k);
  };

  const sliderRef = useRef(null);
  const [dragging, setDragging] = useState(false);
  const min = 2,max = 6;

  // Per-bucket independent ranges (scale 0…maxBucket)
  const bucketMaxFor = (key) => {
    const baseAtLoad = key === 'profit' ? initial.profit : key === 'sundries' ? initial.sundries : key === 'subs' ? initial.subs : initial.labour;
    return Math.max(baseAtLoad * 3, hardwareTotal * 1.5);
  };

  const setFromClientX = (clientX) => {
    const r = sliderRef.current.getBoundingClientRect();
    const ratio = Math.max(0, Math.min(1, (clientX - r.left) / r.width));
    if (activeBucket === 'master') {
      const raw = min + ratio * (max - min);
      const snapped = +(Math.round(raw / 0.05) * 0.05).toFixed(2);
      setMasterMultiplier(snapped);
    } else {
      const b = buckets.find((x) => x.key === activeBucket);
      if (!b || b.locked) return;
      const max$ = bucketMaxFor(activeBucket);
      b.set(Math.round(ratio * max$ / 50) * 50);
    }
  };

  const buckets = [
  { key: 'hardware', label: 'Quoted Materials', value: hardwareTotal, color: '#06B6D4', locked: true },
  { key: 'sundries', label: 'Sundry Materials', value: sundries, color: '#3B82F6', set: setSundries },
  { key: 'subs', label: 'Subcontractors', value: subs, color: '#8B5CF6', set: setSubs },
  { key: 'labour', label: 'Labour', value: labour, color: '#22C55E', set: setLabour },
  { key: 'profit', label: 'Gross Profit', value: profit, color: '#F97322', set: setProfit }];


  const pct = (v) => total > 0 ? v / total * 100 : 0;
  const active = buckets.find((b) => b.key === activeBucket);
  const isMaster = activeBucket === 'master';
  const sliderColor = isMaster ? '#FEC230' : (active ? active.color : '#FEC230');
  const sliderProgress = isMaster
    ? Math.max(0, Math.min(1, (liveMultiplier - min) / (max - min)))
    : (active && !active.locked ? Math.max(0, Math.min(1, active.value / bucketMaxFor(active.key))) : 0);

  const grossMargin = total > 0 ? profit / total : 0;
  const finalPrice = total;

  // Loading state
  if (loading) {
    return (
      <PhoneShell title="Set Quote Value" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
          <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading pricing data...</div>
        </div>
      </PhoneShell>
    );
  }

  // Error state
  if (loadError) {
    return (
      <PhoneShell title="Set Quote Value" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.AlertTriangle size={32} color="#EF4444" />
          <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Failed to load pricing</div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{loadError}</div>
          <Button variant="secondary" style={{ marginTop: 20 }} onClick={() => window.location.reload()}>Retry</Button>
        </div>
      </PhoneShell>
    );
  }

  return (
    <PhoneShell title="Set Quote Value" onBack={onBack} progress={progress}>
      <div style={{ padding: '12px 16px 200px' }}>
        {/* Auto-save indicator */}
        {saving && (
          <div style={{
            position: 'absolute', top: 8, right: 16, display: 'flex', alignItems: 'center', gap: 6,
            color: '#808080', fontSize: 11, zIndex: 10
          }}>
            <I.Loader size={12} style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
            <span>Saving...</span>
          </div>
        )}
        {/* Big total number */}
        <div style={{
          textAlign: 'center', padding: '20px 16px 14px',
          background: '#1f1f1f', border: '1px solid #404040', borderRadius: 10
        }}>
          <div style={{ color: '#808080', fontSize: 11, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase' }}>
            Quote total · ex GST
          </div>
          <div style={{
            color: '#fff', fontSize: 44, fontWeight: 700, letterSpacing: '-1.2px',
            fontVariantNumeric: 'tabular-nums', lineHeight: 1, marginTop: 6
          }}>{fmt0(finalPrice)}</div>
          <div style={{ color: '#B8B8B8', fontSize: 12, marginTop: 6, fontVariantNumeric: 'tabular-nums' }}>
            {fmt0(hardwareTotal)} × <span style={{ color: '#FEC230', fontWeight: 600 }}>{liveMultiplier.toFixed(2)}</span>
          </div>
        </div>

        {/* Stacked allocation bar */}
        <div style={{ marginTop: 18 }}>
          <div style={{ display: 'flex', height: 36, borderRadius: 6, overflow: 'hidden', gap: 2 }}>
            {buckets.map((b) =>
            <div key={b.key}
            onClick={() => !b.locked && setActiveBucket(b.key)}
            style={{
              width: `${pct(b.value)}%`, background: b.color,
              cursor: b.locked ? 'default' : 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: '#000', fontSize: 11, fontWeight: 700,
              outline: activeBucket === b.key ? '2px solid #fff' : 'none', outlineOffset: -2,
              overflow: 'hidden'
            }}>
                {pct(b.value) > 7 ? `${pct(b.value).toFixed(0)}%` : ''}
              </div>
            )}
          </div>

          {/* Legend / segment selector */}
          <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 6 }}>
            {buckets.map((b) => {
              const isActive = activeBucket === b.key;
              return (
                <button key={b.key}
                onClick={() => !b.locked && setActiveBucket(b.key)}
                disabled={b.locked}
                style={{
                  width: '100%', textAlign: 'left', cursor: b.locked ? 'default' : 'pointer',
                  fontFamily: 'inherit', background: isActive ? '#262626' : 'transparent',
                  border: `1px solid ${isActive ? b.color : '#262626'}`,
                  borderRadius: 6, padding: '8px 10px',
                  display: 'flex', alignItems: 'center', gap: 10,
                  transition: 'border-color .15s ease'
                }}>
                  <div style={{ width: 12, height: 12, borderRadius: 3, background: b.color, flexShrink: 0 }} />
                  <span style={{ flex: 1, color: '#D4D4D4', fontSize: 13, display: 'flex', alignItems: 'center', gap: 6 }}>
                    {b.label}
                    {b.locked && <I.Lock size={11} color="#808080" />}
                  </span>
                  <span style={{ color: '#808080', fontSize: 11, fontVariantNumeric: 'tabular-nums', minWidth: 38, textAlign: 'right' }}>
                    {pct(b.value).toFixed(1)}%
                  </span>
                  <span style={{ color: '#fff', fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums', minWidth: 70, textAlign: 'right' }}>
                    {fmt0(b.value)}
                  </span>
                </button>);

            })}
          </div>
        </div>

        {/* Context slider — master or per-bucket */}
        <div style={{ marginTop: 22 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
            <div style={{ color: '#D4D4D4', fontSize: 12, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }}>
              <div style={{ width: 8, height: 8, borderRadius: 2, background: sliderColor }} />
              {isMaster ? 'Quote value' : `Adjust ${active.label.toLowerCase()}`}
            </div>
            <div style={{ color: sliderColor, fontSize: 12, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>
              {isMaster ? `×${liveMultiplier.toFixed(2)}` : fmt0(active.value)}
            </div>
          </div>
          <div
            ref={sliderRef}
            onPointerDown={(e) => {e.target.setPointerCapture?.(e.pointerId);setDragging(true);setFromClientX(e.clientX);}}
            onPointerMove={(e) => {if (dragging) setFromClientX(e.clientX);}}
            onPointerUp={() => setDragging(false)}
            onPointerCancel={() => setDragging(false)}
            style={{ position: 'relative', height: 44, cursor: 'pointer', display: 'flex', alignItems: 'center', touchAction: 'none' }}>
            <div style={{ position: 'absolute', left: 0, right: 0, height: 6, borderRadius: 999, background: '#404040' }} />
            <div style={{
              position: 'absolute', left: 0, height: 6, borderRadius: 999,
              width: `${sliderProgress * 100}%`,
              background: sliderColor,
              transition: dragging ? 'none' : 'background-color .15s ease, width .12s ease'
            }} />
            <div style={{
              position: 'absolute',
              left: `calc(${sliderProgress * 100}% - 14px)`,
              width: 28, height: 28, borderRadius: '50%', background: sliderColor,
              border: '2px solid #171717',
              boxShadow: `0 0 0 1px ${sliderColor}, 0 0 12px ${sliderColor}80`,
              transition: dragging ? 'none' : 'left .12s ease, background-color .15s ease'
            }} />
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', color: '#808080', fontSize: 11, marginTop: 2 }}>
            {isMaster
              ? <><span>×2.0</span><span>×3.5</span><span>×6.0</span></>
              : <><span>$0</span><span>{fmt0(bucketMaxFor(activeBucket) / 2)}</span><span>{fmt0(bucketMaxFor(activeBucket))}</span></>
            }
          </div>
        </div>
      </div>

      {/* Sticky footer */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))'
      }}>
        <Button variant="primary" full onClick={() => onContinue({ finalPrice, materialsTotal: sundries, labourTotal: labour, profit, materials: [], labourHours: 0, grossMargin })}>
          See quote summary
        </Button>
      </div>
    </PhoneShell>);

}

const stepperBtn = {
  width: 44, height: 44, borderRadius: 8, background: '#171717', border: '1px solid #404040',
  color: '#fff', fontSize: 22, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer',
  display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0
};

// ── Final price hero card with multiplier toggle
function FinalPriceCard({ finalPrice, grossMargin, marginOk, target, multiplier, setMultiplier, hardwareTotal }) {
  return (
    <div style={{
      background: 'linear-gradient(135deg, #1f1a0e 0%, #262626 50%)',
      border: '1px solid #404040', borderRadius: 12, padding: 16, position: 'relative', overflow: 'hidden'
    }}>
      <div style={{
        position: 'absolute', top: -50, right: -50, width: 180, height: 180, borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(254,194,48,0.16), transparent 65%)'
      }} />
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', position: 'relative' }}>
        <div>
          <div style={{ color: '#FEC230', fontSize: 11, fontWeight: 700, letterSpacing: '0.08em' }}>CUSTOMER PRICE</div>
          <div style={{ color: '#fff', fontSize: 30, fontWeight: 700, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.8px', marginTop: 4, lineHeight: '36px' }}>
            {fmt0(finalPrice)}
          </div>
          <div style={{ color: '#B8B8B8', fontSize: 12, marginTop: 2 }}>ex GST · {(grossMargin * 100).toFixed(1)}% gross margin</div>
        </div>
        <Badge tone={marginOk ? 'success' : 'warning'}>{marginOk ? 'Healthy' : 'Below 33%'}</Badge>
      </div>

      {/* Multiplier toggle */}
      <div style={{
        marginTop: 14, padding: '8px 10px',
        background: 'rgba(0,0,0,0.28)', border: '1px solid #404040', borderRadius: 8,
        display: 'flex', alignItems: 'center', gap: 10, position: 'relative'
      }}>
        <I.Sparkles size={16} color="#FEC230" />
        <div style={{ flex: 1 }}>
          <div style={{ color: '#B8B8B8', fontSize: 11 }}>Default target multiplier</div>
          <div style={{ color: '#fff', fontSize: 13, fontWeight: 500, marginTop: 1, fontVariantNumeric: 'tabular-nums' }}>
            {fmt0(hardwareTotal)} × {multiplier} = {fmt0(target)}
          </div>
        </div>
        <div style={{
          display: 'inline-flex', background: '#171717', borderRadius: 6, padding: 2, gap: 0, border: '1px solid #404040'
        }}>
          {[3.5, 4].map((m) =>
          <button key={m} onClick={() => setMultiplier(m)} style={{
            border: 0, background: multiplier === m ? '#FEC230' : 'transparent',
            color: multiplier === m ? '#000' : '#fff', fontWeight: 600, fontSize: 12,
            padding: '4px 10px', borderRadius: 4, fontFamily: 'inherit', cursor: 'pointer',
            fontVariantNumeric: 'tabular-nums'
          }}>×{m}</button>
          )}
        </div>
      </div>
    </div>);

}

// ── Generic expanding section
function Section({ open, onToggle, icon, iconBg, iconColor, label, sub, value, children, warning }) {
  return (
    <div style={{
      background: '#262626', border: `1px solid ${warning ? 'rgba(249,115,34,0.45)' : '#404040'}`,
      borderRadius: 10, overflow: 'hidden'
    }}>
      <button onClick={onToggle} style={{
        width: '100%', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit',
        background: 'transparent', border: 0, padding: 12, display: 'flex', alignItems: 'center', gap: 12
      }}>
        <div style={{
          width: 36, height: 36, borderRadius: 8, background: iconBg, color: iconColor,
          display: 'flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 36px'
        }}>{icon}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ color: '#fff', fontSize: 14, fontWeight: 600, lineHeight: '20px' }}>{label}</div>
          <div style={{ color: warning ? '#F97322' : '#B8B8B8', fontSize: 12, lineHeight: '18px', marginTop: 1 }}>{sub}</div>
        </div>
        <div style={{ color: '#fff', fontSize: 15, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt0(value)}</div>
        <I.ChevronDown size={18} color="#808080" style={{ transform: open ? 'rotate(180deg)' : 'none', transition: 'transform .2s ease', flex: '0 0 18px' }} />
      </button>
      {open &&
      <div style={{ padding: '0 12px 12px', borderTop: '1px solid #404040', animation: 'vrvSlideDown .25s ease' }}>{children}</div>
      }
    </div>);

}

function ExpandRow({ icon, iconBg, iconColor, label, sub, value, locked }) {
  return (
    <div style={{
      background: '#262626', border: '1px solid #404040', borderRadius: 10, padding: 12,
      display: 'flex', alignItems: 'center', gap: 12
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 8, background: iconBg, color: iconColor,
        display: 'flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 36px'
      }}>{icon}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ color: '#fff', fontSize: 14, fontWeight: 600 }}>{label}</span>
          {locked &&
          <span style={{ color: '#808080', fontSize: 10, padding: '1px 5px', border: '1px solid #404040', borderRadius: 3, fontWeight: 500 }}>FROM PDF</span>
          }
        </div>
        <div style={{ color: '#B8B8B8', fontSize: 12, marginTop: 1 }}>{sub}</div>
      </div>
      <div style={{ color: '#fff', fontSize: 15, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt0(value)}</div>
    </div>);

}

// ── Material card (editable) — TRAiDMIN list-item card pattern
function MaterialCard({ m, editing, onEditStart, onEditEnd, onChange, onRemove }) {
  return (
    <div style={{
      background: '#262626', border: `1px solid ${editing ? '#FEC230' : '#404040'}`,
      borderRadius: 6, padding: 12, transition: 'border-color .15s ease'
    }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          {editing ?
          <input
            autoFocus
            value={m.name}
            onChange={(e) => onChange({ name: e.target.value })}
            style={{ ...editInput, fontWeight: 600, color: '#fff' }} /> :


          <div style={{ color: '#fff', fontSize: 14, fontWeight: 600, lineHeight: '20px' }}>{m.name}</div>
          }
          {editing ?
          <input
            value={m.desc}
            onChange={(e) => onChange({ desc: e.target.value })}
            style={{ ...editInput, fontSize: 12, color: '#B8B8B8', marginTop: 4 }} /> :


          <div style={{ color: '#B8B8B8', fontSize: 12, lineHeight: '18px', marginTop: 2 }}>{m.desc}</div>
          }
        </div>
        <button onClick={editing ? onEditEnd : onEditStart} style={{
          background: 'transparent', border: 0, color: editing ? '#FEC230' : '#808080', cursor: 'pointer',
          padding: 4, fontFamily: 'inherit'
        }}>
          {editing ? <I.Check size={16} strokeWidth={2.5} /> : <I.Pencil size={14} />}
        </button>
      </div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginTop: 10 }}>
        <div style={{ flex: 1 }}>
          <div style={{ color: '#808080', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Allowance</div>
          {editing ?
          <input value={m.qty} onChange={(e) => onChange({ qty: e.target.value })} style={{ ...editInput, marginTop: 2, fontSize: 13 }} /> :

          <div style={{ color: '#D4D4D4', fontSize: 13, marginTop: 2 }}>{m.qty}</div>
          }
        </div>
        <div style={{ flex: 1, textAlign: 'right' }}>
          <div style={{ color: '#808080', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Cost</div>
          {editing ?
          <input
            type="number" value={m.cost} onChange={(e) => onChange({ cost: Math.max(0, +e.target.value || 0) })}
            style={{ ...editInput, marginTop: 2, fontSize: 14, fontWeight: 700, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }} /> :


          <div style={{ color: '#fff', fontSize: 14, fontWeight: 700, fontVariantNumeric: 'tabular-nums', marginTop: 2 }}>{fmt0(m.cost)}</div>
          }
        </div>
        {editing &&
        <button onClick={onRemove} style={{
          background: 'transparent', border: 0, color: '#EF4444', cursor: 'pointer',
          padding: 6, alignSelf: 'flex-end'
        }}><I.Trash size={15} /></button>
        }
      </div>
    </div>);

}

const editInput = {
  background: '#262626', border: '1px solid #404040', borderRadius: 4,
  color: '#fff', fontFamily: 'inherit', padding: '4px 8px', outline: 'none', width: '100%',
  boxSizing: 'border-box', fontSize: 13
};

// ── Labour editor with slider
function LabourEditor({ hours, setHours, rate, crew, total }) {
  return (
    <div style={{ padding: '6px 0 8px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
        <div style={{ color: '#B8B8B8', fontSize: 12 }}>Total hours</div>
        <div style={{ color: '#fff', fontSize: 16, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{hours} h</div>
      </div>
      <Slider min={4} max={80} step={1} value={hours} onChange={setHours} />
      <div style={{ display: 'flex', justifyContent: 'space-between', color: '#808080', fontSize: 11, marginTop: 4 }}>
        <span>4 h</span><span>80 h</span>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8, marginTop: 14 }}>
        <KV label="Hours" value={`${hours}`} />
        <KV label="Rate" value={`$${rate}/h`} />
        <KV label="Crew" value={`${crew} px`} />
      </div>
      <div style={{
        marginTop: 10, padding: '10px 12px', background: '#171717', border: '1px solid #404040',
        borderRadius: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'center'
      }}>
        <span style={{ color: '#B8B8B8', fontSize: 12 }}>{hours} × ${rate} × {crew}</span>
        <span style={{ color: '#fff', fontSize: 16, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt0(total)}</span>
      </div>
    </div>);

}

function KV({ label, value }) {
  return (
    <div style={{ background: '#171717', border: '1px solid #404040', borderRadius: 6, padding: '8px 10px' }}>
      <div style={{ color: '#808080', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.05em' }}>{label}</div>
      <div style={{ color: '#fff', fontSize: 13, fontWeight: 600, marginTop: 2, fontVariantNumeric: 'tabular-nums' }}>{value}</div>
    </div>);

}

// ── Profit editor with slider + warning
function ProfitEditor({ profit, setProfit, installerCost, hardwareTotal, minRecommendedFinal, finalPrice, grossMargin, marginOk }) {
  // slider over profit value
  const min = 0;
  const max = Math.max(installerCost * 5 + hardwareTotal, profit * 1.4, 50000);
  return (
    <div style={{ padding: '6px 0 8px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
        <div style={{ color: '#B8B8B8', fontSize: 12 }}>Profit</div>
        <div style={{ color: '#fff', fontSize: 16, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt0(profit)}</div>
      </div>
      <Slider min={min} max={max} step={50} value={profit} onChange={setProfit} />
      <div style={{ display: 'flex', justifyContent: 'space-between', color: '#808080', fontSize: 11, marginTop: 4 }}>
        <span>$0</span><span>{fmt0(max)}</span>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 14 }}>
        <KV label="Final price" value={fmt0(finalPrice)} />
        <KV label="Gross margin" value={`${(grossMargin * 100).toFixed(1)}%`} />
      </div>

      {!marginOk &&
      <div style={{
        marginTop: 10, padding: 10, background: 'rgba(249,115,34,0.10)',
        border: '1px solid rgba(249,115,34,0.32)', borderRadius: 6,
        display: 'flex', gap: 10, alignItems: 'flex-start'
      }}>
          <I.AlertTriangle size={15} color="#F97322" style={{ marginTop: 1, flexShrink: 0 }} />
          <div style={{ color: '#D4D4D4', fontSize: 12, lineHeight: '18px' }}>
            Margin below 33%. Recommended minimum final price is <strong style={{ color: '#fff' }}>{fmt0(minRecommendedFinal)}</strong> — installer-supplied portion should clear (materials + labour) × 1.5.
          </div>
        </div>
      }
    </div>);

}

// ── Slider primitive (yellow themed)
function Slider({ min, max, step, value, onChange }) {
  const pct = (value - min) / (max - min) * 100;
  return (
    <div style={{ position: 'relative', height: 24, display: 'flex', alignItems: 'center' }}>
      <div style={{
        position: 'absolute', left: 0, right: 0, height: 4, background: '#404040', borderRadius: 2, top: '50%', transform: 'translateY(-50%)'
      }} />
      <div style={{
        position: 'absolute', left: 0, width: `${pct}%`, height: 4, background: '#FEC230',
        borderRadius: 2, top: '50%', transform: 'translateY(-50%)', boxShadow: '0 0 10px rgba(254,194,48,0.5)'
      }} />
      <input
        type="range" min={min} max={max} step={step} value={value}
        onChange={(e) => onChange(+e.target.value)}
        style={{
          position: 'absolute', inset: 0, width: '100%', opacity: 0, cursor: 'pointer',
          margin: 0, height: '100%'
        }} />
      
      <div style={{
        position: 'absolute', left: `calc(${pct}% - 10px)`, width: 20, height: 20, borderRadius: '50%',
        background: '#FEC230', border: '2px solid #171717', top: '50%', transform: 'translateY(-50%)',
        boxShadow: '0 0 0 1px #FEC230, 0 0 12px rgba(254,194,48,0.4)', pointerEvents: 'none'
      }} />
    </div>);

}

// ── Stacked split bar visualisation
function SplitBar({ hardware, materials, labour, profit }) {
  const total = hardware + materials + labour + profit;
  const segs = [
  { label: 'Hardware', value: hardware, color: '#FEC230' },
  { label: 'Materials', value: materials, color: '#3B82F6' },
  { label: 'Labour', value: labour, color: '#22C55E' },
  { label: 'Profit', value: profit, color: '#DC6C3D' }];

  return (
    <div style={{
      marginTop: 18, padding: 14, background: '#1f1f1f', border: '1px solid #404040', borderRadius: 10
    }}>
      <div style={{ color: '#D4D4D4', fontSize: 12, fontWeight: 700, letterSpacing: '0.02em', marginBottom: 10 }}>
        WHERE THE MONEY GOES
      </div>
      <div style={{ display: 'flex', height: 12, borderRadius: 4, overflow: 'hidden', background: '#262626' }}>
        {segs.map((s) =>
        <div key={s.label} style={{ width: `${s.value / total * 100}%`, background: s.color, transition: 'width .35s ease' }} />
        )}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 12 }}>
        {segs.map((s) =>
        <div key={s.label} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <div style={{ width: 8, height: 8, borderRadius: 2, background: s.color, flex: '0 0 8px' }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ color: '#B8B8B8', fontSize: 11 }}>{s.label}</div>
              <div style={{ color: '#fff', fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>
                {fmt0(s.value)} <span style={{ color: '#808080', fontWeight: 400, fontSize: 11 }}>· {(s.value / total * 100).toFixed(0)}%</span>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>);

}

window.PricingScreen = PricingScreen;

// ─── Set Price (Step 1: total target) ────────────────────────
function SetPriceScreen({ onBack, onContinue, hardwareTotal, multiplier }) {
  const [unit, setUnit] = useState('dollar');
  const finalPrice = hardwareTotal * multiplier;

  return (
    <PhoneShell title="Set Quote Price" subtitle={fmt0(finalPrice)} onBack={onBack} progress={progress}>
      <div style={{ padding: '8px 16px 140px' }}>
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 18 }}>
          <div style={{
            display: 'inline-flex', background: '#262626', border: '1px solid #404040',
            borderRadius: 999, padding: 3, gap: 2
          }}>
            {['dollar', 'percent'].map((u) => {
              const active = unit === u;
              return (
                <button key={u} onClick={() => setUnit(u)} style={{
                  width: 36, height: 28, borderRadius: 999, border: 0, cursor: 'pointer',
                  background: active ? '#FEC230' : 'transparent',
                  color: active ? '#000' : '#B8B8B8',
                  fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
                  display: 'flex', alignItems: 'center', justifyContent: 'center'
                }}>{u === 'dollar' ? '$' : '%'}</button>);

            })}
          </div>
        </div>

        <div style={{
          textAlign: 'center', padding: '24px 16px 16px',
          background: '#1f1f1f', border: '1px solid #404040', borderRadius: 8
        }}>
          <div style={{
            color: '#fff', fontSize: 56, fontWeight: 700, letterSpacing: '-1.5px',
            fontVariantNumeric: 'tabular-nums', lineHeight: 1
          }}>
            {unit === 'dollar' ? fmt0(finalPrice) : `${(multiplier * 100).toFixed(0)}%`}
          </div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>
            {unit === 'dollar' ?
            `${fmt0(hardwareTotal)} hardware × ${multiplier.toFixed(2)}` :
            `${fmt0(finalPrice)} customer price`}
          </div>
        </div>
      </div>

      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))'
      }}>
        <Button variant="primary" full onClick={onContinue}>See quote summary</Button>
      </div>
    </PhoneShell>);

}

// ─── Quote Summary ───────────────────────────────────────────
function PriceSummaryScreen({ onBack, onContinue, onAddClient, onEditProfit, onEditMaterials, onEditLabour, onEditCopy, hardwareTotal, multiplier, progress, quoteId, v3Pricing }) {
  const [loading, setLoading] = useState(!!quoteId && !v3Pricing);
  const [loadError, setLoadError] = useState(null);
  const [pricingData, setPricingData] = useState(null);
  const [quoteDetails, setQuoteDetails] = useState(null);

  // These must be at the top level before any conditional returns (React hooks rule)
  const [matsOpen, setMatsOpen] = useState(true);
  const [labourOpen, setLabourOpen] = useState(true);
  const [profitOpen, setProfitOpen] = useState(false);

  // GST toggle - default to including GST
  const [includeGst, setIncludeGst] = useState(true);

  // V3 pricing state for when we need to fetch it ourselves
  const [localV3Pricing, setLocalV3Pricing] = useState(null);

  // Load pricing data and quote details from API
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }

    let cancelled = false;
    (async () => {
      try {
        // Always load quote details
        const quoteResponse = await api.getQuote(quoteId);
        if (cancelled) return;
        setQuoteDetails(quoteResponse?.data || quoteResponse);

        // If v3Pricing was passed from HardwareScreen, use it
        if (v3Pricing) {
          setLoading(false);
          return;
        }

        // Otherwise, fetch V3 pricing ourselves (for existing quotes opened from dashboard)
        let v3Success = false;
        try {
          const v3Data = await api.calculateV3Pricing(quoteId, 15, 3.5);
          if (v3Data.success && v3Data.data) {
            setLocalV3Pricing(v3Data.data);
            v3Success = true;
          }
        } catch (v3Err) {
          console.warn('V3 pricing fetch failed:', v3Err);
        }

        // Fall back to old pricing API if V3 didn't work
        if (!v3Success) {
          try {
            const pricingResponse = await api.getPricing(quoteId);
            const data = pricingResponse?.data || pricingResponse;
            setPricingData(data);
          } catch (pricingErr) {
            console.warn('Old pricing fetch failed:', pricingErr);
          }
        }
      } catch (err) {
        if (!cancelled) setLoadError(err.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId, v3Pricing]);

  // V3: Use v3Pricing (from props) or localV3Pricing (fetched here) if available
  const effectiveV3Pricing = v3Pricing || localV3Pricing;
  const isV3 = !!effectiveV3Pricing;
  const effectiveHardwareTotal = isV3 ? effectiveV3Pricing.pricing.breakdown.hardware : (pricingData?.hardware_total || hardwareTotal || 0);
  const effectiveMultiplier = isV3 ? (effectiveV3Pricing.pricing.totalQuoteValue / effectiveV3Pricing.pricing.breakdown.hardware) : (pricingData?.multiplier || multiplier || 4.0);

  // Calculate final price with proper fallbacks
  let finalPrice = isV3 ? effectiveV3Pricing.pricing.totalQuoteValue : pricingData?.final_price;
  if (!finalPrice || finalPrice <= 0) {
    finalPrice = effectiveHardwareTotal * effectiveMultiplier;
  }

  const profit = isV3 ? effectiveV3Pricing.pricing.breakdown.profit : (pricingData?.gross_profit || (finalPrice - effectiveHardwareTotal) || 0);
  const materialsTotal = isV3 ? effectiveV3Pricing.pricing.breakdown.materials : (pricingData?.materials_total || 0);
  const labourTotal = isV3 ? effectiveV3Pricing.pricing.breakdown.labour : (pricingData?.labour_total || 0);
  const marginPct = isV3 ? Math.round(effectiveV3Pricing.pricing.grossMarginPercent) : (finalPrice > 0 ? Math.round((profit / finalPrice) * 100) : 0);

  // Loading state
  if (loading) {
    return (
      <PhoneShell title="Quote Summary" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
          <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading quote summary...</div>
        </div>
      </PhoneShell>
    );
  }

  // Error state
  if (loadError) {
    return (
      <PhoneShell title="Quote Summary" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.AlertTriangle size={32} color="#EF4444" />
          <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Failed to load quote</div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{loadError}</div>
          <Button variant="secondary" style={{ marginTop: 20 }} onClick={() => window.location.reload()}>Retry</Button>
        </div>
      </PhoneShell>
    );
  }

  // Check if quote is still processing (no pricing data available)
  const quoteStatus = quoteDetails?.status;
  const isProcessing = quoteStatus && !['draft', 'Draft'].includes(quoteStatus);
  if (isProcessing && finalPrice === 0 && !isV3) {
    return (
      <PhoneShell title="Quote Summary" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.Clock size={32} color="#FEC230" />
          <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Quote Still Processing</div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8, lineHeight: 1.5 }}>
            This quote hasn't finished processing yet.<br/>
            Status: {quoteStatus}
          </div>
          <Button variant="secondary" style={{ marginTop: 20 }} onClick={onBack}>Go Back</Button>
        </div>
      </PhoneShell>
    );
  }

  const fmt2 = (n) => '$' + (n || 0).toLocaleString('en-AU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

  return (
    <PhoneShell
      title="Quote Summary"
      onBack={onBack}
      progress={progress}
    >
      <div style={{ padding: '8px 20px 140px' }}>
        {/* Client / status row */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
          <div style={{ color: '#737373', fontSize: 22, fontWeight: 700, letterSpacing: '-0.3px', lineHeight: 1.15 }}>
            No client assigned
          </div>
          <div style={{
            background: '#404040', color: '#D4D4D4', fontSize: 13, fontWeight: 500,
            padding: '6px 14px', borderRadius: 999, whiteSpace: 'nowrap'
          }}>Draft</div>
        </div>

        <button onClick={onAddClient} style={{
          marginTop: 10, display: 'inline-flex', alignItems: 'center', gap: 6,
          background: 'rgba(220,38,38,0.14)', border: 0, color: '#F87171',
          fontFamily: 'inherit', fontSize: 14, fontWeight: 600,
          padding: '7px 12px', borderRadius: 8, cursor: 'pointer',
        }}>
          <span style={{ fontSize: 16, fontWeight: 700, lineHeight: 1 }}>+</span>
          Add Client
        </button>

        <div style={{ color: '#fff', fontSize: 15, fontWeight: 500, marginTop: 14 }}>No job location added</div>
        <div style={{ color: '#737373', fontSize: 13, marginTop: 4 }}>Last updated today</div>

        {/* Billing */}
        <div style={{ marginTop: 36 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ color: '#A3A3A3', fontSize: 14 }}>Billing</div>
            {/* GST Toggle */}
            <button
              onClick={() => setIncludeGst(v => !v)}
              style={{
                display: 'flex', alignItems: 'center', gap: 8,
                background: 'transparent', border: 0, padding: 0, cursor: 'pointer', fontFamily: 'inherit',
              }}
            >
              <span style={{ color: '#A3A3A3', fontSize: 12 }}>{includeGst ? 'inc GST' : 'ex GST'}</span>
              <div style={{
                width: 40, height: 22, borderRadius: 11,
                background: includeGst ? '#FEC230' : '#404040',
                position: 'relative', transition: 'background 0.2s',
              }}>
                <div style={{
                  position: 'absolute', top: 2, left: includeGst ? 20 : 2,
                  width: 18, height: 18, borderRadius: 9,
                  background: '#fff', transition: 'left 0.2s',
                }} />
              </div>
            </button>
          </div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 6 }}>
            <div style={{
              color: '#fff', fontSize: 40, fontWeight: 700, letterSpacing: '-0.8px',
              fontVariantNumeric: 'tabular-nums', lineHeight: 1
            }}>{fmt2(includeGst ? finalPrice * 1.1 : finalPrice)}</div>
            <div style={{ color: '#A3A3A3', fontSize: 13 }}>{includeGst ? 'inc GST' : 'ex GST'}</div>
          </div>
        </div>

        {/* Price breakdown header */}
        <div style={{ marginTop: 30, marginBottom: 10 }}>
          <div style={{ color: '#A3A3A3', fontSize: 14 }}>Price breakdown</div>
        </div>

        {/* Materials - VRV System + auto-allocated materials combined */}
        <div style={{ background: '#262626', borderRadius: 12, overflow: 'hidden' }}>
          <button onClick={onEditMaterials} style={{
            width: '100%', background: 'transparent', border: 0, padding: '16px 16px',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
          }}>
            <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <span style={{ color: '#fff', fontSize: 17, fontWeight: 600 }}>Materials</span>
              {isV3 && <span style={{ color: '#A3A3A3', fontSize: 12 }}>VRV System + {effectiveV3Pricing.allocation.materials.length} items</span>}
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ color: '#fff', fontSize: 17, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{fmt2(effectiveHardwareTotal + materialsTotal)}</span>
              <I.ChevronRight size={18} color="#A3A3A3"/>
            </span>
          </button>
        </div>

        {/* Labour - Click to edit */}
        <div style={{ marginTop: 12, background: '#262626', borderRadius: 12, overflow: 'hidden' }}>
          <button onClick={onEditLabour} style={{
            width: '100%', background: 'transparent', border: 0, padding: '16px 16px',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
          }}>
            <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <span style={{ color: '#fff', fontSize: 17, fontWeight: 600 }}>Labour</span>
              {isV3 && <span style={{ color: '#A3A3A3', fontSize: 12 }}>2 HVAC Technicians</span>}
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ color: '#fff', fontSize: 17, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{fmt2(labourTotal)}</span>
              <I.ChevronRight size={18} color="#A3A3A3"/>
            </span>
          </button>
        </div>

        {/* Net Profit - Click to edit */}
        <div style={{ marginTop: 12, background: '#262626', borderRadius: 12, overflow: 'hidden' }}>
          <button onClick={onEditProfit} style={{
            width: '100%', background: 'transparent', border: 0, padding: '16px 16px',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
          }}>
            <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <span style={{ color: '#fff', fontSize: 17, fontWeight: 600 }}>Net Profit</span>
              <span style={{ color: '#A3A3A3', fontSize: 12 }}>{marginPct}% margin</span>
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ color: '#4CAF50', fontSize: 17, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{fmt2(profit)}</span>
              <I.ChevronRight size={18} color="#A3A3A3"/>
            </span>
          </button>
        </div>

        {/* Job overview */}
        <div style={{ color: '#A3A3A3', fontSize: 14, marginTop: 28, marginBottom: 10 }}>Job overview</div>
        <button onClick={onEditCopy} style={{
          width: '100%', background: '#262626', border: 0, borderRadius: 12,
          padding: '16px 16px', fontFamily: 'inherit', textAlign: 'left', cursor: 'pointer',
          display: 'flex', flexDirection: 'column', gap: 6,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ color: '#fff', fontSize: 16, fontWeight: 600 }}>Job description</span>
            <I.ChevronRight size={18} color="#A3A3A3"/>
          </div>
          <div style={{ color: '#D4D4D4', fontSize: 14, lineHeight: '20px' }}>
            {quoteDetails?.project_name || quoteDetails?.manufacturer
              ? `${quoteDetails.manufacturer || 'HVAC'} Installation${quoteDetails.project_name ? ` — ${quoteDetails.project_name}` : ''}`
              : 'No job description added'}
          </div>
        </button>

        {/* Client details */}
        <div style={{ color: '#A3A3A3', fontSize: 14, marginTop: 28, marginBottom: 10 }}>Client details</div>
        <button onClick={onAddClient} style={{
          width: '100%', background: '#262626', border: 0, borderRadius: 12,
          padding: '18px 16px', fontFamily: 'inherit', textAlign: 'left', cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        }}>
          <span style={{ color: '#fff', fontSize: 16, fontWeight: 600 }}>Add client</span>
          <I.ChevronRight size={18} color="#A3A3A3"/>
        </button>
      </div>

      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))'
      }}>
        <button onClick={onContinue} style={{
          width: '100%', background: '#FEC230', color: '#171717',
          fontFamily: 'inherit', fontSize: 16, fontWeight: 700,
          border: 0, borderRadius: 12, padding: '16px 20px', cursor: 'pointer',
        }}>Review and Send Quote</button>
      </div>
    </PhoneShell>);

}

window.SetPriceScreen = SetPriceScreen;
window.PriceSummaryScreen = PriceSummaryScreen;

// ─── Client Details ──────────────────────────────────────────
function ClientDetailsScreen({ onBack, onFinish, quoteId }) {
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [phone, setPhone] = React.useState('');
  const [billing, setBilling] = React.useState('');
  const [sameAddress, setSameAddress] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [loading, setLoading] = React.useState(!!quoteId);

  // Load existing client data
  React.useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    (async () => {
      try {
        const response = await api.getClient(quoteId);
        if (response?.data) {
          setName(response.data.name || '');
          setEmail(response.data.email || '');
          setPhone(response.data.phone || '');
          setBilling(response.data.billing_address || '');
        }
      } catch (err) {
        console.warn('Failed to load client:', err);
      } finally {
        setLoading(false);
      }
    })();
  }, [quoteId]);

  const handleFinish = async () => {
    if (quoteId && typeof api !== 'undefined') {
      setSaving(true);
      try {
        await api.updateClient(quoteId, {
          name: name.trim(),
          email: email.trim(),
          phone: phone.trim(),
          billing_address: billing.trim(),
        });
      } catch (err) {
        console.error('Failed to save client:', err);
      }
      setSaving(false);
    }
    onFinish();
  };

  const labelStyle = { color: '#fff', fontSize: 14, fontWeight: 500, marginBottom: 8 };
  const inputStyle = {
    width: '100%', background: '#262626', border: '1px solid #2C2C2C',
    borderRadius: 10, padding: '14px 14px',
    color: '#fff', fontSize: 14, fontFamily: 'inherit',
    outline: 'none', boxSizing: 'border-box',
  };
  const placeholderColor = '#737373';

  return (
    <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
      {/* Header */}
      <div style={{
        marginTop: 62,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '12px 16px 10px',
      }}>
        <button onClick={onBack} aria-label="Back" style={{
          width: 36, height: 36, borderRadius: 8, border: 0, background: 'transparent',
          color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        }}><I.ChevronLeft size={22}/></button>
        <div style={{ color: '#fff', fontSize: 16, fontWeight: 600 }}>Client Details</div>
        <button onClick={onBack} aria-label="Close" style={{
          width: 36, height: 36, borderRadius: 8, border: 0, background: 'transparent',
          color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        }}><I.X size={20}/></button>
      </div>
      {/* Yellow progress bar (1/3) */}
      <div style={{ height: 3, background: '#2C2C2C', position: 'relative' }}>
        <div style={{ position: 'absolute', top: 0, left: 0, height: '100%', width: '33%', background: '#FEC230' }}/>
      </div>

      {/* Body */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 20px 120px' }}>
        <div style={{ color: '#fff', fontSize: 26, fontWeight: 700, letterSpacing: '-0.3px' }}>Client Details</div>
        <div style={{ color: '#A3A3A3', fontSize: 14, marginTop: 4 }}>Review and confirm client details</div>

        <div style={{ marginTop: 26 }}>
          <div style={{ color: '#fff', fontSize: 16, fontWeight: 600 }}>Billing details</div>
        </div>

        <div style={{ marginTop: 18 }}>
          <div style={labelStyle}>Name</div>
          <input value={name} onChange={(e) => setName(e.target.value)}
            placeholder="Enter clients first name and surname"
            style={inputStyle}/>
        </div>

        <div style={{ marginTop: 18 }}>
          <div style={labelStyle}>Email</div>
          <input value={email} onChange={(e) => setEmail(e.target.value)} type="email"
            placeholder="Enter clients email address"
            style={inputStyle}/>
        </div>

        <div style={{ marginTop: 18 }}>
          <div style={labelStyle}>Phone</div>
          <input value={phone} onChange={(e) => setPhone(e.target.value)} type="tel"
            placeholder="Enter clients phone number"
            style={inputStyle}/>
        </div>

        <div style={{ marginTop: 18 }}>
          <div style={labelStyle}>Billing address</div>
          <input value={billing} onChange={(e) => setBilling(e.target.value)}
            placeholder="Enter clients billing address"
            style={inputStyle}/>
        </div>

        <div style={{ marginTop: 22 }}>
          <div style={{ color: '#fff', fontSize: 14, fontWeight: 500 }}>Site address</div>
          <button onClick={() => setSameAddress(s => !s)} style={{
            display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 10,
            background: 'transparent', border: 0, padding: 0, cursor: 'pointer', fontFamily: 'inherit',
          }}>
            <span style={{
              width: 22, height: 22, borderRadius: 11,
              background: sameAddress ? '#FEC230' : 'transparent',
              border: sameAddress ? '0' : '1.5px solid #525252',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              {sameAddress && <span style={{ color: '#171717', fontSize: 13, fontWeight: 700, lineHeight: 1 }}>✓</span>}
            </span>
            <span style={{ color: '#D4D4D4', fontSize: 14 }}>Same as billing address</span>
          </button>
        </div>
      </div>

      {/* Footer */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))',
      }}>
        <button onClick={handleFinish} disabled={saving || loading} style={{
          width: '100%', background: saving || loading ? '#666' : '#FEC230', color: '#171717',
          fontFamily: 'inherit', fontSize: 16, fontWeight: 700,
          border: 0, borderRadius: 12, padding: '16px 20px', cursor: saving || loading ? 'not-allowed' : 'pointer',
        }}>{saving ? 'Saving...' : loading ? 'Loading...' : 'Finish Quote'}</button>
      </div>
    </div>
  );
}

window.ClientDetailsScreen = ClientDetailsScreen;

// ─── Net Profit (edit) ───────────────────────────────────────
function NetProfitScreen({ onBack, onSave, hardwareCost = 0, materialsTotal = 2577, labourTotal = 800, initialProfit = 1688, finalPrice, quoteId, v3Pricing }) {
  const [profit, setProfit] = React.useState(initialProfit);
  const [mode, setMode] = React.useState('pct'); // 'pct' | 'dollar'

  // Update profit when initialProfit changes (e.g., when V3 data loads)
  React.useEffect(() => {
    if (initialProfit > 0) {
      setProfit(initialProfit);
    }
  }, [initialProfit]);

  // Auto-save when going back (no API call needed)
  const handleBack = () => {
    if (onSave) onSave(profit);
    else onBack();
  };

  // V3: Total is fixed (Hardware × Multiplier), not calculated from components
  // External costs = Hardware + Materials (what you pay suppliers)
  const externalCosts = hardwareCost + materialsTotal;
  const total = finalPrice || (externalCosts + labourTotal + profit);
  const taxTotal = total * 1.10;

  // Calculate percentages based on the fixed total
  const extPct = total > 0 ? Math.round((externalCosts / total) * 100) : 0;
  const labPct = total > 0 ? Math.round((labourTotal / total) * 100) : 0;
  const profPct = Math.max(0, 100 - extPct - labPct);
  const marginPct = total > 0 ? Math.round((profit / total) * 100) : 0;

  const fmt = (n) => '$' + Number(n).toLocaleString('en-AU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const fmt0 = (n) => '$' + Math.round(n).toLocaleString('en-AU');

  // Slider 0..max profit — derive from finalPrice if provided, else fall back to 3× initial
  const maxProfit = finalPrice ? Math.max(finalPrice - externalCosts - labourTotal, initialProfit * 1.2, 1000) : Math.max(initialProfit * 3, 5000);

  return (
    <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
      <CustomHeader title="Net Profit" subtitle={fmt(profit)} onBack={handleBack}/>

      {/* Body */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '8px 20px 20px' }}>
        {/* $ / % toggle */}
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 8 }}>
          <div style={{
            display: 'inline-flex', alignItems: 'center',
            background: '#262626', borderRadius: 999, padding: 4, gap: 4,
          }}>
            {[
              { key: 'dollar', label: '$' },
              { key: 'pct', label: '%' },
            ].map(o => {
              const active = mode === o.key;
              return (
                <button key={o.key} onClick={() => setMode(o.key)} style={{
                  width: 36, height: 36, borderRadius: 999, border: 0, cursor: 'pointer',
                  background: active ? '#FEC230' : 'transparent',
                  color: active ? '#171717' : '#D4D4D4',
                  fontFamily: 'inherit', fontSize: 16, fontWeight: 700,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>{o.label}</button>
              );
            })}
          </div>
        </div>

        {/* Big number card */}
        <div style={{
          marginTop: 14, background: '#262626', borderRadius: 12,
          padding: '24px 16px', textAlign: 'center',
        }}>
          <div style={{
            color: '#fff', fontWeight: 700, letterSpacing: '-1px',
            fontVariantNumeric: 'tabular-nums', lineHeight: 1,
            fontSize: mode === 'pct' ? 64 : 52,
          }}>
            {mode === 'pct' ? `${marginPct}%` : fmt(profit)}
          </div>
        </div>
        <div style={{ textAlign: 'center', marginTop: 12, color: '#D4D4D4', fontSize: 14 }}>
          {mode === 'pct' ? `${fmt(profit)} net profit` : `${marginPct}% margin`}
        </div>

        {/* Segmented bar */}
        <div style={{
          marginTop: 18, display: 'flex', borderRadius: 8, overflow: 'hidden',
          height: 38, fontFamily: 'inherit',
        }}>
          <div style={{
            flex: extPct, background: '#F97316', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums',
          }}>{mode === 'pct' ? `${extPct}%` : fmt0(externalCosts)}</div>
          <div style={{
            flex: labPct, background: '#3B82F6', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums',
          }}>{mode === 'pct' ? `${labPct}%` : fmt0(labourTotal)}</div>
          <div style={{
            flex: profPct, background: '#22C55E', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums',
          }}>{mode === 'pct' ? `${profPct}%` : fmt0(profit)}</div>
        </div>

        {/* Legend */}
        <div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 10 }}>
          {[
            { c: '#F97316', label: 'External costs' },
            { c: '#3B82F6', label: 'Internal labour' },
            { c: '#22C55E', label: 'Net profit' },
          ].map((row, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ width: 14, height: 14, borderRadius: 3, background: row.c, flex: '0 0 14px' }}/>
              <span style={{ color: '#D4D4D4', fontSize: 14 }}>{row.label}</span>
            </div>
          ))}
        </div>

        {/* Slider */}
        <div style={{ marginTop: 26 }}>
          <div style={{ color: '#A3A3A3', fontSize: 13, marginBottom: 10 }}>Adjust net profit</div>
          {(() => {
            const pct = Math.max(0, Math.min(100, (profit / maxProfit) * 100));
            return (
              <div style={{ position: 'relative', height: 28, display: 'flex', alignItems: 'center' }}>
                <div style={{
                  position: 'absolute', left: 0, right: 0, height: 6, borderRadius: 3,
                  background: `linear-gradient(to right, #FEC230 0%, #FEC230 ${pct}%, #404040 ${pct}%, #404040 100%)`,
                  pointerEvents: 'none',
                }}/>
                <div style={{
                  position: 'absolute', left: `calc(${pct}% - 11px)`,
                  width: 22, height: 22, borderRadius: '50%', background: '#FEC230',
                  border: '3px solid #171717', boxShadow: '0 0 0 1px #FEC230',
                  pointerEvents: 'none',
                }}/>
                <input type="range" min={0} max={maxProfit} step={1}
                  value={profit}
                  onChange={(e) => setProfit(Number(e.target.value))}
                  style={{
                    position: 'relative', zIndex: 2, width: '100%',
                    appearance: 'none', WebkitAppearance: 'none',
                    background: 'transparent', height: 28, margin: 0, cursor: 'pointer',
                    opacity: 0,
                  }}
                />
              </div>
            );
          })()}
        </div>

        {/* Summary */}
        <div style={{ marginTop: 30 }}>
          <div style={{ color: '#fff', fontSize: 18, fontWeight: 700, marginBottom: 14 }}>Summary</div>
          {[
            ['External costs', externalCosts],
            ['Internal labour', labourTotal],
            ['Net profit', profit],
          ].map(([label, v], i) => (
            <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '8px 0' }}>
              <span style={{ color: '#D4D4D4', fontSize: 14 }}>{label}</span>
              <span style={{ color: '#D4D4D4', fontSize: 14, fontVariantNumeric: 'tabular-nums' }}>{fmt(v)}</span>
            </div>
          ))}
          <div style={{ height: 1, background: '#2C2C2C', margin: '10px 0' }}/>
          <div style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 0' }}>
            <span style={{ color: '#fff', fontSize: 16, fontWeight: 700 }}>Total estimate</span>
            <span style={{ color: '#fff', fontSize: 18, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt(total)}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0' }}>
            <span style={{ color: '#A3A3A3', fontSize: 14 }}>Inclusive of tax</span>
            <span style={{ color: '#A3A3A3', fontSize: 14, fontVariantNumeric: 'tabular-nums' }}>{fmt(taxTotal)}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

window.NetProfitScreen = NetProfitScreen;

// ─── Item Cost Editor (Materials / Labour) ───────────────────
function ItemCostScreen({ title, total, items, setItems, unitNoun, onBack, onSave }) {
  const list = items;
  const subtotal = list.reduce((s, it) => s + (it.qty * it.unit), 0);

  const fmt2 = (n) => '$' + Number(n).toLocaleString('en-AU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

  const updateItem = (id, patch) => setItems(l => l.map(it => it.id === id ? { ...it, ...patch } : it));

  // Auto-save when going back - just update parent state, no API call
  const handleBack = () => {
    if (onSave) onSave(list);
    else onBack();
  };

  return (
    <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
      <CustomHeader title={title} subtitle={fmt2(subtotal)} onBack={handleBack}/>

      {/* Body */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '8px 16px 20px' }}>
        {/* Section header with + */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 4px 10px' }}>
          <div style={{ color: '#A3A3A3', fontSize: 14 }}>{unitNoun === 'employee' ? 'Roles' : 'Material'}</div>
          <button aria-label="Add" style={{
            width: 28, height: 28, borderRadius: 6, border: 0, background: 'transparent',
            color: '#D4D4D4', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <span style={{ fontSize: 22, fontWeight: 400, lineHeight: 1 }}>+</span>
          </button>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {list.map(it => {
            const lineTotal = it.qty * it.unit;
            return (
              <div key={it.id} style={{ background: '#262626', borderRadius: 12, overflow: 'hidden' }}>
                <div style={{ padding: '14px 14px 0', display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12 }}>
                  <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, lineHeight: '22px', flex: 1 }}>{it.name}</div>
                  <button style={{
                    background: 'transparent', border: 0, color: '#FEC230', fontFamily: 'inherit',
                    fontSize: 14, fontWeight: 500, cursor: 'pointer', padding: 0,
                  }}>Swap</button>
                </div>

                {/* Employee/Subcontractor toggle for labour items */}
                {unitNoun === 'employee' && (
                  <div style={{ padding: '10px 14px 0', display: 'flex', gap: 8 }}>
                    <button
                      onClick={() => updateItem(it.id, { type: 'Employee' })}
                      style={{
                        padding: '8px 16px',
                        borderRadius: 20,
                        border: 0,
                        background: it.type === 'Employee' ? '#FEC230' : '#404040',
                        color: it.type === 'Employee' ? '#171717' : '#D4D4D4',
                        fontFamily: 'inherit',
                        fontSize: 13,
                        fontWeight: 500,
                        cursor: 'pointer',
                      }}
                    >Employee</button>
                    <button
                      onClick={() => updateItem(it.id, { type: 'Subcontractor' })}
                      style={{
                        padding: '8px 16px',
                        borderRadius: 20,
                        border: 0,
                        background: it.type === 'Subcontractor' ? '#FEC230' : '#404040',
                        color: it.type === 'Subcontractor' ? '#171717' : '#D4D4D4',
                        fontFamily: 'inherit',
                        fontSize: 13,
                        fontWeight: 500,
                        cursor: 'pointer',
                      }}
                    >Subcontractor</button>
                  </div>
                )}

                <div style={{ display: 'flex', gap: 12, padding: '10px 14px 14px' }}>
                  {/* Quantity */}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ color: '#A3A3A3', fontSize: 12, marginBottom: 6 }}>
                      Quantity ({it.unitLabel || (unitNoun === 'employee' ? 'employees' : 'units')})
                    </div>
                    <div style={{ display: 'flex', alignItems: 'stretch', gap: 6 }}>
                      <button onClick={() => updateItem(it.id, { qty: Math.max(0, it.qty - 1) })} style={{
                        width: 36, height: 38, borderRadius: 8, border: 0, background: '#404040',
                        color: '#D4D4D4', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
                      }}>−</button>
                      <input type="text" inputMode="numeric" value={it.qty}
                        onChange={(e) => {
                          const v = Number(e.target.value.replace(/\D/g, ''));
                          updateItem(it.id, { qty: isNaN(v) ? 0 : v });
                        }}
                        style={{
                          flex: 1, minWidth: 0, height: 38, background: '#171717',
                          border: '1px solid #2C2C2C', borderRadius: 8, color: '#fff',
                          textAlign: 'center', fontFamily: 'inherit', fontSize: 14, fontVariantNumeric: 'tabular-nums',
                          outline: 'none',
                        }}
                      />
                      <button onClick={() => updateItem(it.id, { qty: it.qty + 1 })} style={{
                        width: 36, height: 38, borderRadius: 8, border: 0, background: '#404040',
                        color: '#D4D4D4', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
                      }}>+</button>
                    </div>
                  </div>

                  {/* Est. cost per unit */}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ color: '#A3A3A3', fontSize: 12, marginBottom: 6 }}>
                      {unitNoun === 'employee' ? 'Est. hourly rate' : 'Est. cost per unit'}
                    </div>
                    <div style={{ position: 'relative' }}>
                      <span style={{
                        position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)',
                        color: '#737373', fontSize: 14,
                      }}>$</span>
                      <input type="text" inputMode="decimal" value={it.unit.toFixed(2)}
                        onChange={(e) => {
                          const v = parseFloat(e.target.value.replace(/[^0-9.]/g, ''));
                          updateItem(it.id, { unit: isNaN(v) ? 0 : v });
                        }}
                        style={{
                          width: '100%', height: 38, background: '#171717',
                          border: '1px solid #2C2C2C', borderRadius: 8, color: '#fff',
                          padding: '0 12px 0 24px', textAlign: 'right',
                          fontFamily: 'inherit', fontSize: 14, fontVariantNumeric: 'tabular-nums',
                          outline: 'none', boxSizing: 'border-box',
                        }}
                      />
                    </div>
                  </div>
                </div>

                <div style={{
                  borderTop: '1px solid #2C2C2C', padding: '12px 14px',
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                }}>
                  <span style={{ color: '#A3A3A3', fontSize: 13 }}>Item subtotal</span>
                  <span style={{ color: '#fff', fontSize: 16, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{fmt2(lineTotal)}</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>

    </div>
  );
}

// Pre-seeded data matching the screenshot's vibe (mirrors PriceSummaryScreen totals)
const MATERIAL_ITEMS = [
  { id: 'm1', name: 'Daikin Inverter Ducted 8.5kW', qty: 1,  unit: 2678.40, unitLabel: 'units' },
  { id: 'm2', name: 'Plenum Box',                     qty: 1,  unit: 224.00,  unitLabel: 'units' },
  { id: 'm3', name: 'Return Air Allowance',           qty: 1,  unit: 200.00,  unitLabel: 'units' },
  { id: 'm4', name: 'Copper Pipe Allowance',          qty: 12, unit: 20.00,   unitLabel: 'metres' },
  { id: 'm5', name: 'Outlet Allowance (incl. grille and ducting)', qty: 1, unit: 450.00, unitLabel: 'units' },
  { id: 'm6', name: 'Feet / Polyslab',                qty: 1,  unit: 80.00,   unitLabel: 'units' },
  { id: 'm7', name: '20A Circuit Breaker',            qty: 1,  unit: 16.00,   unitLabel: 'units' },
  { id: 'm8', name: '20A Isolator Switch',            qty: 1,  unit: 24.00,   unitLabel: 'units' },
  { id: 'm9', name: '2.5mm² Power Cable',             qty: 4,  unit: 2.00,    unitLabel: 'metres' },
];

const LABOUR_ITEMS = [
  { id: 'l1', name: 'HVAC Technician', qty: 8, unit: 100.00, unitLabel: 'hours' },
  { id: 'l2', name: 'Apprentice',      qty: 8, unit: 50.00,  unitLabel: 'hours' },
];

function MaterialsScreen({ onBack, onSave, items, setItems, quoteId }) {
  const [loading, setLoading] = useState(!!quoteId && (!items || items.length === 0));
  const [loadError, setLoadError] = useState(null);
  const [localItems, setLocalItems] = useState(items && items.length > 0 ? items : []);

  // Load V3 pricing and hardware data if quoteId provided and no items passed in
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    // If items were passed from parent with V3 data, use them
    if (items && items.length > 0 && (items[0].id?.startsWith('hw') || items[0].id?.startsWith('v3m'))) {
      setLocalItems(items);
      setLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const allMaterials = [];
        let hardwareTotal = 0;

        // 1. Fetch V3 pricing first to get the hardware total and allocated materials
        try {
          const v3Data = await api.calculateV3Pricing(quoteId, 15, 3.5);
          if (!cancelled && v3Data?.data) {
            // Get hardware total from V3 pricing (this comes from extracted_hardware.manufacturer_total)
            hardwareTotal = v3Data.data.pricing?.breakdown?.hardware || 0;

            // Add VRV System as a single line item with the total
            if (hardwareTotal > 0) {
              allMaterials.push({
                id: 'hw0',
                name: 'VRV System (from supplier quote)',
                qty: 1,
                unit: hardwareTotal,
                unitLabel: 'system',
              });
            }

            // Add V3 allocated materials
            if (v3Data.data.allocation?.materials) {
              v3Data.data.allocation.materials.forEach((mat, i) => {
                allMaterials.push({
                  id: `v3m${i}`,
                  name: mat.name,
                  qty: mat.quantity,
                  unit: mat.unitPrice,
                  unitLabel: mat.unit || 'each',
                });
              });
            }
          }
        } catch (v3Err) {
          console.warn('Failed to load V3 pricing:', v3Err);

          // Fallback: try to load hardware items directly
          try {
            const hwData = await api.getHardware(quoteId);
            if (!cancelled && hwData?.items) {
              hwData.items.forEach((hw, i) => {
                if (!hw.deleted && !hw.is_deleted) {
                  allMaterials.push({
                    id: `hw${i}`,
                    name: hw.name || hw.model || hw.description || 'VRV Equipment',
                    qty: hw.qty || hw.quantity || 1,
                    unit: hw.unit || hw.price || 0,
                    unitLabel: 'units',
                  });
                }
              });
            }
          } catch (hwErr) {
            console.warn('Failed to load hardware:', hwErr);
          }
        }

        if (!cancelled) {
          if (allMaterials.length > 0) {
            setLocalItems(allMaterials);
          } else {
            // Fallback to default items if nothing loaded
            setLocalItems(MATERIAL_ITEMS);
          }
        }
      } catch (err) {
        if (!cancelled) setLoadError(err.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId, items]);

  // Save updates parent state and navigates back (no API call needed)
  const handleSave = (updatedItems) => {
    if (setItems) setItems(updatedItems);
    onBack();
  };

  if (loading) {
    return (
      <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
        <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
        <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading materials...</div>
      </div>
    );
  }

  if (loadError) {
    return (
      <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
        <I.AlertTriangle size={32} color="#EF4444" />
        <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Failed to load materials</div>
        <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{loadError}</div>
        <Button variant="secondary" style={{ marginTop: 20 }} onClick={onBack}>Go Back</Button>
      </div>
    );
  }

  return <ItemCostScreen
    title="Material costs"
    items={localItems}
    setItems={setLocalItems}
    unitNoun="material"
    onBack={onBack}
    onSave={handleSave}
  />;
}

function LabourScreen({ onBack, onSave, items, setItems, quoteId }) {
  const [loading, setLoading] = useState(!!quoteId && (!items || items.length === 0));
  const [loadError, setLoadError] = useState(null);
  const [localItems, setLocalItems] = useState(items && items.length > 0 ? items : []);

  // Load V3 labour data if quoteId provided and no items passed in
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    // If items were passed from parent with V3 data, use them
    if (items && items.length > 0 && items[0].id?.startsWith('v3l')) {
      setLocalItems(items);
      setLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        // Fetch V3 pricing to get labour breakdown
        const v3Data = await api.calculateV3Pricing(quoteId, 15, 3.5);
        if (!cancelled && v3Data?.data?.labourBreakdown) {
          const v3Labour = v3Data.data.labourBreakdown.map((tech, i) => ({
            id: `v3l${i}`,
            name: tech.role,
            qty: tech.hours,
            unit: tech.rate,
            unitLabel: 'hours',
            type: 'Employee',
          }));
          setLocalItems(v3Labour);
        } else {
          // Fallback to default
          setLocalItems(LABOUR_ITEMS);
        }
      } catch (err) {
        console.warn('Failed to load V3 labour:', err);
        // Fallback to default
        if (!cancelled) setLocalItems(LABOUR_ITEMS);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId, items]);

  // Save updates parent state and navigates back (no API call needed)
  const handleSave = (updatedItems) => {
    if (setItems) setItems(updatedItems);
    onBack();
  };

  if (loading) {
    return (
      <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
        <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
        <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading labour costs...</div>
      </div>
    );
  }

  if (loadError) {
    return (
      <div style={{ width: '100%', height: '100%', position: 'relative', background: '#171717', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
        <I.AlertTriangle size={32} color="#EF4444" />
        <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Failed to load labour</div>
        <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{loadError}</div>
        <Button variant="secondary" style={{ marginTop: 20 }} onClick={onBack}>Go Back</Button>
      </div>
    );
  }

  return <ItemCostScreen
    title="Labour costs"
    items={localItems}
    setItems={setLocalItems}
    unitNoun="employee"
    onBack={onBack}
    onSave={handleSave}
  />;
}

window.DEFAULT_MATERIAL_ITEMS = MATERIAL_ITEMS;
window.DEFAULT_LABOUR_ITEMS = LABOUR_ITEMS;

window.MaterialsScreen = MaterialsScreen;
window.LabourScreen = LabourScreen;