/* ============================================================
   RESTO SUITE — BUSINESS IDEA MODULE
   Writes: plan.idea (its own namespace only)
   Adapter: askInterview(history) — v1 heuristic extraction,
            API-ready for a real LLM later (same interface).
   ============================================================ */
const { useState: useStateI, useRef: useRefI, useEffect: useEffectI } = React;

/* ---------- Thai-market presets & benchmarks ---------- */
const CATEGORIES = ["QSR", "Café", "Casual dining", "Fine dining", "Bar", "Cloud kitchen", "Bakery", "Buffet"];
const CUISINE_PRESETS = ["Thai", "Isaan", "Japanese", "Ramen", "Sushi", "Korean", "Chinese", "Italian", "Pizza", "Western", "Seafood", "Fusion", "Vegan"];
const CUSTOMERS = ["Students", "Office workers", "Families", "Tourists", "Expats", "Hi-so"];
const LOCATION_TYPES = ["Shopping mall", "Street / shophouse", "Community mall", "CBD office", "Tourist zone", "Campus"];
const SERVICE_STYLES = ["Counter service", "Table service", "Self service", "Delivery only"];
const EXPERIENCE = ["First-timer", "Worked in F&B", "Opened before"];
const RISK = ["Cautious", "Balanced", "Aggressive"];
const INVOLVEMENT = ["Owner-operator", "Investor"];

const PRICE_BANDS = {
  "Budget": { range: "฿60–150 / head", rangeTh: "฿60–150 ต่อคน", mid: 100 },
  "Mid": { range: "฿150–400 / head", rangeTh: "฿150–400 ต่อคน", mid: 260 },
  "Premium": { range: "฿400–900 / head", rangeTh: "฿400–900 ต่อคน", mid: 600 },
  "Luxury": { range: "฿900+ / head", rangeTh: "฿900+ ต่อคน", mid: 1400 },
};
function priceRange(band, lang) { return lang === "th" ? PRICE_BANDS[band].rangeTh : PRICE_BANDS[band].range; }

/* rough fit-out benchmark per seat, by category — labelled as benchmark, never fact */
const FITOUT_PER_SEAT = {
  "QSR": 30000, "Café": 40000, "Casual dining": 45000, "Fine dining": 120000,
  "Bar": 55000, "Cloud kitchen": null, "Bakery": 40000, "Buffet": 35000,
};
const CLOUD_KITCHEN_FITOUT = 900000;

/* rough monthly-sales benchmark from format + price band — always labelled benchmark */
function salesBenchmark(idea, t) {
  const band = PRICE_BANDS[idea.priceBand];
  const seats = idea.format.seats || 0;
  if (!band || seats <= 0) return null;
  const salesEst = seats * 1.8 * band.mid * 26; // seats × 1.8 turns × band mid × 26 days
  const basis = t ? t("idea.benchSeatsTurns", { seats, mid: fmtBaht(band.mid) }) : `${seats} seats × 1.8 turns × ${fmtBaht(band.mid)} × 26 days`;
  return { salesEst, healthyRent: Math.round(salesEst * 0.10), basis };
}

function fitoutEstimate(idea, t, lang) {
  if (!idea.category) return null;
  if (idea.category === "Cloud kitchen") return { value: CLOUD_KITCHEN_FITOUT, basis: t ? t("idea.benchCloudKitchen") : "typical Bangkok cloud-kitchen setup" };
  const per = FITOUT_PER_SEAT[idea.category];
  const seats = idea.format.seats || 30;
  if (!per) return null;
  const catLabel = t ? optLabel(lang, idea.category) : idea.category.toLowerCase();
  const basis = t ? t("idea.benchPerSeat", { per: fmtBaht(per), seats, cat: catLabel }) : `${fmtBaht(per)}/seat × ${seats} seats (Thai ${idea.category.toLowerCase()} benchmark)`;
  return { value: per * seats, basis };
}

