/* Main App — Flower Terminal Redesign
   FlowerCalc includes its own rail rendered via React Portal to keep state local.
   Other tabs get minimal reskin placeholders. */

const exportFlowerCSV=(products)=>{
  const filtered=products.filter(p=>p.category==='flower');
  if(filtered.length===0)return alert('No flower products yet.');
  const cols=['SKU','Grade','Size','Input','COGS/Unit','WS List','WS Floor','Retail','List Margin %','Units','Revenue','Gross Profit'];
  const rows=filtered.map(p=>[p.skuName,p.grade,p.size,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-flower.csv';a.click();URL.revokeObjectURL(url);
};

/* ============ FlowerTab (combines calc + rail via shared state) ============ */
function FlowerTab({products,setProducts,rawCosts,setRawCosts,distroState,setProgress}){
  /* --- State --- */
  const [grade,setGrade]=useState('indoor');
  const [size,setSize]=useState('eighth');
  const [pkgType,setPkgType]=useState('glass');
  const [pkgCostOverride,setPkgCostOverride]=useState(null);
  const [skuName,setSkuName]=useState('');
  const [inputLbs,setInputLbs]=useState(1);
  const [lossPct,setLossPct]=useState(3);
  const [consumerRetail,setConsumerRetail]=useState(45);
  const [wsList,setWsList]=useState(25);
  const [wsFloor,setWsFloor]=useState(20);
  const [testCostBatch,setTestCostBatch]=useState(400);
  const [testPrePaid,setTestPrePaid]=useState(false);
  const [testBatchLbs,setTestBatchLbs]=useState(0);
  const [isInfused,setIsInfused]=useState(false);
  const [infusionItems,setInfusionItems]=useState([{name:'Distillate Coating',costPerG:1.00,gramsPerUnit:0.5}]);
  const [markupX,setMarkupX]=useState(2.0);
  const [infusionLaborCost,setInfusionLaborCost]=useState(0);
  const [pkgLaborCost,setPkgLaborCost]=useState(1.00);
  const [overheadPerUnit,setOverheadPerUnit]=useState(0);

  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 gradeObj=FLOWER_GRADES.find(g=>g.id===grade);
  const sizeObj=PKG_SIZES.find(s=>s.id===size);
  const pkgObj=PKG_TYPES.find(p=>p.id===pkgType);
  const safeInputLbs=nonNegative(inputLbs);
  const safeLossPct=clamp(lossPct,0,100);
  const safeSizeGrams=positiveOr(sizeObj.grams);
  const safeWsList=nonNegative(wsList);
  const safeWsFloor=nonNegative(wsFloor);
  const safeDistroMargin=pct(distroMargin);
  const safeSalesComm=pct(salesComm);
  const safeSamplePct=pct(samplePct);
  const costPerLb=nonNegative(rawCosts[grade]||gradeObj.defaultPerLb);
  const pkgCost=nonNegative(pkgCostOverride!==null?pkgCostOverride:pkgObj.costs[size]);
  const infusionMaterialCost=isInfused?infusionItems.reduce((s,it)=>s+nonNegative(it.costPerG)*nonNegative(it.gramsPerUnit),0):0;
  const infusionCostPerUnit=infusionMaterialCost+(isInfused?nonNegative(infusionLaborCost):0);
  const usableGrams=safeInputLbs*GRAMS_PER_LB*(1-safeLossPct/100);
  const units=Math.max(0,Math.floor(usableGrams/safeSizeGrams));
  const batchMaterialCost=safeInputLbs*costPerLb;
  const flowerCost=units>0?batchMaterialCost/units:0;
  const safeTestBatchLbs=nonNegative(testBatchLbs);
  const safeTestCostBatch=nonNegative(testCostBatch);
  const effectiveBatchLbs=safeTestBatchLbs>0?Math.min(safeTestBatchLbs,safeInputLbs):safeInputLbs;
  const batchUnits=Math.max(0,Math.floor(effectiveBatchLbs*GRAMS_PER_LB*(1-safeLossPct/100)/safeSizeGrams));
  const testCostPerUnit=testPrePaid?0:(batchUnits>0?safeTestCostBatch/batchUnits:0);
  const totalCOGS=units>0?(flowerCost+pkgCost+nonNegative(pkgLaborCost)+COA_LABEL+testCostPerUnit+infusionCostPerUnit):0;
  const materialCost=batchMaterialCost;
  const lossGrams=safeInputLbs*GRAMS_PER_LB*(safeLossPct/100);
  const listMargin=safeWsList-totalCOGS;
  const listMarginPct=safeWsList>0?(listMargin/safeWsList)*100:0;
  const floorMargin=safeWsFloor-totalCOGS;
  const floorMarginPct=safeWsFloor>0?(floorMargin/safeWsFloor)*100:0;

  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;

  useEffect(()=>{
    setConsumerRetail(CONSUMER_RETAIL_DEFAULTS[grade]?.[size]||30);
    setWsList(WS_LIST_DEFAULTS[grade]?.[size]||18);
    setWsFloor(WS_FLOOR_DEFAULTS[grade]?.[size]||14);
    setPkgCostOverride(null);
  },[grade,size]);

  const sku_done=!!skuName;
  const yield_done=inputLbs>0&&units>0;
  const pricing_done=wsList>0;
  const takehome_done=netPerUnit>0;
  const flowerProducts=products.filter(p=>p.category==='flower');
  const mix_done=flowerProducts.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=()=>{
    setProducts(p=>[...p,{
      id:uid(),category:'flower',skuName:skuName||`${gradeObj.label} ${sizeObj.short}`,
      grade:gradeObj.label,size:sizeObj.label,inputMaterial:`${inputLbs} lb`,
      gramsPerUnit:sizeObj.grams,pkgType:pkgObj.label,
      flowerCost,pkgCost,pkgLaborCost,coaCost:COA_LABEL,testCostPerUnit,infusionCostPerUnit,totalCOGS,
      isInfused,consumerRetail:nonNegative(consumerRetail),wsList:safeWsList,wsFloor:safeWsFloor,
      listMarginPct,floorMarginPct,units,
      totalRevenue:safeWsList*units,totalCOGSAll:totalCOGS*units,totalProfit:listMargin*units
    }]);
  };
  window.__exportFlowerCSV=()=>exportFlowerCSV(products);

  const railBand=bandForMargin(netMarginPct);

  return(<div className="shell">
    <div className="col-main">
      {/* README */}
      <div className="readme">
        <p><strong style={{color:'var(--text)'}}>how the money flows.</strong> you sell to stores at your <code>ws_list</code> (that's income). stores mark up and sell to customers at <code>retail</code>. your <code>cogs</code> is everything it takes to make one unit — material, packaging, labor, testing, COA label. <strong style={{color:'var(--accent)'}}>take-home</strong> = ws_list minus cogs, distro fee, rep commission, and sample cost.</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}>
        <p className="section-desc">what you pay per pound for each grade. costs flow into every SKU you build below.</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 3.5g Jar'. You'll see this label on your product list and invoices."/>
          <Field highlight label="grade" value={grade} onChange={setGrade} options={FLOWER_GRADES.map(g=>({value:g.id,label:g.label}))} tip="Quality tier of the flower. Exotics = top-shelf designer strains. Indoor = premium. Deps = light-deprivation greenhouse. Outdoor = sun-grown. Smalls = small popcorn nugs. Trim = leaves/sugar leaf."/>
          <Field highlight label="size" value={size} onChange={setSize} options={PKG_SIZES.map(s=>({value:s.id,label:s.label}))} tip="How much flower goes in one package. 1/8 oz (3.5g) is the most common consumer size."/>
          <Field highlight label="packaging" value={pkgType} onChange={setPkgType} options={PKG_TYPES.map(p=>({value:p.id,label:p.label}))} tip="The container you put the flower in. Glass jars feel premium. Mylar bags are cheap. Miron (black glass) is top-end — blocks light."/>
        </div>
        <div className="g2" style={{marginTop:12}}>
          <Field label="pkg_cost" prefix="$" value={pkgCostOverride!==null?pkgCostOverride:pkgObj.costs[size]} onChange={v=>setPkgCostOverride(v)} hint={`default for ${pkgObj.label.toLowerCase()} + ${sizeObj.short}`} tip="How much one empty container costs you. Buying in bulk makes this cheaper."/>
          <Field label="pkg_labor" prefix="$" value={pkgLaborCost} onChange={setPkgLaborCost} step={0.05} hint="weigh / fill / seal / label" tip="How much it costs to pay someone to weigh flower, put it in the jar, seal it, and stick on the label — per unit."/>
        </div>
      </Section>

      <Section stepId="yield" idx={3} 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 bought to turn into this product. 1 lb = 453.6 grams."/>
          <Field label="loss_factor" value={lossPct} onChange={setLossPct} suffix="%" step={0.5} hint="stems · shake · scale variance" tip="How much flower you lose during packaging — stems, shake, tiny scale-off amounts. Usually 2–5%."/>
          <Field label="testing_batch" prefix="$" value={testCostBatch} onChange={setTestCostBatch} hint="cost per compliance batch" tip="How much the state-required lab test costs for one batch. Split across every unit made from that batch."/>
        </div>
        <div className="g4" style={{marginTop:12}}>
          <Stat label="theoretical_max" value={Math.floor(inputLbs*GRAMS_PER_LB/sizeObj.grams).toLocaleString()} sub={`${(inputLbs*GRAMS_PER_LB).toFixed(0)}g / ${sizeObj.grams}g`} tone="dim"/>
          <Stat label="loss" value={`${lossGrams.toFixed(0)}g`} sub={`${lossPct}% waste`} tone="neg"/>
          <Stat label="finished_units" value={units.toLocaleString()} sub={`${usableGrams.toFixed(0)}g usable`} tone="pos"/>
          <Stat label="material_cost" value={fmtK(materialCost)} sub={`${inputLbs} lb × ${fmt(costPerLb)}/lb`}/>
        </div>

        <SubHead title="compliance testing" note="spread batch fee across units"/>
        <Seg options={[{value:false,label:'testing_required'},{value:true,label:'pre_tested_no_cost'}]} value={testPrePaid} onChange={setTestPrePaid}/>
        {!testPrePaid&&<div className="g3" style={{marginTop:10}}>
          <Field label="test_batch_lbs" value={testBatchLbs} onChange={setTestBatchLbs} suffix="lbs" step={0.5} hint="0 = use input lbs"/>
          <Stat label="batch_yields" value={batchUnits.toLocaleString()} sub={`${effectiveBatchLbs} lbs → units`}/>
          <Stat label="test_cost / unit" value={fmt(testCostPerUnit)} sub={`${fmt(testCostBatch)} / ${batchUnits}`} tone="warn"/>
        </div>}
        {testPrePaid&&<div style={{marginTop:10}}><Stat label="test_cost / unit" value="$0.00" sub="pre-tested material" tone="pos"/></div>}

        <SubHead title="infused flower" note="moonrocks · snowcaps · terped"/>
        <Seg options={[{value:false,label:'standard'},{value:true,label:'infused'}]} value={isInfused} onChange={setIsInfused}/>
        {isInfused&&<div style={{marginTop:12,background:'var(--surface-2)',border:'1px solid var(--border)',borderRadius:'var(--r-sm)',padding:14}}>
          {infusionItems.map((it,i)=><div key={i} className="g4" style={{marginBottom:8,alignItems:'end'}}>
            <Field label="ingredient" type="text" value={it.name} onChange={v=>{const n=[...infusionItems];n[i]={...n[i],name:v};setInfusionItems(n);}}/>
            <Field label="cost_per_g" prefix="$" value={it.costPerG} onChange={v=>{const n=[...infusionItems];n[i]={...n[i],costPerG:v};setInfusionItems(n);}}/>
            <Field label={`g / ${sizeObj.short}`} value={it.gramsPerUnit} onChange={v=>{const n=[...infusionItems];n[i]={...n[i],gramsPerUnit:v};setInfusionItems(n);}} suffix="g" step={0.1}/>
            <div style={{display:'flex',gap:8,alignItems:'end'}}>
              <Stat label="cost/unit" value={fmt(it.costPerG*it.gramsPerUnit)} tone="warn"/>
              {infusionItems.length>1&&<button className="btn danger sm" onClick={()=>setInfusionItems(items=>items.filter((_,j)=>j!==i))}>×</button>}
            </div>
          </div>)}
          <div style={{display:'flex',gap:10,alignItems:'end',flexWrap:'wrap',marginTop:8}}>
            <button className="btn outline sm" onClick={()=>setInfusionItems(items=>[...items,{name:'',costPerG:0,gramsPerUnit:0}])}>+ ingredient</button>
            <div style={{flex:1,minWidth:160}}><Field label="infusion_labor" prefix="$" value={infusionLaborCost} onChange={setInfusionLaborCost} step={0.25}/></div>
            <Stat label="total_infusion" value={fmt(infusionCostPerUnit)} tone="warn"/>
          </div>
        </div>}

        <SubHead title="per-unit cogs breakdown"/>
        <Waterfall caption={`every line is a cost going into one ${sizeObj.short} unit. added together = your cogs.`}
          lines={[
            {label:`flower_material  (${fmtK(batchMaterialCost)} / ${units||0} units)`,value:fmt(flowerCost)},
            ...(isInfused?infusionItems.filter(it=>nonNegative(it.gramsPerUnit)>0).map(it=>({label:`${it.name||'infusion'}  (${nonNegative(it.gramsPerUnit)}g × ${fmt(nonNegative(it.costPerG))}/g)`,value:fmt(nonNegative(it.costPerG)*nonNegative(it.gramsPerUnit)),tone:'warn'})):[]),
            ...(isInfused&&infusionLaborCost>0?[{label:'infusion_labor',value:fmt(infusionLaborCost),tone:'warn'}]:[]),
            {label:`packaging  (${pkgObj.short})`,value:fmt(pkgCost)},
            {label:'pkg_labor',value:fmt(pkgLaborCost)},
            {label:'coa_label',value:fmt(COA_LABEL)},
            {label:`testing  (${fmt(testCostBatch)} / ${batchUnits} units)`,value:fmt(testCostPerUnit),tone:testPrePaid?'pos':''}
          ]}
          total={fmt(totalCOGS)} totalLabel="cogs / unit"/>
      </Section>

      <Section stepId="pricing" idx={4} 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" tip="Wholesale list price — what the dispensary pays you per unit. This is your sticker price to stores."/>
          <Field highlight label="ws_floor" prefix="$" value={wsFloor} onChange={setWsFloor} hint="lowest you'd accept" tip="The lowest price you'd ever accept. When a buyer pushes hard on price, you won't go below this."/>
          <Field label="markup" value={markupX} onChange={v=>{setMarkupX(v);setConsumerRetail(+(wsList*v).toFixed(2));}} suffix="×" step={0.1} hint="store's retail multiplier" tip="How much the store marks up your price before selling to customers. 2× means if you sell at $25, they charge $50."/>
          <Field label="retail" prefix="$" value={consumerRetail} onChange={v=>{setConsumerRetail(v);if(wsList>0)setMarkupX(+(v/wsList).toFixed(2));}} hint="what customers pay" tip="Final price a customer pays at the dispensary. You don't control this — the store sets it."/>
        </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. <code style={{color:'var(--text)',background:'var(--surface-2)',padding:'1px 6px',borderRadius:3,fontFamily:'var(--mono)',fontSize:11}}>ws_floor / markup / retail</code> hidden.</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={5} title="distribution & sales" done={takehome_done} active={pricing_done&&!takehome_done} note="syncs across all tabs">
        <p className="section-desc">choose how you work with distributors. 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" tip="What percent of every sale the distributor keeps as their fee. Industry standard is 10–20%."/>}
          {distroModel==='wholesale'&&pricingMode==='pct'&&<Field highlight label="discount_pct" value={distroMargin} onChange={setDistroMargin} suffix="%" hint="% off ws_list" tip="How much you discount your list price when selling to the distro — they take the rest as their margin."/>}
          {isFlat&&<Field highlight label="flat_price" prefix="$" value={wsList} onChange={v=>setWsList(v)} hint="per unit to distro" tip="Flat dollar amount the distro pays you per unit — negotiated up front, no percentages."/>}
          <Field highlight label="sales_rep_commission" value={salesComm} onChange={setSalesComm} suffix="%" tip="What percent your sales rep keeps as commission on each sale. Typically 3–10%."/>
          <Field label="samples_pct" value={samplePct} onChange={setSamplePct} suffix="%" hint="% given away" tip="How many units you hand out for free to budtenders, buyers, and events — as a % of total production."/>
          <Field label="additional_overhead" prefix="$" value={overheadPerUnit} onChange={setOverheadPerUnit} step={0.05} hint="per unit, optional" tip="Any extra cost per unit not captured elsewhere — rent, utilities, insurance spread per-unit."/>
        </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={6} 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 spend" 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={7} title="add to product mix" done={mix_done} active={takehome_done&&!mix_done}>
        <p className="section-desc">save this SKU with current settings. build your full lineup — strains, sizes, grades. your mix feeds forecast and ai insights.</p>
        <div style={{display:'flex',gap:8,flexWrap:'wrap'}}>
          <button className="btn primary" onClick={addProduct} disabled={!canAdd}>[+] add_to_mix</button>
          {flowerProducts.length>0&&<button className="btn outline" onClick={()=>exportFlowerCSV(products)}>export flower csv</button>}
        </div>
        {flowerProducts.length>0&&<div style={{marginTop:16}}>
          <SubHead title="flower product mix"/>
          <div className="tbl-wrap"><table className="tbl">
            <thead><tr>
              <th>sku</th><th>grade</th><th>size</th><th>pkg</th><th>input</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_profit</th><th></th>
            </tr></thead>
            <tbody>{flowerProducts.map(p=><tr key={p.id}>
              <td className="sku">{p.skuName}</td>
              <td className="dim">{p.grade}</td><td className="dim">{p.size}</td><td className="dim">{p.pkgType}</td>
              <td className="dim">{p.inputMaterial}</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 sku'}</div>
          <div className="rail-meta">grade:{gradeObj.label} · size:{sizeObj.short} · pkg:{pkgObj.short}</div>
        </div>
        <div className="rail-panel">
          <div className="rail-hero-label">take-home / unit</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">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">capital</span><span className="val neg">{fmtK(totalCOGS*units)}</span></div>
            <div className="rail-stat"><span className="lbl">take-home</span><span className="val pos">{fmtK(netPerUnit*units)}</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 {gradeObj.label}. top-quartile brands: <span style={{color:'var(--text)'}}>32–38%</span>.
      </div>

      {/* Compact product mix under rail */}
      {flowerProducts.length>0&&<div className="mix-mini">
        <div className="mix-mini-head">
          <span className="mix-eyebrow">product_mix</span>
          <span className="mix-count">{flowerProducts.length} sku{flowerProducts.length>1?'s':''}</span>
        </div>
        <div className="mix-list">
          {flowerProducts.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.grade.toLowerCase()} · {PKG_SIZES.find(s=>s.label===p.size)?.short||p.size} · {p.units.toLocaleString()}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">/u</span></span>
                <span className="mix-profit">{fmtK(p.totalProfit)}</span>
              </div>
            </div>);
          })}
        </div>
      </div>}
    </aside>
  </div>);
}

/* ============ Placeholder tabs (other 7 — reskinned shell only) ============ */
function PlaceholderTab({label}){
  return(<div className="shell" style={{gridTemplateColumns:'1fr'}}>
    <div className="col-main">
      <div className="simple-card">
        <h3>{label}</h3>
        <p className="section-desc">this tab keeps the full calculator logic from the source file in the production build. in this mock we're focused on the flower re-skin. the same patterns carry across: stepped section headers, bench bars, deduction waterfalls, the sticky summary rail, and the mono-inflected data treatment.</p>
        <p className="section-desc">see <code style={{fontFamily:'var(--mono)',color:'var(--accent)',background:'var(--surface-2)',padding:'2px 6px',borderRadius:3}}>profit-calc-clean-source.html</code> for the current behavior. it's preserved verbatim — this pass only re-skins flower.</p>
      </div>
    </div>
  </div>);
}

/* ============ App shell ============ */
const TWEAK_DEFAULTS=/*EDITMODE-BEGIN*/{
  "accent":"#31d0a0",
  "density":"comfy",
  "showRail":true,
  "bandStyle":"terminal"
}/*EDITMODE-END*/;

function App(){
  const [tab,setTab]=useState(()=>localStorage.getItem('cba-tab')||'flower');
  useEffect(()=>localStorage.setItem('cba-tab',tab),[tab]);

  const [products,setProducts]=useState([]);
  const [rawCosts,setRawCosts]=useState({exotics:1400,indoor:900,deps:400,outdoor:250,smalls:500,trim:35});
  const [distroModelShared,setDistroModelShared]=useState('percentage');
  const [distroMarginShared,setDistroMarginShared]=useState(10);
  const [distroPricingModeShared,setDistroPricingModeShared]=useState('pct');
  const [salesPctShared,setSalesPctShared]=useState(5);
  const [sampleRateShared,setSampleRateShared]=useState(3);
  const [testingAnnualShared,setTestingAnnualShared]=useState(24000);
  const distroState={distroModelShared,distroMarginShared,salesPctShared,sampleRateShared,testingAnnualShared,distroPricingModeShared,setDistroModelShared,setDistroMarginShared,setSalesPctShared,setSampleRateShared,setTestingAnnualShared,setDistroPricingModeShared};

  const [progress,setProgress]=useState({raw:true,sku:false,yield:false,pricing:false,takehome:false,addmix:false});
  const progressSteps=[
    {id:'raw',n:1,label:'raw_materials'},
    {id:'sku',n:2,label:'configure_sku'},
    {id:'yield',n:3,label:'yield_testing'},
    {id:'pricing',n:4,label:'pricing'},
    {id:'takehome',n:5,label:'take_home'},
    {id:'addmix',n:6,label:'add_to_mix'}
  ];
  /* active = first non-done */
  let activeIdx=progressSteps.findIndex(s=>!progress[s.id]);
  if(activeIdx<0)activeIdx=progressSteps.length-1;

  /* Which section is the user currently looking at (scroll-synced) */
  const [inViewStep,setInViewStep]=useState(null);
  useEffect(()=>{
    if(tab!=='flower'&&tab!=='prerolls'&&tab!=='vapes'&&tab!=='hash'){setInViewStep(null);return;}
    // Wait a frame for the tab's sections to mount
    const visibility=new Map();
    let rafId=null;
    const pick=()=>{
      rafId=null;
      let best=null;let bestRatio=0;
      for(const [id,ratio] of visibility){
        if(ratio>bestRatio){bestRatio=ratio;best=id;}
      }
      if(best)setInViewStep(best);
    };
    const io=new IntersectionObserver((entries)=>{
      for(const e of entries){
        const id=e.target.getAttribute('data-step');
        if(!id)continue;
        visibility.set(id,e.isIntersecting?e.intersectionRatio:0);
      }
      if(rafId==null)rafId=requestAnimationFrame(pick);
    },{
      // Give the fixed header some room: only count the viewport below ~140px
      rootMargin:'-140px 0px -50% 0px',
      threshold:[0,0.1,0.25,0.5,0.75,1]
    });
    // Attach after tab switch paint
    const tId=setTimeout(()=>{
      document.querySelectorAll('.sec[data-step]').forEach(el=>io.observe(el));
    },60);
    return ()=>{clearTimeout(tId);if(rafId)cancelAnimationFrame(rafId);io.disconnect();};
  },[tab]);

  /* Tweaks */
  const [tweaks,setTweaks]=useState(TWEAK_DEFAULTS);
  const [tweaksOn,setTweaksOn]=useState(false);
  useEffect(()=>{
    document.documentElement.style.setProperty('--accent',tweaks.accent);
    document.documentElement.style.setProperty('--pos',tweaks.accent);
    if(tweaks.density==='dense')document.body.style.fontSize='12px';
    else document.body.style.fontSize='13px';
  },[tweaks]);
  useEffect(()=>{
    const handler=(e)=>{
      if(e.data?.type==='__activate_edit_mode')setTweaksOn(true);
      if(e.data?.type==='__deactivate_edit_mode')setTweaksOn(false);
    };
    window.addEventListener('message',handler);
    window.parent.postMessage({type:'__edit_mode_available'},'*');
    return ()=>window.removeEventListener('message',handler);
  },[]);
  const setTweak=(k,v)=>{
    setTweaks(t=>{
      const next={...t,[k]:v};
      window.parent.postMessage({type:'__edit_mode_set_keys',edits:{[k]:v}},'*');
      return next;
    });
  };

  /* Blended footer totals */
  const totalWsRev=products.reduce((s,p)=>s+p.wsList*p.units,0);
  const totalCOGSAll=products.reduce((s,p)=>s+p.totalCOGS*p.units,0);
  const totalUnits=products.reduce((s,p)=>s+p.units,0);
  const totalProfit=totalWsRev-totalCOGSAll;
  const isPctModel=distroModelShared==='percentage';
  const isWholesaleApp=distroModelShared==='wholesale';
  const isFlatApp=isWholesaleApp&&distroPricingModeShared==='flat';
  const safeDistroMarginShared=pct(distroMarginShared);
  const safeSalesPctShared=pct(salesPctShared);
  const safeSampleRateShared=pct(sampleRateShared);
  const blendedDistroFee=isPctModel?totalWsRev*(safeDistroMarginShared/100):0;
  const blendedWsDiscount=isWholesaleApp&&!isFlatApp?totalWsRev*(safeDistroMarginShared/100):0;
  const blendedEffectiveRev=totalWsRev-blendedWsDiscount;
  const blendedSales=blendedEffectiveRev*(safeSalesPctShared/100);
  const blendedSamples=blendedEffectiveRev*(safeSampleRateShared/100)*(totalWsRev>0?totalCOGSAll/totalWsRev:0.4);
  const blendedNetProfit=blendedEffectiveRev-totalCOGSAll-blendedDistroFee-blendedSales-blendedSamples;
  const blendedNetMarginPct=blendedEffectiveRev>0?(blendedNetProfit/blendedEffectiveRev)*100:0;

  const tabLabelMap={flower:'Flower',prerolls:'Pre-Rolls',vapes:'Vapes',hash:'Extracts',toll:'Toll Processing',distro:'Distribution',forecast:'Forecast',insights:'AI Insights'};

  return(<>
    {/* Top chrome */}
    <div className="chrome">
      <div className="chrome-row">
        <div className="chrome-left">
          <a className="brand-lockup" href="https://www.joincannabizacademy.com/" target="_blank" rel="noopener" aria-label="Cannabiz Academy">
            <img src="assets/logo-cannabiz-academy-white.png" alt="Cannabiz Academy"/>
          </a>
          <div className="product-divider" aria-hidden="true"></div>
          <div className="product-name">
            <span className="product-title">Profit Calculator</span>
          </div>
        </div>
        <nav className="tabs" aria-label="calculator tabs">
          {TABS.map(t=><button key={t.id} className={`tab ${tab===t.id?'active':''} ${!t.free?'locked':''}`} onClick={()=>setTab(t.id)}>{t.label}</button>)}
        </nav>
        <div className="chrome-right">
          <a className="header-powered" href="https://www.alokinai.com" target="_blank" rel="noopener noreferrer" aria-label="Powered by Alokin">
            <span className="header-powered-label">Powered by</span>
            <span className="header-powered-chip">
              <img className="header-powered-logo" src="assets/logo-alokin.png" alt="Alokin"/>
            </span>
          </a>
          <a className="launch-cta" href="https://www.joincannabizacademy.com/" target="_blank" rel="noopener noreferrer">
            <span>Launch Your Brand</span>
            <span className="launch-cta-arrow">→</span>
          </a>
        </div>
      </div>
      {(tab==='flower'||tab==='prerolls'||tab==='vapes'||tab==='hash')&&<div className="progress">
        {progressSteps.map((s,i)=>{
          const done=progress[s.id];
          const active=i===activeIdx;
          const inview=inViewStep===s.id;
          const mark=done?'[✓]':active?'[→]':'[ ]';
          return(<React.Fragment key={s.id}>
            <span className={`step ${done?'done':''} ${active?'active':''} ${inview?'inview':''}`} onClick={()=>{
              const el=document.querySelector(`.sec[data-step="${s.id}"]`);
              if(el)window.scrollTo({top:el.getBoundingClientRect().top+window.scrollY-120,behavior:'smooth'});
            }} style={{cursor:'pointer'}}>
              <span className="mark">{mark}</span>
              <span>{String(s.n).padStart(2,'0')} {s.label}</span>
            </span>
            {i<progressSteps.length-1&&<span className="step-sep">·</span>}
          </React.Fragment>);
        })}
      </div>}
    </div>

    {/* Body */}
    {tab==='flower'&&<FlowerTab products={products} setProducts={setProducts} rawCosts={rawCosts} setRawCosts={setRawCosts} distroState={distroState} setProgress={setProgress}/>}
    {tab==='prerolls'&&<PrerollsTab products={products} setProducts={setProducts} rawCosts={rawCosts} setRawCosts={setRawCosts} distroState={distroState} setProgress={setProgress}/>}
    {tab==='vapes'&&<VapesTab products={products} setProducts={setProducts} distroState={distroState} setProgress={setProgress}/>}
    {tab==='hash'&&<ExtractsTab products={products} setProducts={setProducts} distroState={distroState} setProgress={setProgress}/>}
    {tab==='toll'&&<TollTab products={products} setProducts={setProducts} setProgress={setProgress}/>}
    {tab==='distro'&&<DistroTab products={products} distroState={distroState} setProgress={setProgress}/>}
    {tab==='forecast'&&<ForecastTab products={products} distroState={distroState}/>}
    {tab==='insights'&&<InsightsTab products={products} distroState={distroState}/>}
    {tab!=='flower'&&tab!=='prerolls'&&tab!=='vapes'&&tab!=='hash'&&tab!=='toll'&&tab!=='distro'&&tab!=='forecast'&&tab!=='insights'&&<PlaceholderTab label={tabLabelMap[tab]||tab}/>}

    {/* Footer */}
    {products.length>0&&<div className="foot">
      <div className="f-item"><span className="f-lbl">total_units</span><span className="f-val">{totalUnits.toLocaleString()}</span></div>
      <div className="f-item"><span className="f-lbl">revenue</span><span className="f-val">{fmtK(totalWsRev)}</span></div>
      <div className="f-item"><span className="f-lbl">capital</span><span className="f-val warn">{fmtK(totalCOGSAll)}</span></div>
      <div className="f-item"><span className="f-lbl">gross_profit</span><span className={`f-val ${totalProfit>0?'pos':'neg'}`}>{fmtK(totalProfit)}</span></div>
      <div className="f-sep"></div>
      <div className="f-item"><span className="f-lbl" style={{color:'var(--accent)'}}>net_profit</span><span className={`f-val ${blendedNetProfit>0?'accent':'neg'}`}>{fmtK(blendedNetProfit)}</span></div>
      <div className="f-item"><span className="f-lbl" style={{color:'var(--accent)'}}>net_margin</span><span className={`f-val ${blendedNetMarginPct>20?'accent':blendedNetMarginPct>10?'warn':'neg'}`}>{blendedNetMarginPct.toFixed(1)}%</span></div>
      <div className="f-spacer"></div>
      <button className="btn outline sm" onClick={()=>window.print()}>print / pdf</button>
    </div>}

    {/* Tweaks */}
    <div className={`tweaks ${tweaksOn?'on':''}`}>
      <div className="tweaks-head">
        <span>Tweaks</span>
        <button className="btn ghost sm" onClick={()=>setTweaksOn(false)}>×</button>
      </div>
      <div className="tweaks-body">
        <div className="tw-row">
          <label>accent color</label>
          <div className="tw-swatches">
            {['#31d0a0','#12E8A2','#4da6ff','#e3b341','#f2747a','#c084fc'].map(c=><span key={c} className={`tw-sw ${tweaks.accent===c?'sel':''}`} style={{background:c}} onClick={()=>setTweak('accent',c)}/>)}
          </div>
        </div>
        <div className="tw-row">
          <label>density</label>
          <Seg size="sm" options={[{value:'comfy',label:'comfy'},{value:'dense',label:'dense'}]} value={tweaks.density} onChange={v=>setTweak('density',v)}/>
        </div>
        <div className="tw-row">
          <label>show sticky rail</label>
          <Seg size="sm" options={[{value:true,label:'on'},{value:false,label:'off'}]} value={tweaks.showRail} onChange={v=>{
            setTweak('showRail',v);
            document.querySelectorAll('.rail').forEach(el=>el.style.display=v?'':'none');
            document.querySelectorAll('.shell').forEach(el=>el.style.gridTemplateColumns=v?'':'1fr');
          }}/>
        </div>
      </div>
    </div>
  </>);
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
