/* ============ SCAN BARCODE SCREEN ============ */
function ScanScreen({products, stockIn, stockOut, setRoute}){
  const {useState, useEffect, useRef, useCallback} = React;

  const [phase, setPhase]           = useState('idle');
  const [errMsg, setErrMsg]         = useState('');
  const [found, setFound]           = useState(null);
  const [scannedCode, setScannedCode] = useState('');
  const [manualCode, setManualCode] = useState('');
  const [qty, setQty]               = useState('');
  const [employee, setEmployee]     = useState('');
  const [scaleDecoded, setScaleDecoded] = useState(null);

  const qrRef      = useRef(null);   // Html5Qrcode instance
  const videoRef   = useRef(null);   // used for native BarcodeDetector path
  const streamRef  = useRef(null);
  const rafRef     = useRef(null);
  const detectorRef = useRef(null);

  /* ── decode scale barcode: 27 + PLU(4) + grams(6) + check(1) ── */
  function decodeScaleBarcode(code) {
    if (code.length === 13 && code.startsWith('27')) {
      const plu      = parseInt(code.slice(2, 6), 10);
      const grams    = parseInt(code.slice(6, 12), 10);
      const weightKg = Math.round(grams / 10) / 100;
      if (!isNaN(plu) && !isNaN(grams) && grams > 0) return { plu, weightKg };
    }
    return null;
  }

  const handleCode = useCallback((code) => {
    const clean = code.trim();
    setScannedCode(clean);

    const scale = decodeScaleBarcode(clean);
    if (scale) {
      const p = products.find(pr => pr.plu && parseInt(pr.plu) === scale.plu);
      if (p) {
        setFound(p); setScaleDecoded(scale);
        setQty(String(scale.weightKg));
        setPhase('found'); return;
      }
    }

    const p = products.find(pr =>
      (pr.barcode && pr.barcode === clean) ||
      (pr.plu     && String(pr.plu) === clean) ||
      (pr.code    && pr.code.toLowerCase() === clean.toLowerCase())
    );
    if (p) { setFound(p); setScaleDecoded(null); setPhase('found'); }
    else   { setFound(null); setScaleDecoded(null); setPhase('notfound'); }
  }, [products]);

  /* ── stop all camera activity ── */
  const stopCamera = useCallback(() => {
    if (rafRef.current)  { cancelAnimationFrame(rafRef.current); rafRef.current = null; }
    if (qrRef.current)   { try { qrRef.current.stop(); } catch(e){} qrRef.current = null; }
    if (streamRef.current) { streamRef.current.getTracks().forEach(t=>t.stop()); streamRef.current = null; }
  }, []);

  /* ── native BarcodeDetector RAF loop ── */
  const scanLoop = useCallback(() => {
    if (!videoRef.current || !detectorRef.current) return;
    rafRef.current = requestAnimationFrame(async () => {
      try {
        const codes = await detectorRef.current.detect(videoRef.current);
        if (codes.length > 0) { stopCamera(); handleCode(codes[0].rawValue); }
        else scanLoop();
      } catch { scanLoop(); }
    });
  }, [stopCamera, handleCode]);

  /* ── start camera — called by the button ── */
  const startCamera = useCallback(() => {
    setPhase('scanning');
    setErrMsg('');
  }, []);

  /* ── once phase=scanning, DOM is ready → init scanner ── */
  useEffect(() => {
    if (phase !== 'scanning') return;

    const hasBarcodeDetector = 'BarcodeDetector' in window;
    const hasHtml5Qrcode     = typeof Html5Qrcode !== 'undefined';

    let cancelled = false;

    async function init() {
      try {
        if (hasBarcodeDetector) {
          /* Native BarcodeDetector (Chrome Android / Edge) */
          const stream = await navigator.mediaDevices.getUserMedia({
            video: { facingMode:'environment', width:{ideal:1280}, height:{ideal:720} }
          });
          if (cancelled) { stream.getTracks().forEach(t=>t.stop()); return; }
          streamRef.current = stream;
          if (videoRef.current) { videoRef.current.srcObject = stream; await videoRef.current.play(); }
          detectorRef.current = new BarcodeDetector({
            formats:['ean_13','ean_8','code_128','code_39','upc_a','upc_e','qr_code']
          });
          scanLoop();

        } else if (hasHtml5Qrcode) {
          /* html5-qrcode — works on all desktop browsers */
          const scanner = new Html5Qrcode('helbawi-scanner-div');
          qrRef.current = scanner;
          await scanner.start(
            { facingMode: 'environment' },
            { fps: 15, qrbox: { width: 280, height: 160 } },
            (decodedText) => {
              try { scanner.stop(); } catch(e) {}
              qrRef.current = null;
              if (!cancelled) handleCode(decodedText);
            },
            () => { /* per-frame not-found — ignore */ }
          );

        } else {
          /* No scan API — camera only, manual entry */
          const stream = await navigator.mediaDevices.getUserMedia({ video:{ facingMode:'environment' } });
          if (cancelled) { stream.getTracks().forEach(t=>t.stop()); return; }
          streamRef.current = stream;
          if (videoRef.current) { videoRef.current.srcObject = stream; await videoRef.current.play(); }
          if (!cancelled) setErrMsg('Auto-scan unavailable in this browser. Enter the barcode manually below.');
        }
      } catch(e) {
        if (!cancelled) {
          setPhase('error');
          setErrMsg(e.name === 'NotAllowedError'
            ? 'Camera access denied. Allow camera permission and try again.'
            : 'Camera error: ' + e.message);
        }
      }
    }

    init();
    return () => { cancelled = true; stopCamera(); };
  }, [phase, scanLoop, stopCamera, handleCode]);

  useEffect(() => () => stopCamera(), [stopCamera]);

  /* ── reset ── */
  const reset = useCallback(() => {
    stopCamera();
    setPhase('idle'); setFound(null); setScannedCode('');
    setManualCode(''); setQty(''); setEmployee(''); setScaleDecoded(null);
  }, [stopCamera]);

  /* ── confirm stock-out ── */
  const confirmAction = () => {
    const q = parseFloat(qty);
    if (!q || q <= 0) { toast({kind:'err', title:'Enter a valid weight'}); return; }
    if (!employee.trim()) { toast({kind:'err', title:'Employee name is required'}); return; }
    const cur = found ? Math.round(found.batches.reduce((s,b)=>s+b.qty,0)*10)/10 : 0;
    const ok = stockOut({productId: found.id, qty: q, employee: employee.trim()});
    if (!ok) { toast({kind:'err', title:'Insufficient stock', desc:`Only ${H.fmtQty(cur,'kg')} available`}); return; }
    toast({kind:'ok', title:'Stock Out recorded', desc:`${q} kg of ${found.nameEn||found.nameAr} by ${employee.trim()}`});
    reset();
  };

  const cur    = found ? Math.round(found.batches.reduce((s,b)=>s+b.qty,0)*10)/10 : 0;
  const status = found ? H.statusOf(found) : null;

  /* ── determine which video element to show ── */
  const useNative = 'BarcodeDetector' in window;

  return (
    <div className="content fade-up" style={{maxWidth:560, margin:'0 auto'}}>

      {/* ── IDLE ── */}
      {phase === 'idle' && (
        <div className="card card-pad" style={{textAlign:'center', padding:'40px 28px'}}>
          <div style={{width:80,height:80,borderRadius:24,background:'var(--pink-tint)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 20px'}}>
            <Icon name="scan" size={40} style={{color:'var(--magenta)'}}/>
          </div>
          <h2 style={{fontSize:22,fontWeight:800,margin:'0 0 8px'}}>Scan a Barcode</h2>
          <p style={{color:'var(--muted)',fontSize:15,margin:'0 0 28px'}}>Point your camera at a product barcode to look it up instantly</p>
          <button className="btn btn-primary" style={{width:'100%',fontSize:16,padding:'14px'}} onClick={startCamera}>
            <Icon name="scan" size={20}/> Open Camera
          </button>
          <div style={{margin:'20px 0',display:'flex',alignItems:'center',gap:12}}>
            <div style={{flex:1,height:1,background:'var(--line)'}}/>
            <span style={{color:'var(--muted)',fontSize:13,fontWeight:600}}>or enter manually</span>
            <div style={{flex:1,height:1,background:'var(--line)'}}/>
          </div>
          <div style={{display:'flex',gap:10}}>
            <input className="input" placeholder="Product code, PLU, or barcode…" value={manualCode}
              onChange={e=>setManualCode(e.target.value)}
              onKeyDown={e=>e.key==='Enter' && manualCode.trim() && handleCode(manualCode.trim())}
              style={{flex:1}}/>
            <button className="btn btn-soft" onClick={()=>manualCode.trim() && handleCode(manualCode.trim())}>
              Search
            </button>
          </div>
        </div>
      )}

      {/* ── SCANNING ── */}
      {phase === 'scanning' && (
        <div className="card" style={{overflow:'hidden'}}>
          <div style={{position:'relative',background:'#000',borderRadius:'var(--radius) var(--radius) 0 0',minHeight:280}}>

            {/* Native BarcodeDetector: our video element */}
            {useNative && (
              <video ref={videoRef}
                style={{width:'100%',maxHeight:340,display:'block',objectFit:'cover'}}
                playsInline autoPlay muted/>
            )}

            {/* html5-qrcode: mounts video inside this div */}
            {!useNative && (
              <div id="helbawi-scanner-div" style={{width:'100%'}}/>
            )}

            {/* crosshair overlay (BarcodeDetector only — html5-qrcode draws its own box) */}
            {useNative && (
              <div style={{position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center',pointerEvents:'none'}}>
                <div style={{width:240,height:150,border:'2.5px solid rgba(255,255,255,.9)',borderRadius:12,boxShadow:'0 0 0 9999px rgba(0,0,0,.45)'}}/>
              </div>
            )}
          </div>

          <div style={{padding:'14px 20px',background:'var(--ink)',display:'flex',alignItems:'center',justifyContent:'space-between'}}>
            <div style={{color:'rgba(255,255,255,.8)',fontSize:14,fontWeight:600}}>
              {errMsg ? '⚠ Manual entry only' : 'Align barcode within frame…'}
            </div>
            <button className="btn" style={{background:'rgba(255,255,255,.15)',color:'#fff',border:'none',padding:'8px 16px'}} onClick={reset}>Cancel</button>
          </div>

          {errMsg && (
            <div style={{padding:'14px 20px',background:'var(--crit-bg)',color:'var(--crit)',fontSize:13,fontWeight:600,borderTop:'1px solid var(--line)'}}>
              {errMsg}
              <div style={{marginTop:12,display:'flex',gap:10}}>
                <input className="input" placeholder="Enter code manually…" value={manualCode}
                  onChange={e=>setManualCode(e.target.value)}
                  onKeyDown={e=>e.key==='Enter' && manualCode.trim() && handleCode(manualCode.trim())}
                  style={{flex:1,fontSize:14}}/>
                <button className="btn btn-primary" onClick={()=>manualCode.trim() && handleCode(manualCode.trim())}>Go</button>
              </div>
            </div>
          )}
        </div>
      )}

      {/* ── NOT FOUND ── */}
      {phase === 'notfound' && (
        <div className="card card-pad" style={{textAlign:'center',padding:'36px 28px'}}>
          <div style={{width:64,height:64,borderRadius:20,background:'var(--crit-bg)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 16px'}}>
            <Icon name="alert" size={32} style={{color:'var(--crit)'}}/>
          </div>
          <h2 style={{fontSize:20,fontWeight:800,color:'var(--crit)',margin:'0 0 8px'}}>Product Not Found</h2>
          <p style={{color:'var(--muted)',fontSize:14,margin:'0 0 4px'}}>No product matched:</p>
          <code style={{background:'var(--line-2)',padding:'6px 14px',borderRadius:8,fontSize:14,fontWeight:700,display:'inline-block',margin:'0 0 24px'}}>{scannedCode}</code>
          <div style={{display:'flex',gap:12}}>
            <button className="btn btn-soft" style={{flex:1}} onClick={reset}>Scan Again</button>
            <button className="btn btn-primary" style={{flex:1}} onClick={()=>setRoute('items')}>Browse Items</button>
          </div>
        </div>
      )}

      {/* ── ERROR ── */}
      {phase === 'error' && (
        <div className="card card-pad" style={{textAlign:'center',padding:'36px 28px'}}>
          <div style={{width:64,height:64,borderRadius:20,background:'var(--crit-bg)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 16px'}}>
            <Icon name="alert" size={32} style={{color:'var(--crit)'}}/>
          </div>
          <h2 style={{fontSize:20,fontWeight:800,margin:'0 0 8px'}}>Camera Error</h2>
          <p style={{color:'var(--muted)',fontSize:14,margin:'0 0 24px'}}>{errMsg}</p>
          <div style={{display:'flex',gap:12,marginBottom:16}}>
            <button className="btn btn-primary" style={{flex:1}} onClick={startCamera}>Try Again</button>
            <button className="btn btn-soft" style={{flex:1}} onClick={reset}>Cancel</button>
          </div>
          <div style={{display:'flex',gap:10}}>
            <input className="input" placeholder="Enter product code or PLU manually…" value={manualCode}
              onChange={e=>setManualCode(e.target.value)}
              onKeyDown={e=>e.key==='Enter' && manualCode.trim() && handleCode(manualCode.trim())}
              style={{flex:1}}/>
            <button className="btn btn-soft" onClick={()=>manualCode.trim() && handleCode(manualCode.trim())}>Search</button>
          </div>
        </div>
      )}

      {/* ── FOUND ── */}
      {phase === 'found' && found && (
        <div style={{display:'flex',flexDirection:'column',gap:14}}>
          <div className="card card-pad" style={{display:'flex',gap:16,alignItems:'center'}}>
            <ProductThumb p={found} size={60}/>
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontWeight:800,fontSize:17,lineHeight:1.2}}>{found.nameEn||found.nameAr}</div>
              {found.nameAr && found.nameAr !== found.nameEn &&
                <div className="ar" style={{color:'var(--muted)',fontSize:14,marginTop:2}}>{found.nameAr}</div>}
              <div style={{display:'flex',gap:8,marginTop:8,flexWrap:'wrap'}}>
                <span className="pill np" style={{background:H.CAT_COLOR[found.category]+'18',color:H.CAT_COLOR[found.category]}}>{found.category}</span>
                <span className={'pill '+status.cls}>{status.label}</span>
                <span className="pill np pill-grey">{H.fmtQty(cur,found.unit)} in stock</span>
              </div>
            </div>
          </div>

          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
            {[['Code',found.code],['PLU',found.plu||'—'],['Unit',found.unit],['Price',H.money(found.price)+'/'+found.unit]].map(([l,v],i)=>(
              <div key={i} style={{background:'#fff',border:'1px solid var(--line)',borderRadius:12,padding:'12px 14px'}}>
                <div style={{fontSize:11,color:'var(--muted)',fontWeight:600,marginBottom:2}}>{l}</div>
                <div style={{fontWeight:700,fontSize:14}}>{v}</div>
              </div>
            ))}
          </div>

          {/* kg → stock-out form */}
          {found.unit === 'kg' && (
            <div className="card card-pad">
              <div style={{display:'flex',alignItems:'center',gap:10,marginBottom:16}}>
                <div style={{width:36,height:36,borderRadius:10,background:'#FEF3C7',display:'flex',alignItems:'center',justifyContent:'center'}}>
                  <Icon name="stockOut" size={20} style={{color:'#D97706'}}/>
                </div>
                <div style={{fontWeight:800,fontSize:16,color:'#D97706'}}>Record Stock Out</div>
                {scaleDecoded && (
                  <span style={{marginLeft:'auto',background:'#E8F7EE',color:'#16A34A',fontSize:12,fontWeight:700,
                    padding:'4px 10px',borderRadius:8,display:'flex',alignItems:'center',gap:5}}>
                    <Icon name="checkCircle" size={13}/> Weight from scale
                  </span>
                )}
              </div>

              <div className="field" style={{marginBottom:14}}>
                <label>Weight taken (kg)</label>
                <div style={{position:'relative'}}>
                  <input className="input" type="number" min="0.1" step="0.1"
                    placeholder="0.0" value={qty}
                    onChange={e=>setQty(e.target.value)}
                    autoFocus={!scaleDecoded}
                    readOnly={!!scaleDecoded}
                    style={{paddingRight:42,fontSize:22,fontWeight:800,
                      background: scaleDecoded ? '#F0FAF4' : undefined,
                      color:      scaleDecoded ? '#16A34A' : undefined}}/>
                  <span style={{position:'absolute',right:14,top:'50%',transform:'translateY(-50%)',color:'var(--muted)',fontWeight:700,fontSize:15}}>kg</span>
                </div>
                <div style={{fontSize:12,color:'var(--muted)',marginTop:4}}>
                  Available: {H.fmtQty(cur,'kg')}
                  {scaleDecoded && <span style={{color:'#16A34A',fontWeight:700,marginLeft:8}}>· decoded from barcode (PLU {scaleDecoded.plu})</span>}
                </div>
              </div>

              <div className="field" style={{marginBottom:16}}>
                <label>Employee name <span style={{color:'var(--crit)'}}>*</span></label>
                <input className="input" placeholder="Who is taking this stock?"
                  value={employee} onChange={e=>setEmployee(e.target.value)}
                  style={{fontSize:15}}/>
              </div>

              <button className="btn btn-primary" style={{width:'100%',fontSize:16,padding:'14px'}} onClick={confirmAction}>
                <Icon name="stockOut" size={20}/> Confirm Stock Out
              </button>
            </div>
          )}

          {/* pcs → redirect */}
          {found.unit !== 'kg' && (
            <div className="card card-pad" style={{textAlign:'center',padding:'24px 20px'}}>
              <div style={{width:52,height:52,borderRadius:16,background:'var(--low-bg)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 12px'}}>
                <Icon name="info" size={26} style={{color:'var(--low)'}}/>
              </div>
              <div style={{fontWeight:800,fontSize:16,marginBottom:6}}>Piece item — use Stock Out screen</div>
              <div style={{color:'var(--muted)',fontSize:14,lineHeight:1.5,marginBottom:20}}>
                Scanner stock out only works for <strong>weighted (kg) items</strong>.<br/>
                For piece items, go to the Stock Out screen.
              </div>
              <button className="btn btn-primary" style={{width:'100%'}} onClick={()=>setRoute('stock-out')}>
                Go to Stock Out
              </button>
            </div>
          )}

          <button className="btn btn-soft" onClick={reset} style={{width:'100%'}}>
            <Icon name="scan" size={18}/> Scan Another
          </button>
        </div>
      )}
    </div>
  );
}

window.ScanScreen = ScanScreen;
