/* cst-data-validate.jsx — content + logic for the "Validate an idea" tool
   (the original Proving Ground flow). Exported to window.CST_VALIDATE. */

// a deep, varied pool — we surface a fresh random 3 on each session load
const EXAMPLE_POOL = [
  'AI scheduling assistant for dental clinics',
  'Marketplace for refurbished lab equipment',
  'Carbon tracking for small manufacturers',
  'Same-day repair service for e-bikes',
  'Meal-prep subscription for night-shift workers',
  'Bookkeeping co-pilot for solo contractors',
  'Private-label skincare for sensitive skin',
  'Tutoring marketplace for trade apprentices',
  'Inventory app for independent coffee roasters',
  'Compliance assistant for short-term rental hosts',
  'On-demand notary network for real estate',
  'Resale platform for designer furniture',
  'Route planner for mobile pet groomers',
  'Membership club for local wine makers',
  'Warranty tracker for home appliances',
  'Staffing app for last-minute restaurant shifts',
];
function pickExamples(n = 3) {
  const a = EXAMPLE_POOL.slice();
  for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; }
  return a.slice(0, n);
}
// chosen once per session (module load) → varies each time the app is opened
const EXAMPLE_IDEAS = pickExamples(3);

const IDEA_PROMPTS = [
  "What's on your mind?",
  'What are you thinking about?',
  'Got an idea brewing?',
  "What's the big idea?",
  'What do you want to build?',
  'What if… ?',
];

const IDEA_TIPS = [
  "The best ideas solve a problem you've felt yourself.",
  'What does your day waste the most time on?',
  'Who do you wish had a better tool — and for what?',
  'Boring problems often make the best businesses.',
  'What would you happily pay someone else to handle?',
  'Start with a tiny group who would love it, not everyone.',
  "It's fine to be rough — just get the gist down.",
];

const FOCUS = [
  { key: 'speed',  label: "It's faster",           desc: 'People get what they need quicker' },
  { key: 'cost',   label: 'It costs less',          desc: 'Cheaper than the options out there today' },
  { key: 'trust',  label: "It's more trustworthy",  desc: 'Safe, reliable, easy to feel good about' },
  { key: 'niche',  label: "It's made for one group", desc: 'Built really well for a specific kind of person' },
  { key: 'tech',   label: 'It does something new',   desc: "Something that wasn't possible before" },
];

const EXPLORE_NODES = ['Market', 'Competitors', 'Demand', 'Pricing', 'Risk', 'Segment', 'Channel', 'Moat'];

const BREAKDOWN_FACTORS = [
  { key: 'need',   label: 'Need',   measures: 'How real and urgent this problem is for the people you’d serve.' },
  { key: 'ease',   label: 'Ease',   measures: 'How realistic it is to build and deliver a first version.' },
  { key: 'edge',   label: 'Edge',   measures: 'How hard it is for others to copy what makes you different.' },
  { key: 'timing', label: 'Timing', measures: 'Whether now is the right moment for this to take off.' },
  { key: 'reach',  label: 'Reach',  measures: 'How easily you can get in front of the people who’d buy.' },
];

// plain-language read of one factor at a given score
function factorRead(key, score) {
  const band = score >= 78 ? 'strong' : score >= 58 ? 'solid' : score >= 42 ? 'shaky' : 'weak';
  const map = {
    need:   { strong: 'People clearly feel this pain — that’s the best thing you can have.', solid: 'There’s a real need; sharpen who feels it most.', shaky: 'The need isn’t obvious yet — talk to more people before building.', weak: 'Hard to see who urgently needs this. Find the pain first.' },
    ease:   { strong: 'A first version looks very doable. Ship something small fast.', solid: 'Buildable, with some hard parts — scope the smallest version.', shaky: 'This will take real effort to deliver — cut scope hard.', weak: 'Delivering this is a heavy lift. Simplify the promise.' },
    edge:   { strong: 'You’ve got something others can’t easily copy. Protect it.', solid: 'Some edge — make it sharper and harder to clone.', shaky: 'Easy to copy today. Find what only you can offer.', weak: 'Little to stop a fast follower. Build a real moat early.' },
    timing: { strong: 'The moment is right — move while the window is open.', solid: 'Decent timing; watch what’s shifting in your favour.', shaky: 'Timing is uncertain — know what has to be true to win now.', weak: 'May be early or late. Be clear why now is the moment.' },
    reach:  { strong: 'You can reach buyers cheaply — a big advantage.', solid: 'Reachable, with effort — pick one channel and own it.', shaky: 'Getting in front of buyers looks hard — plan this early.', weak: 'Distribution is the real risk. Solve “how they find you” first.' },
  };
  return { band, text: (map[key] && map[key][band]) || '' };
}

