/* ============================================================
   Lima Android — theme tokens, icons, shared Material components
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;
const D = window.LIMA_DATA;

/* ---------- helpers (ported from web) ---------- */
const ZMW = (n, dp=0) => 'K' + Number(n).toLocaleString('en-ZM', {minimumFractionDigits:dp, maximumFractionDigits:dp});
const cap = s => s ? s.charAt(0).toUpperCase()+s.slice(1) : s;
const cropByName = name => D.crops.find(c => c.name === name);
const priceByName = name => D.market_prices.find(p => p.crop === name);
const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
const CATS = [
  {id:'cereal', label:'Cereals'},
  {id:'legume', label:'Legumes'},
  {id:'vegetable', label:'Vegetables'},
  {id:'root', label:'Root Crops'},
  {id:'cash', label:'Cash Crops'},
];
function seedRand(seed){
  let h = 1779033703 ^ seed.length;
  for (let i=0;i<seed.length;i++){ h = Math.imul(h ^ seed.charCodeAt(i), 3432918353); h = (h<<13)|(h>>>19); }
  return () => { h = Math.imul(h ^ (h>>>16), 2246822507); h = Math.imul(h ^ (h>>>13), 3266489909); h ^= h>>>16; return (h>>>0)/4294967296; };
}
const WATER_SOURCES = [
  {id:'Rainfed', sub:'Natural rainfall', icon:'rain'},
  {id:'Irrigated', sub:'Conventional', icon:'droplets'},
  {id:'Mixed', sub:'Rain + supplement', icon:'cloud'},
  {id:'Borehole', sub:'Groundwater', icon:'drop'},
  {id:'TONA System', sub:'Solar irrigation', icon:'bolt', tona:true},
];

/* ---------- icons (stroke, currentColor) — ported + Android extras ---------- */
function Icon({name, size=22, sw=1.7, style, fill='none'}){
  const p = {
    sprout:<><path d="M12 20v-8"/><path d="M12 12C12 8 9 6 4 6c0 5 3 6 8 6Z"/><path d="M12 12c0-3 3-5 8-5 0 4-3 6-8 5Z"/></>,
    leaf:<><path d="M11 20A7 7 0 0 1 4 13c0-5 4-9 16-9 0 12-4 16-9 16Z"/><path d="M4 21c2-6 7-9 12-10"/></>,
    chart:<><path d="M4 19V5"/><path d="M4 19h16"/><path d="M8 16l3-4 3 2 4-6"/></>,
    cloud:<><path d="M7 18a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1.5A3.5 3.5 0 0 1 17 18Z"/></>,
    coins:<><ellipse cx="9" cy="7" rx="5" ry="2.6"/><path d="M4 7v5c0 1.4 2.2 2.6 5 2.6s5-1.2 5-2.6V7"/><path d="M14 11.2c2.4.2 4.5 1.2 4.5 2.4 0 1.4-2.2 2.6-5 2.6-1 0-2-.2-2.8-.5"/><path d="M11 16.5c0 1.4 2.2 2.6 5 2.6s5-1.2 5-2.6v-5"/></>,
    bug:<><path d="M8 10V7a4 4 0 0 1 8 0v3"/><rect x="6" y="10" width="12" height="9" rx="6"/><path d="M3 13h3M18 13h3M4 18l2.5-1.5M20 18l-2.5-1.5M4 9l2.5 1.5M20 9l-2.5 1.5M12 10v9"/></>,
    signal:<><path d="M4 18h.01M9 18v-3M14 18V11M19 18V5"/></>,
    drop:<><path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11Z"/></>,
    sun:<><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M19 5l-1.5 1.5M6.5 17.5 5 19"/></>,
    pin:<><path d="M12 21s7-6 7-11a7 7 0 0 0-14 0c0 5 7 11 7 11Z"/><circle cx="12" cy="10" r="2.5"/></>,
    phone:<><path d="M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L20 13l1 4v2a2 2 0 0 1-2 2A16 16 0 0 1 3 5a2 2 0 0 1 2-1Z"/></>,
    chev:<><path d="M6 9l6 6 6-6"/></>,
    close:<><path d="M6 6l12 12M18 6 6 18"/></>,
    arrowUp:<><path d="M12 19V5M6 11l6-6 6 6"/></>,
    arrowDown:<><path d="M12 5v14M6 13l6 6 6-6"/></>,
    arrowFlat:<><path d="M5 12h14M14 7l5 5-5 5"/></>,
    back:<><path d="M19 12H5M11 18l-6-6 6-6"/></>,
    check:<><path d="M20 6 9 17l-5-5"/></>,
    shield:<><path d="M12 3l7 3v5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6Z"/><path d="M9 12l2 2 4-4"/></>,
    spark:<><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8Z"/></>,
    calendar:<><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></>,
    droplets:<><path d="M7 16a3 3 0 0 0 6 0c0-2-3-5-3-5s-3 3-3 5Z"/><path d="M15 8a2.5 2.5 0 0 0 5 0c0-1.7-2.5-4-2.5-4S15 6.3 15 8Z"/></>,
    rain:<><path d="M7 14a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1.5A3.5 3.5 0 0 1 17 14Z"/><path d="M8 18l-1 2M12 18l-1 2M16 18l-1 2"/></>,
    bolt:<><path d="M13 2 4 14h6l-1 8 9-12h-6Z"/></>,
    map:<><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2Z"/><path d="M9 4v14M15 6v14"/></>,
    db:<><ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></>,
    seedling:<><path d="M12 22V9"/><path d="M12 13c5 0 8-3 8-8-5 0-8 3-8 8Z"/><path d="M12 16c-4 0-6-2-6-6 4 0 6 2 6 6Z"/></>,
    bell:<><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></>,
    search:<><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></>,
    plus:<><path d="M12 5v14M5 12h14"/></>,
    home:<><path d="M3 11l9-8 9 8"/><path d="M5 9.5V21h14V9.5"/></>,
    dot:<><circle cx="12" cy="12" r="9"/></>,
    wind:<><path d="M3 8h11a3 3 0 1 0-3-3M3 16h15a3 3 0 1 1-3 3M3 12h8"/></>,
    star:<><path d="M12 3l2.6 5.7L21 9.3l-4.5 4.4 1.1 6.3L12 17l-5.6 3 1.1-6.3L3 9.3l6.4-.6Z"/></>,
  }[name];
  return <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke="currentColor"
    strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={style} aria-hidden="true">{p}</svg>;
}

