/* ─────────────────────────────────────────────────────────────────────────
   Menu Factory — Color helpers
   Real palette extraction from an uploaded logo via Canvas sampling,
   then builds an Engine-compatible theme object.
   ───────────────────────────────────────────────────────────────────────── */

function hexToRgb(hex) {
  const h = hex.replace('#', '');
  return [parseInt(h.slice(0,2),16), parseInt(h.slice(2,4),16), parseInt(h.slice(4,6),16)];
}
function rgbToHex(r,g,b) {
  return '#' + [r,g,b].map(v => Math.max(0,Math.min(255,v|0)).toString(16).padStart(2,'0')).join('');
}
function rgbToHsl(r,g,b) {
  r/=255; g/=255; b/=255;
  const max=Math.max(r,g,b), min=Math.min(r,g,b);
  let h, s, l=(max+min)/2;
  if (max===min) { h=s=0; }
  else {
    const d=max-min;
    s = l>0.5 ? d/(2-max-min) : d/(max+min);
    switch(max){
      case r: h=(g-b)/d + (g<b?6:0); break;
      case g: h=(b-r)/d + 2; break;
      case b: h=(r-g)/d + 4; break;
    }
    h/=6;
  }
  return [h,s,l];
}
function hslToHex(h,s,l) {
  let r,g,b;
  if (s===0) { r=g=b=l; }
  else {
    const hue2rgb=(p,q,t)=>{
      if(t<0) t+=1; if(t>1) t-=1;
      if(t<1/6) return p+(q-p)*6*t;
      if(t<1/2) return q;
      if(t<2/3) return p+(q-p)*(2/3-t)*6;
      return p;
    };
    const q = l<0.5 ? l*(1+s) : l+s-l*s;
    const p = 2*l-q;
    r=hue2rgb(p,q,h+1/3); g=hue2rgb(p,q,h); b=hue2rgb(p,q,h-1/3);
  }
  return rgbToHex(r*255,g*255,b*255);
}
function shift(hex, dL, dS=0) {
  const [r,g,b] = hexToRgb(hex);
  let [h,s,l] = rgbToHsl(r,g,b);
  l = Math.max(0, Math.min(1, l + dL));
  s = Math.max(0, Math.min(1, s + dS));
  return hslToHex(h,s,l);
}

async function extractPalette(imgEl) {
  const W = 80, H = 80;
  const cv = document.createElement('canvas');
  cv.width = W; cv.height = H;
  const cx = cv.getContext('2d', { willReadFrequently: true });
  cx.drawImage(imgEl, 0, 0, W, H);
  const data = cx.getImageData(0,0,W,H).data;

  const buckets = new Map();
  for (let i=0; i<data.length; i+=4) {
    const r=data[i], g=data[i+1], b=data[i+2], a=data[i+3];
    if (a < 128) continue;
    const max=Math.max(r,g,b), min=Math.min(r,g,b);
    if (max > 240 && min > 230) continue;
    if (max < 25) continue;
    if (max - min < 12 && max > 60 && max < 200) continue;
    const key = `${(r>>4)},${(g>>4)},${(b>>4)}`;
    const cur = buckets.get(key) || { r:0, g:0, b:0, n:0 };
    cur.r += r; cur.g += g; cur.b += b; cur.n++;
    buckets.set(key, cur);
  }

  const ranked = [...buckets.values()]
    .map(c => ({ r: c.r/c.n, g: c.g/c.n, b: c.b/c.n, n: c.n }))
    .sort((a,b) => b.n - a.n)
    .slice(0, 8);

  if (ranked.length === 0) return defaultPalette();

  const scored = ranked.map(c => {
    const [h,s,l] = rgbToHsl(c.r, c.g, c.b);
    const score = s * (0.5 + Math.min(c.n / 400, 1)) * (l > 0.2 && l < 0.85 ? 1 : 0.4);
    return { ...c, h, s, l, score };
  }).sort((a,b) => b.score - a.score);

  const primary = scored[0];
  return paletteFromPrimary(rgbToHex(primary.r, primary.g, primary.b));
}

function paletteFromPrimary(primaryHex) {
  const [r,g,b] = hexToRgb(primaryHex);
  const [h, s, l] = rgbToHsl(r,g,b);

  const gold       = hslToHex(h, Math.max(0.45, s), Math.max(0.42, Math.min(0.6, l)));
  const goldLight  = shift(gold, +0.12);
  const goldPale   = shift(gold, +0.3, -0.1);
  const goldDeep   = shift(gold, -0.18, +0.05);

  const bg = hslToHex(h, Math.min(0.35, s*0.4), 0.04);
  const s1 = hslToHex(h, Math.min(0.35, s*0.4), 0.07);
  const s2 = hslToHex(h, Math.min(0.35, s*0.4), 0.11);
  const s3 = hslToHex(h, Math.min(0.35, s*0.4), 0.15);
  const s4 = hslToHex(h, Math.min(0.35, s*0.4), 0.22);

  const tx = shift(goldPale, +0.1, -0.2);
  const mu = hslToHex(h, 0.18, 0.55);
  const di = hslToHex(h, 0.12, 0.42);
  const fa = hslToHex(h, 0.10, 0.28);

  return {
    bg, s1, s2, s3, s4, gold, goldLight, goldPale, goldDeep,
    tx, mu, di, fa,
    line: `rgba(${hexToRgb(goldPale).join(',')}, 0.08)`,
    lineStrong: `rgba(${hexToRgb(goldPale).join(',')}, 0.18)`,
    landingGradient: `radial-gradient(ellipse at top, ${s2} 0%, ${bg} 60%)`,
    primaryHex,
  };
}

function defaultPalette() { return paletteFromPrimary('#c8923a'); }

window.FactoryPalette = { extractPalette, paletteFromPrimary, defaultPalette, hexToRgb };