/* ============================================================
   ADAPTER — askInterview (v1: heuristics · FUTURE: real LLM call)
   Interface stays stable: ({ questionId, answer, idea }) => { patch, heard }
   ============================================================ */
function extractNumber(s, unitWords) {
  const t = s.toLowerCase().replace(/,/g, "");
  const re = new RegExp(`(\\d+(?:\\.\\d+)?)\\s*(?:${unitWords.join("|")})`, "i");
  const m = t.match(re);
  return m ? parseFloat(m[1]) : null;
}
function parseMoneyTh(s) {
  const t = s.toLowerCase().replace(/,/g, "");
  let m = t.match(/(\d+(?:\.\d+)?)\s*(?:m\b|million|ล้าน)/i);
  if (m) return parseFloat(m[1]) * 1000000;
  m = t.match(/(\d+(?:\.\d+)?)\s*(?:k\b|พัน|thousand)/i);
  if (m) return parseFloat(m[1]) * 1000;
  m = t.match(/฿?\s*(\d{4,})/);
  if (m) return parseFloat(m[1]);
  return null;
}
const hasAny = (s, words) => words.some((w) => s.toLowerCase().includes(w));

const INTERVIEW = [
  {
    id: "concept",
    extract: (a, idea) => {
      const patch = {};
      const heard = [];
      const catMap = [
        ["Café", ["cafe", "café", "coffee", "คาเฟ่", "กาแฟ"]],
        ["Bar", ["bar", "cocktail", "บาร์", "เหล้า", "craft beer"]],
        ["Cloud kitchen", ["cloud", "delivery only", "ghost kitchen"]],
        ["Bakery", ["bakery", "bread", "croissant", "เบเกอรี่", "ขนมปัง"]],
        ["Buffet", ["buffet", "บุฟเฟ่ต์", "หมูกระทะ", "shabu", "ชาบู"]],
        ["Fine dining", ["fine dining", "tasting menu", "chef's table", "omakase"]],
        ["QSR", ["fast", "quick", "street", "grab and go", "kiosk", "ข้าวแกง", "ตามสั่ง"]],
      ];
      for (const [cat, kws] of catMap) if (hasAny(a, kws)) { patch.category = cat; break; }
      const cuiMap = [
        ["Ramen", ["ramen", "ราเมง", "ราเมน"]], ["Sushi", ["sushi", "ซูชิ"]],
        ["Japanese", ["japanese", "ญี่ปุ่น", "izakaya"]], ["Korean", ["korean", "เกาหลี"]],
        ["Isaan", ["isaan", "อีสาน", "ส้มตำ", "somtum"]], ["Thai", ["thai", "ไทย"]],
        ["Pizza", ["pizza", "พิซซ่า"]], ["Italian", ["italian", "pasta", "อิตาเลียน"]],
        ["Chinese", ["chinese", "จีน", "dim sum", "ติ่มซำ"]], ["Seafood", ["seafood", "ซีฟู้ด", "ทะเล"]],
        ["Vegan", ["vegan", "plant", "เจ", "มังสวิรัติ"]], ["Western", ["western", "steak", "burger", "สเต๊ก", "เบอร์เกอร์"]],
      ];
      for (const [cui, kws] of cuiMap) if (hasAny(a, kws)) { patch.cuisine = cui; break; }
      if (!patch.category && patch.cuisine) patch.category = "Casual dining";
      if (patch.category) heard.push(["Category", patch.category]);
      if (patch.cuisine) heard.push(["Cuisine", patch.cuisine]);
      return { patch, heard };
    },
  },
  {
    id: "name",
    extract: (a) => {
      const patch = {}; const heard = [];
      const dash = a.split(/\s+[—–-]\s+|:/);
      if (dash.length > 1) { patch.conceptName = dash[0].trim(); patch.tagline = dash.slice(1).join(" ").trim(); }
      else if (a.trim().length > 1 && a.trim().split(/\s+/).length <= 6) patch.conceptName = a.trim();
      else patch.tagline = a.trim();
      if (patch.conceptName) heard.push(["Name", patch.conceptName]);
      if (patch.tagline) heard.push(["Tagline", "“" + patch.tagline + "”"]);
      return { patch, heard };
    },
  },
  {
    id: "customer",
    extract: (a) => {
      const found = [];
      const map = [
        ["Students", ["student", "นักศึกษา", "นักเรียน", "uni"]],
        ["Office workers", ["office", "ออฟฟิศ", "พนักงาน", "worker", "lunch crowd"]],
        ["Families", ["famil", "ครอบครัว", "kids", "เด็ก"]],
        ["Tourists", ["tourist", "นักท่องเที่ยว", "travel"]],
        ["Expats", ["expat", "ต่างชาติ", "foreigner"]],
        ["Hi-so", ["hi-so", "ไฮโซ", "premium", "wealthy", "high end", "high-end"]],
      ];
      for (const [c, kws] of map) if (hasAny(a, kws)) found.push(c);
      return { patch: found.length ? { targetCustomer: found } : {}, heard: found.length ? [["Target customer", found.join(", ")]] : [] };
    },
  },
  {
    id: "price",
    extract: (a) => {
      const n = parseMoneyTh(a) || extractNumber(a, ["baht", "บาท", "฿", ""]);
      if (!n) return { patch: {}, heard: [] };
      const band = n < 150 ? "Budget" : n < 400 ? "Mid" : n < 900 ? "Premium" : "Luxury";
      return { patch: { priceBand: band }, heard: [["Price band", `${band} (${PRICE_BANDS[band].range})`]] };
    },
  },
  {
    id: "channels",
    extract: (a) => {
      const nums = (a.match(/\d+/g) || []).map(Number).filter((n) => n <= 100);
      if (nums.length >= 3 && nums[0] + nums[1] + nums[2] === 100) {
        const mix = { dineIn: nums[0], delivery: nums[1], takeaway: nums[2] };
        return { patch: { channelMix: mix }, heard: [["Channel mix", `${mix.dineIn} dine-in / ${mix.delivery} delivery / ${mix.takeaway} takeaway`]] };
      }
      if (hasAny(a, ["delivery only", "เดลิเวอรี่อย่างเดียว"])) return { patch: { channelMix: { dineIn: 0, delivery: 90, takeaway: 10 } }, heard: [["Channel mix", "delivery-led"]] };
      if (hasAny(a, ["mostly dine", "dine-in", "นั่งกิน", "นั่งทาน"])) return { patch: { channelMix: { dineIn: 75, delivery: 15, takeaway: 10 } }, heard: [["Channel mix", "dine-in-led (75/15/10)"]] };
      return { patch: {}, heard: [] };
    },
  },
  {
    id: "format",
    extract: (a) => {
      const patch = { format: {} }; const heard = [];
      const seats = extractNumber(a, ["seats?", "ที่นั่ง", "covers"]);
      const sqm = extractNumber(a, ["sqm", "sq\\.?m", "ตร\\.?ม", "ตารางเมตร", "square"]);
      if (seats) { patch.format.seats = Math.round(seats); heard.push(["Seats", String(Math.round(seats))]); }
      if (sqm) { patch.format.sqm = Math.round(sqm); heard.push(["Size", Math.round(sqm) + " m²"]); }
      for (const s of SERVICE_STYLES) if (a.toLowerCase().includes(s.toLowerCase().split(" ")[0])) { patch.format.serviceStyle = s; heard.push(["Service", s]); break; }
      return { patch: Object.keys(patch.format).length ? patch : {}, heard, mergeFormat: true };
    },
  },
  {
    id: "location",
    extract: (a) => {
      const map = [
        ["Shopping mall", ["mall", "ห้าง", "เซ็นทรัล", "central", "department"]],
        ["Community mall", ["community"]],
        ["CBD office", ["cbd", "silom", "สีลม", "sathorn", "สาทร", "asoke", "อโศก", "office district"]],
        ["Tourist zone", ["tourist", "khao san", "ข้าวสาร", "beach", "old town", "นักท่องเที่ยว"]],
        ["Campus", ["campus", "university", "มหาวิทยาลัย", "มหาลัย"]],
        ["Street / shophouse", ["street", "shophouse", "ตึกแถว", "soi", "ซอย", "ริมถนน"]],
      ];
      for (const [loc, kws] of map) if (hasAny(a, kws)) return { patch: { locationType: loc }, heard: [["Location type", loc]] };
      return { patch: {}, heard: [] };
    },
  },
  {
    id: "usp",
    extract: (a) => (a.trim().length > 3 ? { patch: { usp: a.trim() }, heard: [["Your edge", "“" + a.trim() + "”"]] } : { patch: {}, heard: [] }),
  },
  {
    id: "experience",
    extract: (a) => {
      let e = "";
      if (hasAny(a, ["opened", "own", "เคยเปิด", "เจ้าของ"])) e = "Opened before";
      else if (hasAny(a, ["worked", "chef", "cook", "เคยทำ", "ทำงาน", "barista", "manager"])) e = "Worked in F&B";
      else if (hasAny(a, ["no", "first", "never", "ไม่เคย", "ครั้งแรก", "มือใหม่"])) e = "First-timer";
      return e ? { patch: { founder: { experience: e } }, heard: [["Experience", e]], mergeFounder: true } : { patch: {}, heard: [] };
    },
  },
  {
    id: "capital",
    extract: (a) => {
      const patch = { founder: {} }; const heard = [];
      const cap = parseMoneyTh(a);
      if (cap) { patch.founder.capital = cap; heard.push(["Capital", fmtBaht(cap)]); }
      if (hasAny(a, ["myself", "run it", "เอง", "ทำเอง", "owner"])) { patch.founder.involvement = "Owner-operator"; heard.push(["Involvement", "Owner-operator"]); }
      else if (hasAny(a, ["invest", "ลงทุนอย่างเดียว", "partner runs", "hire"])) { patch.founder.involvement = "Investor"; heard.push(["Involvement", "Investor"]); }
      return { patch: Object.keys(patch.founder).length ? patch : {}, heard, mergeFounder: true };
    },
  },
];