/* ---------- Lima logo lockup ---------- */
/* Ku-Lima is operated by Akili Ventures Limited — Ku-Lima emblem (seedling mark is the fallback) */
const USSD_CODE='*384*[code]#'; // pending Africa's Talking assignment
const SMS_SENDER='Ku-Lima';
function LogoMark({size=34, mono=false}){
  const [ok,setOk]=useState(true);
  return ok
    ? <img src="assets/ku-lima-logo.png" alt="" onError={()=>setOk(false)}
        style={{width:size,height:size,objectFit:'contain',display:'block',flex:'0 0 auto'}}/>
    : <span style={{width:size,height:size,borderRadius:9,display:'grid',placeItems:'center',
        background:'linear-gradient(150deg,#3f9a64,#2E7D4F)',color:'#fff',flex:'0 0 auto'}}>
        <Icon name="seedling" size={size*0.62} sw={1.9}/></span>;
}
function Wordmark({size=20, mono=false, sub=true}){
  return <span style={{display:'flex',flexDirection:'column',lineHeight:1}}>
    <span className="serif" style={{fontWeight:800,fontSize:size,letterSpacing:'-.01em',color:mono?'#fff':'var(--ink)'}}>Ku-Lima</span>
    {sub && <span className="mono" style={{fontSize:size*0.32,letterSpacing:'.16em',textTransform:'uppercase',color:mono?'rgba(255,255,255,.6)':'var(--ink-faint)',marginTop:3}}>Akili&nbsp;Ventures</span>}
  </span>;
}
function LiveDot({label='Live', light=false, soon=false}){
  if(soon) return <span style={{display:'inline-flex',alignItems:'center',gap:5,padding:'3px 8px',borderRadius:999,
    background:light?'rgba(224,181,78,.22)':'rgba(201,151,43,.16)',color:light?'var(--gold-l)':'var(--gold-d)',fontSize:10,fontWeight:800,letterSpacing:'.1em',textTransform:'uppercase',whiteSpace:'nowrap'}}>
    <span style={{width:6,height:6,borderRadius:99,background:light?'var(--gold-l)':'var(--gold)'}}></span>{label==='Live'?'Soon':label}
  </span>;
  return <span style={{display:'inline-flex',alignItems:'center',gap:5,padding:'3px 8px',borderRadius:999,
    background:light?'rgba(255,255,255,.16)':'rgba(46,125,79,.12)',color:light?'#fff':'var(--green-d)',fontSize:10,fontWeight:800,letterSpacing:'.1em',textTransform:'uppercase',whiteSpace:'nowrap'}}>
    <span style={{width:6,height:6,borderRadius:99,background:light?'#8fdcab':'var(--green)',boxShadow:'0 0 0 3px '+(light?'rgba(143,220,171,.25)':'rgba(46,125,79,.18)')}}></span>{label}
  </span>;
}

