/* ============ PrerollsTab — terminal reskin of PrerollCalc ============
   Ported from profit-calc-clean-source.html (function PrerollCalc, lines 972-1320).
   Math is identical; chrome matches flower-terminal-app.jsx (FlowerTab). */

const exportPrerollsCSV=(products)=>{
  const filtered=products.filter(p=>p.category==='prerolls');
  if(filtered.length===0)return alert('No pre-roll products yet.');
  const cols=['SKU','Type','Grade','Wt','Method','Format','Input','COGS/Unit','WS List','WS Floor','Retail','List Margin %','Units','Revenue','Gross Profit'];
  const rows=filtered.map(p=>[p.skuName,p.prType,p.grade,p.weight,p.method,p.isMultiPack?`${p.jointsPerPack}-pk`:'Single',p.inputMaterial,
    '$'+p.totalCOGS.toFixed(2),'$'+p.wsList.toFixed(2),'$'+p.wsFloor.toFixed(2),'$'+p.consumerRetail.toFixed(2),
    p.listMarginPct.toFixed(1)+'%',p.units,'$'+p.totalRevenue.toFixed(2),'$'+p.totalProfit.toFixed(2)]);
  const csv=[cols.join(','),...rows.map(r=>r.map(c=>'"'+String(c).replace(/"/g,'""')+'"').join(','))].join('\n');
  const blob=new Blob([csv],{type:'text/csv'});
  const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download='cannabiz-prerolls.csv';a.click();URL.revokeObjectURL(url);
};

function PrerollsTab({products,setProducts,rawCosts,setRawCosts,distroState,setProgress}){
  /* --- State (lifted verbatim from PrerollCalc) --- */
  const [prType,setPrType]=useState('standard');
  const [flowerGrade,setFlowerGrade]=useState('deps');
  const [jointWeight,setJointWeight]=useState(1.0);
  const [method,setMethod]=useState('machine');
  const [handLaborCost,setHandLaborCost]=useState(3.00);
  const [machineLaborCost,setMachineLaborCost]=useState(0.50);
  const [packLaborCost,setPackLaborCost]=useState(0.10);
  const [conePaperCost,setConePaperCost]=useState(0.08);
  const [filterCost,setFilterCost]=useState(0.02);
  const [tubeCost,setTubeCost]=useState(0.25);
  const [boxCost,setBoxCost]=useState(0.40);
  const [concType,setConcType]=useState('distillate');
  const [concCostPerG,setConcCostPerG]=useState(1.00);
  const [concAmountG,setConcAmountG]=useState(0.25);
  const [kiefCost,setKiefCost]=useState(0.15);
  const [useKief,setUseKief]=useState(true);
  const [hashHoleRosinG,setHashHoleRosinG]=useState(0.5);
  const [hashHoleRosinCost,setHashHoleRosinCost]=useState(15);
  const [hashHoleLaborCost,setHashHoleLaborCost]=useState(5);
  const [infusionLaborCost,setInfusionLaborCost]=useState(1.50);
  const [qcLaborCost,setQcLaborCost]=useState(0.10);
  const [pkgLaborCost,setPkgLaborCost]=useState(0.15);
  const [isMultiPack,setIsMultiPack]=useState(false);
  const [jointsPerPack,setJointsPerPack]=useState(5);
  const [multiPackBoxCost,setMultiPackBoxCost]=useState(1.25);
  const [multiPackInsertCost,setMultiPackInsertCost]=useState(0.15);
  const [multiPackLaborCost,setMultiPackLaborCost]=useState(0.50);
  const [masterCaseQty,setMasterCaseQty]=useState(20);
  const [masterCaseCost,setMasterCaseCost]=useState(2.50);
  const [markupX,setMarkupX]=useState(2.0);
  const [skuName,setSkuName]=useState('');
  const [inputLbs,setInputLbs]=useState(5);
  const [lossPct,setLossPct]=useState(5);
  const [useBlend,setUseBlend]=useState(false);
  const [blendTrimPct,setBlendTrimPct]=useState(30);
  const [blendGrade2,setBlendGrade2]=useState('trim');
  const [consumerRetail,setConsumerRetail]=useState(10);
  const [wsList,setWsList]=useState(5);
  const [wsFloor,setWsFloor]=useState(4);
  const [testCostBatch,setTestCostBatch]=useState(400);

  /* price defaults react to type/method/pack (from source) */
  useEffect(()=>{
    if(prType==='standard'){
      const baseRetail=method==='hand'?14:10;const baseWs=method==='hand'?7.50:5.00;const baseFloor=method==='hand'?6.00:4.00;
      setConsumerRetail(isMultiPack?baseRetail*jointsPerPack*0.9:baseRetail);
      setWsList(isMultiPack?baseWs*jointsPerPack*0.9:baseWs);
      setWsFloor(isMultiPack?baseFloor*jointsPerPack*0.9:baseFloor);
      setJointWeight(method==='hand'?1.5:1.0);
    }
    if(prType==='infused'){
      setConsumerRetail(isMultiPack?22*jointsPerPack*0.9:22);
      setWsList(isMultiPack?12*jointsPerPack*0.9:12);
      setWsFloor(isMultiPack?9*jointsPerPack*0.9:9);
      setConcCostPerG(concType==='distillate'?1:concType==='liveresin'?6:10);
    }
    if(prType==='hashhole'){
      setConsumerRetail(isMultiPack?50*jointsPerPack*0.9:50);
      setWsList(isMultiPack?28*jointsPerPack*0.9:28);
      setWsFloor(isMultiPack?22*jointsPerPack*0.9:22);
      setJointWeight(1.5);
    }
  },[prType,method,concType,isMultiPack,jointsPerPack]);

  /* shared distro state */
  const distroModel=distroState.distroModelShared;
  const setDistroModel=distroState.setDistroModelShared;
  const distroMargin=distroState.distroMarginShared;
  const setDistroMargin=distroState.setDistroMarginShared;
  const pricingMode=distroState.distroPricingModeShared;
  const setPricingMode=distroState.setDistroPricingModeShared;
  const salesComm=distroState.salesPctShared;
  const setSalesComm=distroState.setSalesPctShared;
  const samplePct=distroState.sampleRateShared;
  const setSamplePct=distroState.setSampleRateShared;
  const [overheadPerUnit,setOverheadPerUnit]=useState(0);

  /* derived (verbatim) */
  const gradeObj=FLOWER_GRADES.find(g=>g.id===flowerGrade);
  const grade2Obj=FLOWER_GRADES.find(g=>g.id===blendGrade2);
  const safeInputLbs=nonNegative(inputLbs);
  const safeLossPct=clamp(lossPct,0,100);
  const safeBlendTrimPct=clamp(blendTrimPct,0,100);
  const safeJointWeight=positiveOr(jointWeight);
  const safeHashHoleRosinG=nonNegative(hashHoleRosinG);
  const safeWsList=nonNegative(wsList);
  const safeWsFloor=nonNegative(wsFloor);
  const safeDistroMargin=pct(distroMargin);
  const safeSalesComm=pct(salesComm);
  const safeSamplePct=pct(samplePct);
  const costPerLb=nonNegative(rawCosts[flowerGrade]||gradeObj.defaultPerLb);
  const costPerGram=costPerLb/GRAMS_PER_LB;
  const cost2PerGram=nonNegative(rawCosts[blendGrade2]||grade2Obj.defaultPerLb)/GRAMS_PER_LB;
  const flowerGramsInJoint=prType==='hashhole'?Math.max(0,safeJointWeight-safeHashHoleRosinG):safeJointWeight;
  const blendedCostPerGram=useBlend?(costPerGram*((100-safeBlendTrimPct)/100))+(cost2PerGram*(safeBlendTrimPct/100)):costPerGram;
  const baseLaborCost=prType==='hashhole'?nonNegative(hashHoleLaborCost):method==='hand'?nonNegative(handLaborCost):(nonNegative(machineLaborCost)+nonNegative(packLaborCost));
  const laborCost=baseLaborCost+(prType==='infused'?nonNegative(infusionLaborCost):0)+nonNegative(qcLaborCost)+nonNegative(pkgLaborCost);
  const concCost=prType==='infused'?(nonNegative(concCostPerG)*nonNegative(concAmountG))+(useKief?nonNegative(kiefCost):0):0;
  const rosinCost=prType==='hashhole'?nonNegative(hashHoleRosinCost)*safeHashHoleRosinG:0;
  const flowerPerJoint=prType==='hashhole'?Math.max(0.01,safeJointWeight-safeHashHoleRosinG):Math.max(0.01,safeJointWeight);
  const usableGrams=safeInputLbs*GRAMS_PER_LB*(1-safeLossPct/100);
  const totalJoints=Math.max(0,Math.floor(usableGrams/flowerPerJoint));
  const materialCost=useBlend?safeInputLbs*GRAMS_PER_LB*blendedCostPerGram:safeInputLbs*costPerLb;
  const flowerCostJoint=totalJoints>0?materialCost/totalJoints:0;
  const perJointCOGS=flowerCostJoint+laborCost+nonNegative(conePaperCost)+nonNegative(filterCost)+nonNegative(tubeCost)+nonNegative(boxCost)+COA_LABEL+concCost+rosinCost;
  const safeJointsPerPack=Math.max(1,Math.floor(nonNegative(jointsPerPack)||1));
  const units=isMultiPack?Math.max(0,Math.floor(totalJoints/safeJointsPerPack)):totalJoints;
  const testCostPerUnit=units>0?nonNegative(testCostBatch)/units:0;
  const multiPackPkgCost=isMultiPack?(nonNegative(multiPackBoxCost)+nonNegative(multiPackInsertCost)+nonNegative(multiPackLaborCost)):0;
  const masterCaseCostPerUnit=isMultiPack&&nonNegative(masterCaseQty)>0?nonNegative(masterCaseCost)/nonNegative(masterCaseQty):0;
  const totalCOGS=units>0?(isMultiPack?(perJointCOGS*safeJointsPerPack+multiPackPkgCost+masterCaseCostPerUnit+testCostPerUnit):(perJointCOGS+testCostPerUnit)):0;
  const concNeeded=prType==='infused'?totalJoints*nonNegative(concAmountG):0;
  const rosinNeeded=prType==='hashhole'?totalJoints*safeHashHoleRosinG:0;
  const listMargin=safeWsList-totalCOGS;
  const listMarginPct=safeWsList>0?(listMargin/safeWsList)*100:0;
  const floorMargin=safeWsFloor-totalCOGS;
  const floorMarginPct=safeWsFloor>0?(floorMargin/safeWsFloor)*100:0;

  /* net/take-home */
  const isFlat=distroModel==='wholesale'&&pricingMode==='flat';
  const isPct=distroModel==='percentage';
  const distroPerUnit=isPct?safeWsList*(safeDistroMargin/100):0;
  const effectiveRevPerUnit=isPct?safeWsList:(isFlat?safeWsList:safeWsList*(1-safeDistroMargin/100));
  const salesPerUnit=effectiveRevPerUnit*(safeSalesComm/100);
  const sampleUnits=Math.ceil(units*(safeSamplePct/100));
  const samplePerUnit=units>0?(sampleUnits*totalCOGS)/units:0;
  const netPerUnit=effectiveRevPerUnit-totalCOGS-distroPerUnit-salesPerUnit-samplePerUnit-nonNegative(overheadPerUnit);
  const netTotal=netPerUnit*units;
  const netMarginPct=effectiveRevPerUnit>0?(netPerUnit/effectiveRevPerUnit)*100:0;
  const revenueAfterDistro=effectiveRevPerUnit-distroPerUnit;
  const netAfterRepsSamples=effectiveRevPerUnit-distroPerUnit-salesPerUnit-samplePerUnit;

  /* progress */
  const sku_done=!!skuName;
  const yield_done=inputLbs>0&&units>0;
  const pricing_done=wsList>0;
  const takehome_done=netPerUnit>0;
  const prerollProducts=products.filter(p=>p.category==='prerolls');
  const mix_done=prerollProducts.length>0;

  useEffect(()=>{
    setProgress({raw:true,sku:sku_done,yield:yield_done,pricing:pricing_done,takehome:takehome_done,addmix:mix_done});
  },[sku_done,yield_done,pricing_done,takehome_done,mix_done]);

  const canAdd=units>0&&wsList>0;
  const addProduct=()=>{
    const typeLabel=prType==='standard'?'Standard':prType==='infused'?'Infused':'Hash Hole';
    const packLabel=isMultiPack?` (${safeJointsPerPack}-pk)`:'';
    setProducts(p=>[...p,{
      id:uid(),category:'prerolls',skuName:skuName||`${typeLabel} ${safeJointWeight}g${packLabel} ${gradeObj.label}`,
      prType:typeLabel,inputMaterial:`${inputLbs} lb`,
      grade:gradeObj.label,weight:`${safeJointWeight}g`,method:method==='hand'?'Hand Roll':'Machine',
      isMultiPack,jointsPerPack:isMultiPack?safeJointsPerPack:1,totalJoints,
      flowerCost:flowerCostJoint,laborCost,concCost,rosinCost,
      pkgCost:conePaperCost+filterCost+tubeCost+boxCost,multiPackPkgCost,masterCaseCostPerUnit,
      coaCost:COA_LABEL,testCostPerUnit,totalCOGS,
      consumerRetail:nonNegative(consumerRetail),wsList:safeWsList,wsFloor:safeWsFloor,listMarginPct,floorMarginPct,units,
      totalRevenue:safeWsList*units,totalCOGSAll:totalCOGS*units,totalProfit:listMargin*units
    }]);
  };

  const railBand=bandForMargin(netMarginPct);
  const typeLabelMap={standard:'Standard',infused:'Infused',hashhole:'Hash Hole'};

  return(<div className="shell">
    <div className="col-main">
      {/* README */}
      <div className="readme">
        <p><strong style={{color:'var(--text)'}}>pre-roll math.</strong> one <code>batch_lbs</code> of flower yields a total number of <code>joints</code> after loss. if you're selling <code>multi_packs</code>, joints divide by pack size to get <code>units</code>. <code>cogs</code> per joint = flower + rolling labor + cone + tube/box + COA. infused and hash holes add concentrate or rosin cost on top. <strong style={{color:'var(--accent)'}}>take-home</strong> = ws_list − cogs − distro − reps − samples.</p>
        <div className="bands">
          <span className="band premium"><b>45%+</b> excellent</span>
          <span className="band strong"><b>30–45%</b> strong</span>
          <span className="band average"><b>20–30%</b> average</span>
          <span className="band thin"><b>10–20%</b> thin</span>
          <span className="band low"><b>&lt;10%</b> unviable</span>
        </div>
      </div>

      <Section stepId="raw" idx={1} title="raw material costs · per lb" done={true} note="synced with flower tab">
        <p className="section-desc">what you pay per pound of raw flower. shared with the flower tab — change here or there, both update.</p>
        <div className="g3">
          {FLOWER_GRADES.map(g=><Field key={g.id} label={g.id} prefix="$" suffix="/lb" value={rawCosts[g.id]||g.defaultPerLb} onChange={v=>setRawCosts(c=>({...c,[g.id]:v}))}/>)}
        </div>
      </Section>

      <Section stepId="sku" idx={2} title="configure sku" done={sku_done} active={!sku_done}>
        <div className="g-sku">
          <Field highlight label="sku_name" type="text" value={skuName} onChange={setSkuName} hint="strain or product name" tip="The name you'll sell this under. Example: 'Runtz 1g Preroll'."/>
          <Field highlight label="preroll_type" value={prType} onChange={setPrType} options={[{value:'standard',label:'Standard Flower'},{value:'infused',label:'Infused'},{value:'hashhole',label:'Hash Hole'}]} tip="Standard = plain flower. Infused = flower coated/dipped in distillate or resin. Hash Hole = flower wrapped around a rosin core."/>
          <Field highlight label="grade" value={flowerGrade} onChange={setFlowerGrade} options={FLOWER_GRADES.map(g=>({value:g.id,label:g.label}))} tip="Flower quality tier used for the joint."/>
          <Field highlight label="joint_weight" value={jointWeight} onChange={setJointWeight} suffix="g" step={0.1} tip="Weight of flower in each joint. 1g is standard, 1.5g is king-size, 0.5g is a mini."/>
        </div>
        {prType!=='hashhole'&&<div style={{marginTop:12}}>
          <SubHead title="production method"/>
          <Seg options={[{value:'machine',label:'machine (knockbox)'},{value:'hand',label:'hand_roll'}]} value={method} onChange={setMethod}/>
        </div>}

        <SubHead title="flower blend" note="mix two grades for a tuned strain cost"/>
        <Seg options={[{value:false,label:'single_grade'},{value:true,label:'blend_grades'}]} value={useBlend} onChange={setUseBlend}/>
        {useBlend&&<div style={{marginTop:12,background:'var(--surface-2)',border:'1px solid var(--border)',borderRadius:'var(--r-sm)',padding:14}}>
          <div className="g3">
            <Field label="secondary_grade" value={blendGrade2} onChange={setBlendGrade2} options={FLOWER_GRADES.filter(g=>g.id!==flowerGrade).map(g=>({value:g.id,label:g.label}))}/>
            <div className="field">
              <label>blend_ratio <span style={{color:'var(--muted)',fontWeight:400,textTransform:'none',letterSpacing:0,fontSize:11}}>&nbsp;{100-blendTrimPct}% {gradeObj.label} / {blendTrimPct}% {grade2Obj.label}</span></label>
              <input type="range" min={5} max={95} value={blendTrimPct} onChange={e=>setBlendTrimPct(parseInt(e.target.value))} style={{width:'100%',accentColor:'var(--accent)',marginTop:10}}/>
            </div>
            <Stat label="blended_cost/g" value={fmt(blendedCostPerGram)} sub={`vs ${fmt(costPerGram)}/g single`} tone={blendedCostPerGram<costPerGram?'pos':'warn'}/>
          </div>
          <div style={{fontSize:11,color:'var(--muted)',marginTop:10,fontFamily:'var(--mono)'}}>
            per_joint_mix:&nbsp;{(flowerGramsInJoint*((100-safeBlendTrimPct)/100)).toFixed(2)}g {gradeObj.label} + {(flowerGramsInJoint*(safeBlendTrimPct/100)).toFixed(2)}g {grade2Obj.label}
          </div>
        </div>}
      </Section>

      <Section stepId="sku" idx={3} title="labor · materials · add-ons" done={true}>
        <SubHead title="rolling labor & packaging materials"/>
        <div className="g4">
          <Field label={method==='hand'?'hand_labor / joint':'machine_labor / joint'} prefix="$" value={method==='hand'?handLaborCost:machineLaborCost} onChange={method==='hand'?setHandLaborCost:setMachineLaborCost}/>
          {method==='machine'&&prType!=='hashhole'&&<Field label="pack_labor / joint" prefix="$" value={packLaborCost} onChange={setPackLaborCost} step={0.05}/>}
          <Field label="qc_labor" prefix="$" value={qcLaborCost} onChange={setQcLaborCost} step={0.05} hint="weight check, inspect"/>
          <Field label="pkg_labor" prefix="$" value={pkgLaborCost} onChange={setPkgLaborCost} step={0.05} hint="tube, box, label"/>
          <Field label="cone_paper" prefix="$" value={conePaperCost} onChange={setConePaperCost} step={0.01}/>
          <Field label="filter_crutch" prefix="$" value={filterCost} onChange={setFilterCost} step={0.01}/>
          <Field label="tube / joint" prefix="$" value={tubeCost} onChange={setTubeCost} step={0.05}/>
          <Field label="box / joint" prefix="$" value={boxCost} onChange={setBoxCost} step={0.05}/>
        </div>
        <Stat label="labor / joint total" value={fmt(laborCost)} sub={`${prType==='hashhole'?'Hash Hole':method==='hand'?'Hand roll':'Machine+pack'} ${fmt(baseLaborCost)} + qc ${fmt(qcLaborCost)} + pkg ${fmt(pkgLaborCost)}${prType==='infused'?' + infusion '+fmt(infusionLaborCost):''}`} tone="warn"/>

        {prType==='infused'&&<>
          <SubHead title="infusion materials" note="distillate · live resin · rosin"/>
          <div className="g3">
            <Field label="concentrate_type" value={concType} onChange={v=>{setConcType(v);setConcCostPerG(v==='distillate'?1:v==='liveresin'?6:10);}} options={[{value:'distillate',label:'Distillate (~$1/g)'},{value:'liveresin',label:'Live Resin (~$6/g)'},{value:'rosin',label:'Hash Rosin (~$10/g)'}]}/>
            <Field label="concentrate_cost / g" prefix="$" value={concCostPerG} onChange={setConcCostPerG}/>
            <Field label="concentrate_amount" value={concAmountG} onChange={setConcAmountG} suffix="g" step={0.05}/>
          </div>
          <div className="g4" style={{marginTop:12}}>
            <div className="field"><label>add_kief_coating?</label>
              <Seg options={[{value:true,label:'yes'},{value:false,label:'no'}]} value={useKief} onChange={setUseKief} size="sm"/>
            </div>
            {useKief&&<Field label="kief_cost / joint" prefix="$" value={kiefCost} onChange={setKiefCost} step={0.05}/>}
            <Field label="infusion_labor / joint" prefix="$" value={infusionLaborCost} onChange={setInfusionLaborCost} step={0.25}/>
            <Stat label="total_infusion" value={fmt(concCost+infusionLaborCost)} sub={`mat ${fmt(concCost)} + lab ${fmt(infusionLaborCost)}`} tone="warn"/>
          </div>
        </>}

        {prType==='hashhole'&&<>
          <SubHead title="hash hole core" note="rosin snake through center"/>
          <div className="g4">
            <Field label="rosin / joint" value={hashHoleRosinG} onChange={setHashHoleRosinG} suffix="g" step={0.1}/>
            <Field label="rosin_cost / g" prefix="$" value={hashHoleRosinCost} onChange={setHashHoleRosinCost}/>
            <Field label="hashhole_labor" prefix="$" value={hashHoleLaborCost} onChange={setHashHoleLaborCost}/>
            <Stat label="flower_in_joint" value={`${(safeJointWeight-safeHashHoleRosinG).toFixed(2)}g`} sub={`${safeJointWeight}g − ${safeHashHoleRosinG}g rosin`}/>
          </div>
        </>}

        <SubHead title="pack format" note="single joint or multi-pack"/>
        <Seg options={[{value:false,label:'single_joint'},{value:true,label:'multi_pack'}]} value={isMultiPack} onChange={setIsMultiPack}/>
        {isMultiPack&&<>
          <div className="g4" style={{marginTop:12}}>
            <Field label="joints_per_pack" value={jointsPerPack} onChange={setJointsPerPack} min={2} max={20} step={1}/>
            <Field label="multipack_box" prefix="$" value={multiPackBoxCost} onChange={setMultiPackBoxCost} step={0.05}/>
            <Field label="pack_insert" prefix="$" value={multiPackInsertCost} onChange={setMultiPackInsertCost} step={0.05}/>
            <Field label="pack_assembly_labor" prefix="$" value={multiPackLaborCost} onChange={setMultiPackLaborCost} step={0.05}/>
          </div>
          <div className="g3" style={{marginTop:12}}>
            <Field label="master_case_qty" value={masterCaseQty} onChange={setMasterCaseQty} min={1} step={1} hint="packs per case"/>
            <Field label="master_case_cost" prefix="$" value={masterCaseCost} onChange={setMasterCaseCost} step={0.25}/>
            <Stat label="case_cost / pack" value={fmt(masterCaseCostPerUnit)} sub={`${fmt(masterCaseCost)} ÷ ${Math.max(1,nonNegative(masterCaseQty))}`} tone="warn"/>
          </div>
          <Stat label="multipack_pkg_total" value={fmt(multiPackPkgCost+masterCaseCostPerUnit)} sub={`box ${fmt(multiPackBoxCost)} + ins ${fmt(multiPackInsertCost)} + lab ${fmt(multiPackLaborCost)} + case ${fmt(masterCaseCostPerUnit)}`} tone="warn"/>
        </>}
      </Section>

      <Section stepId="yield" idx={4} title="input quantity · yield · testing" done={yield_done} active={sku_done&&!yield_done}>
        <div className="g3">
          <Field highlight label="flower_purchased" value={inputLbs} onChange={setInputLbs} suffix="lbs" step={0.5} min={0.5} tip="How many pounds of raw flower you're running in this batch."/>
          <Field label="loss_factor" value={lossPct} onChange={setLossPct} suffix="%" step={0.5} hint="grind · spill · fill" tip="Flower lost during grinding, filling, and waste. 3–8% is typical for prerolls."/>
          <Field label="testing_batch" prefix="$" value={testCostBatch} onChange={setTestCostBatch} hint="cost per compliance batch"/>
        </div>
        <div className="g4" style={{marginTop:12}}>
          <Stat label="usable_flower" value={`${usableGrams.toFixed(0)}g`} sub={`after ${lossPct}% loss`}/>
          <Stat label="total_joints" value={totalJoints.toLocaleString()} sub={`${usableGrams.toFixed(0)}g ÷ ${flowerPerJoint}g/jt`} tone="pos"/>
          {isMultiPack&&<Stat label="finished_packs" value={units.toLocaleString()} sub={`${totalJoints.toLocaleString()} jts ÷ ${safeJointsPerPack}/pk`} tone="pos"/>}
          {!isMultiPack&&<Stat label="finished_units" value={units.toLocaleString()} sub="same as joints" tone="pos"/>}
          {prType==='infused'&&<Stat label="concentrate_needed" value={`${concNeeded.toFixed(0)}g`} sub={`${totalJoints} × ${nonNegative(concAmountG)}g`} tone="warn"/>}
          {prType==='hashhole'&&<Stat label="rosin_needed" value={`${rosinNeeded.toFixed(0)}g`} sub={`${totalJoints} × ${safeHashHoleRosinG}g`} tone="warn"/>}
          <Stat label="material_cost" value={fmtK(materialCost)} sub={useBlend?`${safeInputLbs} lb blended`:`${safeInputLbs} lb × ${fmt(costPerLb)}/lb`}/>
        </div>
        <div className="g2" style={{marginTop:12}}>
          <Field label="test_cost / unit" prefix="$" value={testCostPerUnit.toFixed(2)} disabled suffix={`per ${isMultiPack?'pack':'joint'}`}/>
          <Stat label="test_spread" value={fmt(testCostPerUnit)} sub={`${fmt(testCostBatch)} ÷ ${units} ${isMultiPack?'packs':'joints'}`} tone="warn"/>
        </div>

        <SubHead title="per-unit cogs breakdown"/>
        <Waterfall caption={`every line is a cost going into one ${isMultiPack?safeJointsPerPack+'-pack':'joint'}. added together = your cogs.`}
          lines={[
            ...(isMultiPack?[{label:'// per_joint_costs (× '+safeJointsPerPack+')',value:'',tone:'dim'}]:[]),
            {label:`flower_material  (${fmtK(materialCost)} / ${totalJoints||0} joints)`,value:fmt(flowerCostJoint)},
            ...(prType==='infused'?[{label:`concentrate  (${nonNegative(concAmountG)}g ${concType}${useKief?' + kief':''})`,value:fmt(concCost),tone:'warn'}]:[]),
            ...(prType==='hashhole'?[{label:`rosin  (${safeHashHoleRosinG}g × ${fmt(hashHoleRosinCost)}/g)`,value:fmt(rosinCost),tone:'warn'}]:[]),
            {label:`rolling_labor  (${prType==='hashhole'?'hash hole':method==='hand'?'hand':'machine+pack'})`,value:fmt(baseLaborCost)},
            ...(prType==='infused'?[{label:'infusion_labor',value:fmt(infusionLaborCost)}]:[]),
            {label:'qc_labor',value:fmt(qcLaborCost)},
            {label:'pkg_labor',value:fmt(pkgLaborCost)},
            {label:'cone + filter',value:fmt(conePaperCost+filterCost)},
            {label:'tube + box',value:fmt(tubeCost+boxCost)},
            {label:'coa_label',value:fmt(COA_LABEL)},
            ...(isMultiPack?[
              {label:`per_joint_subtotal`,value:fmt(perJointCOGS),tone:'dim'},
              {label:`// pack_level_costs`,value:'',tone:'dim'},
              {label:`${safeJointsPerPack} joints × ${fmt(perJointCOGS)}`,value:fmt(perJointCOGS*safeJointsPerPack)},
              {label:'multipack_box',value:fmt(multiPackBoxCost)},
              {label:'pack_insert',value:fmt(multiPackInsertCost)},
              {label:'pack_assembly_labor',value:fmt(multiPackLaborCost)},
              {label:`master_case  (${fmt(masterCaseCost)} ÷ ${Math.max(1,nonNegative(masterCaseQty))})`,value:fmt(masterCaseCostPerUnit)}
            ]:[]),
            {label:`testing  (${fmt(testCostBatch)} ÷ ${units} ${isMultiPack?'pks':'jts'})`,value:fmt(testCostPerUnit)}
          ]}
          total={fmt(totalCOGS)} totalLabel={`cogs / ${isMultiPack?'pack':'joint'}`}/>
      </Section>

      <Section stepId="pricing" idx={5} title="pricing · margin bands" done={pricing_done} active={yield_done&&!pricing_done}>
        {!isFlat&&<div className="g4">
          <Field highlight label="ws_list" prefix="$" value={wsList} onChange={v=>{setWsList(v);setConsumerRetail(+(v*markupX).toFixed(2));}} hint="what you charge the store"/>
          <Field highlight label="ws_floor" prefix="$" value={wsFloor} onChange={setWsFloor} hint="lowest you'd accept"/>
          <Field label="markup" value={markupX} onChange={v=>{setMarkupX(v);setConsumerRetail(+(wsList*v).toFixed(2));}} suffix="×" step={0.1} hint="store's retail multiplier"/>
          <Field label="retail" prefix="$" value={consumerRetail} onChange={v=>{setConsumerRetail(v);if(wsList>0)setMarkupX(+(v/wsList).toFixed(2));}} hint="what customers pay"/>
        </div>}
        {isFlat&&<div className="g2">
          <Field label="flat_price_to_distro" prefix="$" value={wsList} onChange={v=>{setWsList(v);setConsumerRetail(+(v*markupX).toFixed(2));}} hint="what the distro pays you"/>
          <div style={{alignSelf:'center',color:'var(--muted)',fontSize:12,lineHeight:1.6}}>selling flat to a distributor — they handle retail pricing.</div>
        </div>}

        <SubHead title="benchmarks"/>
        {!isFlat?<div className="g2">
          <BenchBar name="gm @ list" pct={listMarginPct}/>
          <BenchBar name="gm @ floor" pct={floorMarginPct}/>
        </div>:<BenchBar name="gm @ flat" pct={listMarginPct}/>}

        <SubHead title="deductions waterfall" note="revenue → take-home"/>
        <Waterfall caption="every deduction from revenue down to what you pocket per unit."
          lines={[
            {label:isFlat?'flat_price_to_distro':'ws_list',value:fmt(effectiveRevPerUnit),sign:'+ '},
            {label:'cogs',value:fmt(totalCOGS),sign:'− ',tone:'neg'},
            ...(isPct?[{label:`distro_fee  (${safeDistroMargin}% of invoice)`,value:fmt(distroPerUnit),sign:'− ',tone:'warn'}]:[]),
            {label:`sales_reps  (${safeSalesComm}%)`,value:fmt(salesPerUnit),sign:'− ',tone:'warn'},
            {label:`samples  (${safeSamplePct}% at cogs)`,value:fmt(samplePerUnit),sign:'− ',tone:'warn'},
            ...(overheadPerUnit>0?[{label:'overhead',value:fmt(overheadPerUnit),sign:'− ',tone:'neg'}]:[])
          ]}
          total={fmt(netPerUnit)} totalLabel="take-home / unit"/>
      </Section>

      <Section stepId="takehome" idx={6} title="distribution & sales" done={takehome_done} active={pricing_done&&!takehome_done} note="syncs across all tabs">
        <p className="section-desc">these settings apply to every product tab — change once, updates everywhere.</p>
        <Seg options={[
          {value:'pct',label:'distro_takes_fee'},
          {value:'flat',label:'sell_at_flat_price'},
          {value:'discount',label:'sell_at_discount'}
        ]} value={distroModel==='percentage'?'pct':(pricingMode==='flat'?'flat':'discount')}
        onChange={v=>{
          if(v==='pct'){setDistroModel('percentage');setPricingMode('pct');setDistroMargin(10);}
          else if(v==='flat'){setDistroModel('wholesale');setPricingMode('flat');}
          else {setDistroModel('wholesale');setPricingMode('pct');setDistroMargin(20);}
        }}/>
        <div className="g4" style={{marginTop:12}}>
          {distroModel==='percentage'&&<Field highlight label="distro_pct" value={distroMargin} onChange={setDistroMargin} suffix="%" hint="% of your invoice"/>}
          {distroModel==='wholesale'&&pricingMode==='pct'&&<Field highlight label="discount_pct" value={distroMargin} onChange={setDistroMargin} suffix="%" hint="% off ws_list"/>}
          {isFlat&&<Field highlight label="flat_price" prefix="$" value={wsList} onChange={v=>setWsList(v)} hint="per unit to distro"/>}
          <Field highlight label="sales_rep_commission" value={salesComm} onChange={setSalesComm} suffix="%"/>
          <Field label="samples_pct" value={samplePct} onChange={setSamplePct} suffix="%" hint="% given away"/>
          <Field label="overhead_per_unit" prefix="$" value={overheadPerUnit} onChange={setOverheadPerUnit} step={0.05} hint="optional"/>
        </div>
        <div className="g3" style={{marginTop:14}}>
          <Stat label="revenue_after_distro" value={fmt(revenueAfterDistro)} sub={isPct?`${fmt(effectiveRevPerUnit)} − ${fmt(distroPerUnit)} fee`:`distro pays you directly`}/>
          <Stat label="net_after_reps_samples" value={fmt(netAfterRepsSamples)} sub={`− ${fmt(salesPerUnit)} reps − ${fmt(samplePerUnit)} samples`} tone="warn"/>
          <Stat label="take_home / unit" value={fmt(netPerUnit)} sub={`${netMarginPct.toFixed(1)}% net margin`} tone={netPerUnit>0?'pos':'neg'}/>
        </div>
      </Section>

      <Section stepId="takehome" idx={7} title="batch totals · full run" done={units>0}>
        <div className="g3">
          <Stat label="capital_required" value={fmtK(totalCOGS*units)} sub={`${fmt(totalCOGS)}/u × ${units.toLocaleString()}`} tone="neg"/>
          <Stat label="revenue_at_list" value={fmtK(effectiveRevPerUnit*units)} sub={`${fmt(effectiveRevPerUnit)}/u × ${units.toLocaleString()}`}/>
          <Stat label="gross_profit" value={fmtK(listMargin*units)} sub="before distro/reps/samples" tone={listMargin>0?'pos':'neg'}/>
        </div>
        <div className="g3" style={{marginTop:12}}>
          <Stat label="take_home_batch" value={fmtK(netTotal)} sub={`${units.toLocaleString()} × ${fmt(netPerUnit)}`} tone={netTotal>0?'pos':'neg'}/>
          <Stat label="return_on_capital" value={totalCOGS*units>0?`${(netTotal/(totalCOGS*units)*100).toFixed(1)}%`:'—'} sub="take-home / capital" tone={netTotal>0?'pos':'neg'}/>
          <Stat label="net_margin" value={`${netMarginPct.toFixed(1)}%`} sub={bandForMargin(netMarginPct).label} tone={bandForMargin(netMarginPct).idx>=3?'pos':bandForMargin(netMarginPct).idx>=2?'warn':'neg'}/>
        </div>
      </Section>

      <Section stepId="addmix" idx={8} title="add to product mix" done={mix_done} active={takehome_done&&!mix_done}>
        <p className="section-desc">save this SKU. build your full preroll lineup — types, grades, weights, pack formats. your mix feeds the distro and forecast tabs.</p>
        <div style={{display:'flex',gap:8,flexWrap:'wrap'}}>
          <button className="btn primary" onClick={addProduct} disabled={!canAdd}>[+] add_to_mix</button>
          {prerollProducts.length>0&&<button className="btn outline" onClick={()=>exportPrerollsCSV(products)}>export prerolls csv</button>}
        </div>
        {prerollProducts.length>0&&<div style={{marginTop:16}}>
          <SubHead title="preroll product mix"/>
          <div className="tbl-wrap"><table className="tbl">
            <thead><tr>
              <th>sku</th><th>type</th><th>grade</th><th>wt</th><th>method</th><th>format</th>
              <th>cogs/u</th><th>ws_list</th><th>ws_floor</th><th>retail</th><th>margin</th>
              <th>units</th><th>revenue</th><th>gross</th><th></th>
            </tr></thead>
            <tbody>{prerollProducts.map(p=><tr key={p.id}>
              <td className="sku">{p.skuName}</td>
              <td className="dim">{p.prType}</td>
              <td className="dim">{p.grade}</td>
              <td className="dim">{p.weight}</td>
              <td className="dim">{p.method}</td>
              <td className="dim">{p.isMultiPack?`${p.jointsPerPack}-pk`:'single'}</td>
              <td>{fmt(p.totalCOGS)}</td>
              <td className="pos">{fmt(p.wsList)}</td>
              <td className="warn">{fmt(p.wsFloor)}</td>
              <td className="dim">{fmt(p.consumerRetail)}</td>
              <td style={{color:bandForMargin(p.listMarginPct).color}}>{p.listMarginPct.toFixed(1)}%</td>
              <td>{p.units.toLocaleString()}</td>
              <td>{fmtK(p.totalRevenue)}</td>
              <td className="pos">{fmtK(p.totalProfit)}</td>
              <td><button className="btn danger sm" onClick={()=>setProducts(ps=>ps.filter(x=>x.id!==p.id))}>×</button></td>
            </tr>)}</tbody>
          </table></div>
        </div>}
      </Section>
    </div>

    {/* RAIL */}
    <aside className="rail">
      <div className="rail-card">
        <div className="rail-panel head">
          <div className="rail-eyebrow">live sku</div>
          <div className="rail-title">{skuName||'untitled preroll'}</div>
          <div className="rail-meta">{typeLabelMap[prType]} · {safeJointWeight}g · {gradeObj.label}{isMultiPack?` · ${safeJointsPerPack}-pk`:''}</div>
        </div>
        <div className="rail-panel">
          <div className="rail-hero-label">take-home / {isMultiPack?'pack':'joint'}</div>
          <div className={`rail-hero-val ${netPerUnit<0?'neg':''}`}>{fmt(netPerUnit)}</div>
          <div className="rail-hero-sub">{netMarginPct.toFixed(1)}% of {isFlat?'flat_price':'ws_list'}</div>
        </div>
        <div className="rail-panel">
          <div className="rail-ledger">
            <div className="r"><span className="lbl">{isFlat?'flat_price':'ws_list'}</span><span className="val">+ {fmt(effectiveRevPerUnit)}</span></div>
            <div className="r neg"><span className="lbl">cogs</span><span className="val">− {fmt(totalCOGS)}</span></div>
            {isPct&&<div className="r warn"><span className="lbl">distro</span><span className="val">− {fmt(distroPerUnit)}</span></div>}
            <div className="r warn"><span className="lbl">reps</span><span className="val">− {fmt(salesPerUnit)}</span></div>
            <div className="r warn"><span className="lbl">samples</span><span className="val">− {fmt(samplePerUnit)}</span></div>
            <div className="rule"></div>
            <div className="r total"><span className="lbl">net</span><span className="val">{fmt(netPerUnit)}</span></div>
          </div>
        </div>
        <div className="rail-panel">
          <div className="rail-grid">
            <div className="rail-stat"><span className="lbl">joints</span><span className="val">{totalJoints.toLocaleString()}</span></div>
            <div className="rail-stat"><span className="lbl">{isMultiPack?'packs':'units'}</span><span className="val">{units.toLocaleString()}</span></div>
            <div className="rail-stat"><span className="lbl">revenue</span><span className="val">{fmtK(effectiveRevPerUnit*units)}</span></div>
            <div className="rail-stat"><span className="lbl">take-home</span><span className="val pos">{fmtK(netTotal)}</span></div>
          </div>
        </div>
        <div className="rail-panel">
          <button className="btn primary" style={{width:'100%',justifyContent:'center'}} onClick={addProduct} disabled={!canAdd}>[+] add_to_mix</button>
        </div>
      </div>
      <div className="bench-callout">
        <span className="pct" style={{color:railBand.color}}>{netMarginPct.toFixed(1)}%</span> — <b style={{color:railBand.color}}>{railBand.label}</b> band for {typeLabelMap[prType]} prerolls.
      </div>

      {prerollProducts.length>0&&<div className="mix-mini">
        <div className="mix-mini-head">
          <span className="mix-eyebrow">preroll_mix</span>
          <span className="mix-count">{prerollProducts.length} sku{prerollProducts.length>1?'s':''}</span>
        </div>
        <div className="mix-list">
          {prerollProducts.map(p=>{
            const b=bandForMargin(p.listMarginPct);
            return(<div key={p.id} className="mix-item">
              <div className="mix-row-top">
                <span className="mix-sku" title={p.skuName}>{p.skuName}</span>
                <button className="mix-x" onClick={()=>setProducts(ps=>ps.filter(x=>x.id!==p.id))} title="remove">×</button>
              </div>
              <div className="mix-row-mid">
                <span className="mix-meta">{p.prType.toLowerCase()} · {p.weight} · {p.units.toLocaleString()}{p.isMultiPack?'pk':'u'}</span>
                <span className="mix-pct" style={{color:b.color}}>{p.listMarginPct.toFixed(0)}%</span>
              </div>
              <div className="mix-row-bot">
                <span className="mix-price">{fmt(p.wsList)} <span className="dim">/{p.isMultiPack?'pk':'u'}</span></span>
                <span className="mix-profit">{fmtK(p.totalProfit)}</span>
              </div>
            </div>);
          })}
        </div>
      </div>}
    </aside>
  </div>);
}

Object.assign(window,{PrerollsTab,exportPrerollsCSV});