const REPORT_INCLUDES = [
  'The full breakdown of who to try it with',
  'Every thing to watch — and how to handle each',
  'Your complete step-by-step starting plan',
  'A look at who else is doing something similar',
  'A saved report you can share with anyone',
];

const ANALYSIS_LINES = [
  'Getting to know your idea…',
  "Thinking about who it's for…",
  "Looking at what's already out there…",
  'Spotting things to watch…',
  'Putting it all together…',
];

function scoreBand(score) {
  if (score >= 85) return { label: 'This could be big', tone: 'high' };
  if (score >= 65) return { label: 'Looking good — keep going', tone: 'high' };
  if (score >= 45) return { label: 'Promising — a few things to refine', tone: 'mid' };
  return { label: 'A few things to rethink', tone: 'low' };
}

function heuristicVerdict(idea, focus) {
  const words = idea.trim().split(/\s+/).length;
  const specificity = Math.min(1, words / 12);
  const base = 52 + Math.round(specificity * 20);
  const focusBoost = { speed: 6, cost: 5, trust: 9, niche: 11, tech: 8 }[focus.key] || 6;
  const score = Math.max(40, Math.min(92, base + focusBoost));
  const clamp = (n) => Math.max(25, Math.min(96, Math.round(n)));
  const breakdown = {
    need:   clamp(score + 5),
    ease:   clamp(score - (focus.key === 'tech' ? 16 : 4)),
    edge:   clamp(score + ({ speed: 4, cost: 2, trust: 6, niche: 10, tech: 8 }[focus.key] || 4)),
    timing: clamp(score - 2),
    reach:  clamp(score - (focus.key === 'niche' ? 14 : 2)),
  };
  const subject = idea.trim().replace(/\.$/, '') || 'your idea';
  const betLine = { speed: 'being faster', cost: 'costing less', trust: 'being safe and reliable', niche: 'being made for one group', tech: 'doing something new' }[focus.key];
  return {
    score, breakdown,
    verdict: scoreBand(score).label,
    summary: `There's something here. Leaning into ${betLine} is a smart way to stand out — just keep "${subject}" simple and focused to start.`,
    market: `Try it first with the people who feel this problem the most and can say yes on their own. Win them over, then grow from there — you don't have to reach everyone at once.`,
    risks: [
      'Other people might try something similar once it works — so stay close to your users and keep improving.',
      'Getting the word out can be harder than building it. Think early about how people will find you.',
      "Make the good part obvious in the first few minutes — that's what makes people stick around.",
    ],
    nextSteps: [
      "Say what your idea does in one simple sentence, then share it with 10 people who'd use it.",
      'Build the smallest version that shows the main thing working — nothing fancy yet.',
      'Pick one place to find your first users, and focus there.',
    ],
    _fallback: true,
  };
}

function verdictPrompt(idea, focus) {
  return `You are a warm, encouraging mentor helping someone think through a new idea. Explain everything in simple, everyday words — like you're talking to a friend who has never run a business.

THE IDEA: "${idea}"
WHAT THEY THINK MAKES IT SPECIAL: ${focus.label} — ${focus.desc}

Return ONLY a JSON object (no markdown, no extra text) with exactly these keys:
{
  "score": <integer 0-100, how promising this looks — lean supportive, rarely below 40>,
  "breakdown": { "need": <0-100>, "ease": <0-100>, "edge": <0-100>, "timing": <0-100>, "reach": <0-100> },
  "verdict": "<a short, friendly one-line take>",
  "summary": "<2 simple, encouraging sentences about what's good about the idea>",
  "market": "<who they should try it with first, and why — plain words, 1-2 sentences>",
  "risks": ["<a thing to gently watch out for>", "<another>", "<another>"],
  "nextSteps": ["<a simple first step>", "<another>", "<another>"]
}
Rules: Be kind and encouraging, never harsh. Plain language — no jargon (avoid "wedge", "moat", "TAM", "incumbents", "monetize"). Short, clear sentences. Honest but constructive.`;
}