/* ---------- badges & pills ---------- */
function SuitBadge({level, size='md'}){
  const map = {high:{c:'var(--high)',bg:'rgba(46,125,79,.13)',t:'High suitability'},
               medium:{c:'var(--med)',bg:'rgba(201,151,43,.16)',t:'Medium suitability'},
               low:{c:'var(--low)',bg:'rgba(178,58,46,.13)',t:'Low suitability'}};
  const m = map[level]||map.medium;
  const lg = size==='lg';
  return <span style={{display:'inline-flex',alignItems:'center',gap:7,background:m.bg,color:m.c,
    padding:lg?'7px 14px':'5px 11px',borderRadius:999,fontWeight:700,fontSize:lg?14:12.5,whiteSpace:'nowrap'}}>
    <span style={{width:lg?8:7,height:lg?8:7,borderRadius:99,background:m.c}}></span>
    {lg ? m.t : cap(level)}
  </span>;
}
function Trend({dir, pct, size=13.5}){
  const map = {up:{c:'var(--high)',i:'arrowUp'},down:{c:'var(--clay)',i:'arrowDown'},flat:{c:'var(--ink-faint)',i:'arrowFlat'}};
  const m = map[dir]||map.flat;
  return <span style={{display:'inline-flex',alignItems:'center',gap:4,color:m.c,fontWeight:700,fontSize:size}}>
    <Icon name={m.i} size={size+2} sw={2.3}/>{dir==='flat'?'0%':(pct>0?`+${pct}%`:`${pct}%`)}
  </span>;
}
function Pill({children, tone='neutral', style}){
  const tones={
    neutral:{bg:'var(--cream-2)',c:'var(--ink-soft)'},
    green:{bg:'rgba(46,125,79,.1)',c:'var(--green-d)'},
    gold:{bg:'rgba(201,151,43,.16)',c:'var(--gold-d)'},
    navy:{bg:'rgba(27,58,107,.1)',c:'var(--navy)'},
    clay:{bg:'rgba(178,58,46,.1)',c:'var(--clay)'},
  };
  const t=tones[tone]||tones.neutral;
  return <span style={{display:'inline-flex',alignItems:'center',gap:6,background:t.bg,color:t.c,whiteSpace:'nowrap',
    padding:'5px 11px',borderRadius:999,fontSize:12.5,fontWeight:700,...style}}>{children}</span>;
}

/* ---------- striped image placeholder ---------- */
function Placeholder({label, h=150, style}){
  return <div style={{
    height:h,borderRadius:14,border:'1px dashed var(--line-d)',
    background:'repeating-linear-gradient(135deg,var(--cream-2),var(--cream-2) 10px,var(--cream) 10px,var(--cream) 20px)',
    display:'grid',placeItems:'center',...style}}>
    <span className="mono" style={{fontSize:11,color:'var(--ink-faint)',letterSpacing:'.04em',textTransform:'uppercase'}}>{label}</span>
  </div>;
}

/* ---------- Material surface card ---------- */
function MCard({children, style, pad=18, onClick, elevated=true}){
  return <div onClick={onClick} style={{
    background:'var(--paper)',borderRadius:20,padding:pad,
    border:'1px solid var(--line)',
    boxShadow:elevated?'0 1px 2px rgba(35,33,28,.05), 0 4px 14px rgba(35,33,28,.05)':'none',
    ...style}}>{children}</div>;
}