function askInterview({ questionId, answer, idea }) {
  // DEFAULT (v1): rule/heuristic extraction from the answer text.
  // FUTURE: replace body with a real LLM call — keep this signature.
  const q = INTERVIEW.find((x) => x.id === questionId);
  if (!q) return { patch: {}, heard: [] };
  return q.extract(answer, idea);
}

/* ============================================================
   COHERENCE + READINESS
   ============================================================ */
function computeIdea(idea, t, lang) {
  const mixSum = idea.channelMix.dineIn + idea.channelMix.delivery + idea.channelMix.takeaway;
  const fields = [
    ["conceptName", !!idea.conceptName], ["category", !!idea.category], ["cuisine", !!idea.cuisine],
    ["targetCustomer", idea.targetCustomer.length > 0], ["priceBand", !!idea.priceBand],
    ["channelMix", mixSum === 100], ["seats", idea.format.seats > 0], ["serviceStyle", !!idea.format.serviceStyle],
    ["locationType", !!idea.locationType], ["usp", idea.usp.trim().length > 10],
    ["experience", !!idea.founder.experience], ["capital", idea.founder.capital > 0],
  ];
  const filled = fields.filter(([, ok]) => ok).length;
  const completeness = filled / fields.length;
  const ol = (v) => optLabel(lang, v);

  const flags = [];
  const genericUsp = /^(good|great|delicious|อร่อย|tasty|quality)\s*(food|taste)?\.?$/i;
  const weakUsp = !idea.usp || genericUsp.test(idea.usp.trim()) || idea.usp.trim().length < 12;
  if (mixSum !== 100) flags.push({ tone: "red", text: t("idea.flagMix", { mixSum }), blocking: true });
  if (idea.category === "Fine dining" && idea.channelMix.delivery >= 35) flags.push({ tone: "amber", text: t("idea.flagFineDelivery") });
  if ((idea.priceBand === "Premium" || idea.priceBand === "Luxury") && (idea.locationType === "Campus" || idea.locationType === "Community mall")) flags.push({ key: "price", tone: "amber", text: t("idea.flagPricePlace", { band: ol(idea.priceBand), loc: ol(idea.locationType) }) });
  if ((idea.priceBand === "Premium" || idea.priceBand === "Luxury") && idea.targetCustomer.includes("Students")) flags.push({ key: "price", tone: "amber", text: t("idea.flagPriceStudents") });
  if (idea.competition === "Many" && weakUsp) flags.push({ key: "usp", tone: "amber", text: t("idea.flagCompetitionUsp") });
  if (idea.channelMix.delivery >= 40) flags.push({ tone: "amber", text: t("idea.flagDeliveryPct", { pct: idea.channelMix.delivery }) });
  const rentBench = salesBenchmark(idea, t);
  if (rentBench && idea.rentExpectation > rentBench.healthyRent) {
    const gap = idea.rentExpectation - rentBench.healthyRent;
    flags.push({ key: "rent", tone: "amber", text: t("idea.flagRent", { rent: fmtBaht(idea.rentExpectation), gap: fmtBaht(gap), est: fmtBaht(rentBench.salesEst), basis: rentBench.basis }) });
  }
  const est = fitoutEstimate(idea, t, lang);
  if (est && idea.founder.capital > 0 && idea.founder.capital < est.value * 0.7) flags.push({ key: "capital", tone: "red", text: t("idea.flagCapital", { cap: fmtBaht(idea.founder.capital), est: fmtBaht(est.value), basis: est.basis }) });
  if (idea.usp && weakUsp) flags.push({ key: "usp", tone: "amber", text: t("idea.flagUsp") });
  if (idea.category === "Bar" && (idea.locationType === "CBD office" || idea.locationType === "Campus") && idea.targetCustomer.includes("Office workers")) flags.push({ tone: "amber", text: t("idea.flagBarOffice") });
  if (idea.founder.experience === "First-timer" && (idea.category === "Fine dining" || idea.format.seats > 80)) flags.push({ tone: "amber", text: t("idea.flagFirstTimerScale") });

  const amber = flags.filter((f) => f.tone === "amber").length;
  const red = flags.filter((f) => f.tone === "red").length;
  const coherence = Math.max(0, 40 - amber * 8 - red * 20);
  const readiness = Math.round(completeness * 60 + coherence);
  const blocking = flags.some((f) => f.blocking);

  let verdict;
  if (blocking || red > 0) verdict = { label: t("idea.verdictContradictions"), tone: "red" };
  else if (readiness >= 75) verdict = { label: t("idea.verdictReady"), tone: "green" };
  else verdict = { label: t("idea.verdictSharpen"), tone: "amber" };

  /* the single riskiest assumption to test first: rent breach > capital gap > price mismatch > weak USP */
  const RISK_ORDER = [
    ["rent", t("idea.riskRent")],
    ["capital", t("idea.riskCapital")],
    ["price", t("idea.riskPrice")],
    ["usp", t("idea.riskUsp")],
  ];
  let riskiest = null;
  for (const [key, text] of RISK_ORDER) {
    if (flags.some((f) => f.key === key)) { riskiest = { key, text }; break; }
  }

  return { readiness, completeness, filled, total: fields.length, flags, verdict, mixSum, fitout: est, rentBench, riskiest };
}

Object.assign(window, {
  CATEGORIES, CUISINE_PRESETS, CUSTOMERS, LOCATION_TYPES, SERVICE_STYLES, EXPERIENCE, RISK, INVOLVEMENT,
  PRICE_BANDS, priceRange, INTERVIEW, askInterview, computeIdea, fitoutEstimate, salesBenchmark,
});