function parseVerdict(raw) {
  const o = window.CST.parseJSONLoose(raw);
  if (!o) return null;
  const score = Math.round(Number(o.score));
  if (!isFinite(score)) return null;
  const arr = (x) => Array.isArray(x) ? x.filter(Boolean).map(String).slice(0, 4) : [];
  const bdRaw = (o.breakdown && typeof o.breakdown === 'object') ? o.breakdown : {};
  const breakdown = {};
  BREAKDOWN_FACTORS.forEach((f) => {
    const v = Math.round(Number(bdRaw[f.key]));
    breakdown[f.key] = isFinite(v) ? window.CST.clamp(v) : window.CST.clamp(score);
  });
  return {
    score: window.CST.clamp(score), breakdown,
    verdict: String(o.verdict || scoreBand(score).label),
    summary: String(o.summary || ''), market: String(o.market || ''),
    risks: arr(o.risks), nextSteps: arr(o.nextSteps),
  };
}

// ---- tailored "what makes it special" options, specific to the idea --------
function focusOptionsPrompt(idea) {
  return `You help someone spot why THEIR specific business idea could stand out. Given the idea, write 4 distinct, plausible “what makes it special” angles — each phrased concretely for THIS idea, in plain, friendly words.

IDEA: "${idea}"

Return ONLY JSON (no markdown):
{ "options": [ { "key": "speed|cost|trust|niche|tech", "label": "<3–6 word angle specific to this idea>", "desc": "<one short, plain sentence>" } ] }
Rules: exactly 4 options. "key" must be one of speed, cost, trust, niche, tech (these map to how it competes). Prefer 4 different keys; never more than two the same. Labels must be concrete to the idea (mention the who/what), not generic like “it’s faster”. No jargon. Keep it warm and simple.`;
}

const FOCUS_KEYS = ['speed', 'cost', 'trust', 'niche', 'tech'];
function parseFocusOptions(raw) {
  const o = window.CST.parseJSONLoose(raw);
  const list = o && Array.isArray(o.options) ? o.options : null;
  if (!list) return null;
  // map common synonyms the model invents back onto our five competitive keys
  const SYN = { value: 'niche', quality: 'trust', convenience: 'speed', service: 'trust', price: 'cost', cheap: 'cost', fast: 'speed', speed: 'speed', cost: 'cost', trust: 'trust', niche: 'niche', tech: 'tech', technology: 'tech', innovation: 'tech', brand: 'trust', focus: 'niche', specialized: 'niche', specialised: 'niche' };
  const cycle = ['niche', 'trust', 'tech', 'cost', 'speed'];
  const out = [];
  list.forEach((x, i) => {
    if (!x || !x.label) return;                          // only a label is truly required
    const k = String(x.key || '').toLowerCase().trim();
    const key = FOCUS_KEYS.includes(k) ? k : (SYN[k] || cycle[i % cycle.length]);
    out.push({ key, label: String(x.label).slice(0, 60), desc: String(x.desc || '').slice(0, 90) });
  });
  // coerce to distinct-ish keys so scoring stays varied, but never drop a tailored label
  return out.length >= 3 ? out.slice(0, 5) : null;
}

window.CST_VALIDATE = {
  EXAMPLE_IDEAS, IDEA_PROMPTS, IDEA_TIPS, FOCUS, EXPLORE_NODES, BREAKDOWN_FACTORS,
  REPORT_INCLUDES, ANALYSIS_LINES, scoreBand, heuristicVerdict, verdictPrompt, parseVerdict,
  focusOptionsPrompt, parseFocusOptions, factorRead,
};