/* ---------- Material filled button (with ripple-ish press) ---------- */
function MButton({children, onClick, tone='green', size='md', full, disabled, style}){
  const [press,setPress]=useState(false);
  const tones={
    green:{bg:'var(--green)',c:'#fff'},
    gold:{bg:'var(--gold)',c:'#fff'},
    navy:{bg:'var(--navy)',c:'#fff'},
    tonal:{bg:'rgba(46,125,79,.12)',c:'var(--green-d)'},
    outline:{bg:'transparent',c:'var(--ink)',bd:'1.5px solid var(--line-d)'},
  };
  const t=tones[tone]||tones.green;
  const pad= size==='lg'?'15px 24px':size==='sm'?'9px 16px':'13px 20px';
  const fs= size==='lg'?16:size==='sm'?13.5:15;
  return <button type="button" disabled={disabled}
    onClick={onClick}
    onPointerDown={()=>setPress(true)} onPointerUp={()=>setPress(false)} onPointerLeave={()=>setPress(false)}
    style={{display:'inline-flex',alignItems:'center',justifyContent:'center',gap:9,padding:pad,fontSize:fs,fontWeight:700,
      border:t.bd||'none',borderRadius:999,background:t.bg,color:t.c,width:full?'100%':'auto',whiteSpace:'nowrap',
      opacity:disabled?.45:1,transition:'transform .12s, box-shadow .16s, filter .16s',cursor:disabled?'not-allowed':'pointer',
      transform:press&&!disabled?'scale(.97)':'none',
      boxShadow:(tone==='green'||tone==='gold'||tone==='navy')&&!disabled?'0 4px 14px rgba(35,33,28,.14)':'none',
      filter:press?'brightness(.94)':'none',...style}}>{children}</button>;
}

/* ---------- assist / filter chip ---------- */
function Chip({children, active, onClick, icon, style}){
  return <button type="button" onClick={onClick} style={{
    display:'inline-flex',alignItems:'center',gap:7,padding:'9px 14px',borderRadius:11,whiteSpace:'nowrap',
    border:'1.5px solid '+(active?'var(--green)':'var(--line-d)'),
    background:active?'rgba(46,125,79,.1)':'var(--paper)',
    color:active?'var(--green-d)':'var(--ink-soft)',fontWeight:700,fontSize:13.5,
    transition:'.14s',cursor:'pointer',...style}}>
    {icon && <Icon name={icon} size={16}/>}{children}
  </button>;
}

/* ---------- crop name in the province's language (null when not reviewed) ---------- */
function provLang(prov){ const p=D.provinces.find(x=>x.name===prov); return p?p.language:null; }
function localName(c, prov){ const l=provLang(prov); if(!l) return null; const n=l==='Bemba'?c.local_bemba:c.local_nyanja; return n && n!==c.name ? {name:n, lang:l} : null; }

/* ---------- sparkline (ported) ---------- */
function Sparkline({pts, color, w=92, h=30}){
  const min=Math.min(...pts), max=Math.max(...pts), rng=(max-min)||1;
  const step=w/(pts.length-1);
  const coords=pts.map((p,i)=>[i*step, h-3-((p-min)/rng)*(h-6)]);
  const d=coords.map((c,i)=>(i?'L':'M')+c[0].toFixed(1)+' '+c[1].toFixed(1)).join(' ');
  const area=d+` L ${w} ${h} L 0 ${h} Z`;
  const id='ag'+Math.abs((pts[0]*1000|0))+w+Math.round(min*7);
  return <svg width={w} height={h} style={{display:'block'}}>
    <defs><linearGradient id={id} x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor={color} stopOpacity="0.2"/><stop offset="1" stopColor={color} stopOpacity="0"/></linearGradient></defs>
    <path d={area} fill={`url(#${id})`}/>
    <path d={d} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    <circle cx={coords[coords.length-1][0]} cy={coords[coords.length-1][1]} r="2.6" fill={color}/>
  </svg>;
}

/* ============================================================
   Bottom sheet (Material 3) — slides up from bottom of frame
   ============================================================ */
function BottomSheet({open, onClose, title, children, maxH='72%'}){
  const [mounted,setMounted]=useState(open);
  const [shown,setShown]=useState(false);
  useEffect(()=>{
    if(open){ setMounted(true); requestAnimationFrame(()=>requestAnimationFrame(()=>setShown(true))); }
    else { setShown(false); const t=setTimeout(()=>setMounted(false),240); return ()=>clearTimeout(t); }
  },[open]);
  if(!mounted) return null;
  return (
    <div onClick={onClose} style={{position:'absolute',inset:0,zIndex:120,display:'flex',flexDirection:'column',justifyContent:'flex-end'}}>
      <div style={{position:'absolute',inset:0,background:'rgba(20,28,24,.42)',opacity:shown?1:0,transition:'opacity .24s'}}></div>
      <div onClick={e=>e.stopPropagation()} style={{position:'relative',background:'var(--paper)',borderRadius:'28px 28px 0 0',
        maxHeight:maxH,display:'flex',flexDirection:'column',boxShadow:'0 -10px 40px rgba(20,28,24,.22)',
        transform:shown?'translateY(0)':'translateY(102%)',transition:'transform .26s cubic-bezier(.2,.8,.2,1)'}}>
        <div style={{display:'grid',placeItems:'center',padding:'10px 0 4px',flex:'0 0 auto'}}>
          <div style={{width:34,height:4,borderRadius:99,background:'var(--line-d)'}}></div>
        </div>
        {title && <div style={{display:'flex',alignItems:'center',gap:10,padding:'8px 20px 12px',flex:'0 0 auto'}}>
          <h3 className="serif" style={{margin:0,fontSize:19,fontWeight:700,whiteSpace:'nowrap'}}>{title}</h3>
          <button onClick={onClose} style={{marginLeft:'auto',width:34,height:34,borderRadius:99,border:'none',background:'var(--cream-2)',color:'var(--ink-soft)',display:'grid',placeItems:'center'}}><Icon name="close" size={18}/></button>
        </div>}
        <div style={{overflowY:'auto',padding:'0 16px 22px',WebkitOverflowScrolling:'touch'}}>{children}</div>
      </div>
    </div>
  );
}

/* ---------- crop & province picker sheets ---------- */
function CropPickerSheet({open, onClose, value, onChange}){
  return <BottomSheet open={open} onClose={onClose} title="Choose a crop" maxH="78%">
    {CATS.map(cat=>{
      const items=D.crops.filter(c=>c.category===cat.id); if(!items.length) return null;
      return <div key={cat.id} style={{marginBottom:6}}>
        <div style={{fontSize:11,fontWeight:800,textTransform:'uppercase',letterSpacing:'.1em',color:'var(--ink-faint)',padding:'12px 8px 6px'}}>{cat.label}</div>
        {items.map(c=>{
          const on=value===c.name;
          return <button key={c.id} onClick={()=>{onChange(c.name);onClose();}} style={{width:'100%',display:'flex',alignItems:'center',gap:13,padding:'13px 12px',borderRadius:14,border:'none',
            background:on?'rgba(46,125,79,.1)':'transparent',textAlign:'left',marginBottom:2}}>
            <span style={{fontSize:24}}>{c.emoji}</span>
            <span style={{display:'flex',flexDirection:'column'}}>
              <span style={{fontWeight:700,fontSize:15.5,color:'var(--ink)'}}>{c.name}</span>
              <span className="mono" style={{fontSize:11.5,color:'var(--ink-faint)',marginTop:2}}>{cap(c.category)}</span>
            </span>
            {on && <span style={{marginLeft:'auto',color:'var(--green)'}}><Icon name="check" size={20} sw={2.4}/></span>}
          </button>;
        })}
      </div>;
    })}
  </BottomSheet>;
}
function ProvincePickerSheet({open, onClose, value, onChange, title='Select province'}){
  return <BottomSheet open={open} onClose={onClose} title={title} maxH="72%">
    {D.provinces.map(p=>{
      const on=value===p.name;
      return <button key={p.id} onClick={()=>{onChange(p.name);onClose();}} style={{width:'100%',display:'flex',alignItems:'center',gap:12,padding:'14px 12px',borderRadius:14,border:'none',
        background:on?'rgba(46,125,79,.1)':'transparent',textAlign:'left',marginBottom:2}}>
        <span style={{width:38,height:38,borderRadius:11,background:on?'var(--green)':'var(--cream-2)',color:on?'#fff':'var(--ink-soft)',display:'grid',placeItems:'center',flex:'0 0 auto'}}><Icon name="pin" size={19}/></span>
        <span style={{display:'flex',flexDirection:'column'}}>
          <span style={{fontWeight:700,fontSize:15.5,color:'var(--ink)'}}>{p.name}</span>
          <span className="mono" style={{fontSize:11.5,color:'var(--ink-faint)',marginTop:2}}>Zone {p.agro_zone} · {p.avg_rainfall_mm}mm/yr</span>
        </span>
        {on && <span style={{marginLeft:'auto',color:'var(--green)'}}><Icon name="check" size={20} sw={2.4}/></span>}
      </button>;
    })}
  </BottomSheet>;
}

Object.assign(window, {
  ZMW, cap, cropByName, priceByName, MONTHS, CATS, seedRand, WATER_SOURCES,
  Icon, LogoMark, Wordmark, LiveDot, USSD_CODE, SMS_SENDER, SuitBadge, Trend, Pill, Placeholder,
  MCard, MButton, Chip, Sparkline, provLang, localName, BottomSheet, CropPickerSheet, ProvincePickerSheet,
});
