/* cst-data-swot.jsx — content + logic for "SWOT/Live": a living, decision-first
   strategy read. Six dimensions, each ending in a NEXT DECISION.
   Exported to window.CST_SWOT. */

const _S = window.CST;

// six dimensions of the living decision board
const DIMENSIONS = [
  { key: 'strengths', glyph: 'S', label: 'Speed-adjusted strengths',
    note: 'Your edge — and how fast it decays in an AI world.' },
  { key: 'working',   glyph: 'W', label: 'Working constraint',
    note: 'The single biggest thing slowing you down right now.' },
  { key: 'open',      glyph: 'O', label: 'Open windows',
    note: 'Opportunities that are open now — and why now.' },
  { key: 'tempo',     glyph: 'T', label: 'Tempo threats',
    note: 'Who can copy or outpace you, and how fast.' },
  { key: 'capital',   glyph: '$', label: 'Capital fit',
    note: 'The funding model that actually fits your economics.' },
  { key: 'pricing',   glyph: '×', label: 'Pricing power',
    note: 'Whether your unit economics are real — and value-based.' },
];

// the strategist session — one prompt at a time, reflects, occasionally pushes back
const STEPS = [
  {
    id: 'ctx',
    prompt: "Let's get oriented. What's the business, and what does it actually do — for whom?",
    placeholder: 'e.g. We run a 6-person studio doing brand + web for B2B SaaS companies…',
    examples: ['Boutique B2B web studio, 6 people', 'SaaS for indie property managers', 'Specialty coffee roaster + 2 cafés'],
    reflect: (a) => `Got it. I'll read everything through that lens.`,
  },
  {
    id: 'bottleneck',
    prompt: "What's the one thing slowing you down the most right now?",
    hint: 'Not a wishlist — the single constraint that, if fixed, frees the most.',
    placeholder: 'Honestly, the thing holding us back is…',
    reflect: () => "That's your working constraint. Everything else waits behind it.",
  },
  {
    id: 'pricing',
    prompt: 'Last one — how do you set your prices today?',
    kind: 'choice',
    choices: [
      { value: 'value',  label: 'On the value we deliver', desc: 'Tied to the outcome for the customer' },
      { value: 'cost',   label: 'Cost-plus a markup', desc: 'What it costs us, plus margin' },
      { value: 'market', label: 'Whatever competitors charge', desc: 'Matched to the market' },
      { value: 'guess',  label: 'Honestly — we guessed', desc: 'No real method yet' },
    ],
    reflect: (v) => ({
      value: "Good instinct. Now let me put the whole board together.",
      cost: 'Cost-plus caps your upside — but let me build the full picture first.',
      market: 'Matching the market is the worst place to compete. More on that in a second.',
      guess: "No judgment. Let me show you where that's costing you.",
    }[v]),
    pushback: (v) => v !== 'value'
      ? "Quick flag before I build this: pricing on cost or comps leaves the value you create on the table. Do you even know your margin per sale? If not, that's the real gap — and Price-It fixes it."
      : null,
  },
];

const ANALYSIS_LINES = [
  'Reading your position…',
  'Pricing your edge against the clock…',
  'Finding the real constraint…',
  'Stress-testing your funding model…',
  'Checking if the economics hold…',
  'Turning it into decisions…',
];

const STATUS_LABEL = { good: 'On your side', watch: 'Watch closely', risk: 'Act now' };

// ---- heuristic decision board (offline fallback) ---------------------------
function heuristicBoard(answers, meta) {
  const a = answers || {};
  const m = meta || {};
  const edge = (a.edge || m.edge || '').trim();
  const bottleneck = (a.bottleneck || 'your current constraint').trim();
  const funding = a.funding || 'bootstrap';
  const pricing = a.pricing || 'guess';
  const snip = (s, n = 46) => { s = (s || '').trim(); return s.length > n ? s.slice(0, n - 1).trim() + '…' : s; };

  const capital = {
    bootstrap: { status: 'good',  read: "You've kept control. The only risk is under-funding the pace you want.",
      decision: 'Stay bootstrapped — but ring-fence [X%] of revenue as a growth budget so you’re not starving the business of fuel.' },
    revenue:   { status: 'good',  read: "Revenue-funded is the strongest seat in the room — you're default-alive and beholden to no one.",
      decision: 'Double down on revenue-based growth. Only consider outside money to seize a specific, time-boxed window.' },
    angel:     { status: 'watch', read: 'A little outside money, mostly your call. Keep the cap table clean while you can.',
      decision: 'Skip the next raise. Get to profitability on this check before you give away more of the company.' },
    vc:        { status: 'risk',  read: "VC fits hyper-growth, winner-take-all markets. For most operators it trades control for a pace they don't need.",
      decision: 'Before raising VC, model the revenue-based path. If margins can fund [your target] growth, keep the equity.' },
    none:      { status: 'watch', read: 'Pre-revenue means capital fit is really about runway to your first dollars.',
      decision: 'Pick the cheapest path to revenue — grants or a paid pilot — before any equity round.' },
  }[funding];

  const pricingDim = {
    value:  { status: 'watch', read: 'You price on value — good. Now prove the unit economics actually hold per sale.',
      decision: 'Run Price-It on your core offer to confirm margin and your true effective hourly rate.' },
    cost:   { status: 'risk',  read: 'Cost-plus caps your upside. You never capture the value you create for customers.',
      decision: 'Re-anchor pricing to customer outcome, not your costs. Test a [+20–40%] value-based tier in Price-It.' },
    market: { status: 'risk',  read: 'Matching competitors puts you in a price war you can only lose slowly.',
      decision: 'Find one dimension you’re clearly best at and charge a premium for it. Validate the number in Price-It.' },
    guess:  { status: 'risk',  read: "Guessing means you don't know which work makes money and which quietly loses it.",
      decision: 'Stop guessing this week. Run Price-It on every active offer and kill anything under [target margin].' },
  }[pricing];

  return {
    headline: 'Your edge is real but on a clock — the leverage is pricing and focus.',
    score: pricing === 'value' ? 64 : 52,
    dims: {
      strengths: { status: 'watch',
        read: edge ? `Your edge — ${snip(edge, 60)}${m.edge && !a.edge ? ' (from your idea check)' : ''} — is genuine, but anything describable is now copyable faster than ever.` : 'You have an edge, but in an AI world the half-life of any advantage is shrinking.',
        decision: 'Convert your edge into something AI can’t clone in 90 days: proprietary data, a workflow, or a relationship.' },
      working: { status: 'risk',
        read: `Your real constraint is ${snip(bottleneck, 60)} — and it’s gating everything behind it.`,
        decision: `Make clearing "${snip(bottleneck, 28)}" the single priority this month. Don’t start anything new until it moves.` },
      open: { status: 'good',
        read: 'AI just reset customer expectations in your category — the players who move first reset the defaults.',
        decision: 'Ship one visibly AI-native improvement to your core offer within [30 days], while the window is open.' },
      tempo: { status: 'watch',
        read: a.threat ? `Watch ${snip(a.threat, 56)} — assume they move faster than you’d like.` : 'Assume a fast follower can copy your visible features in a quarter, not a year.',
        decision: 'Compete on the parts that don’t commoditize — trust, speed of service, and depth — not features.' },
      capital,
      pricing: pricingDim,
    },
    _fallback: true,
  };
}

// ---- live AI prompt + parser -----------------------------------------------
function boardPrompt(answers, meta) {
  const a = answers || {};
  const m = meta || {};
  const carry = (m.edge || m.ideaScore != null)
    ? `\nCARRIED OVER FROM THEIR IDEA CHECK (use it to inform the Speed-adjusted strengths read, don't ignore it):\n- Edge they believe they have: "${m.edge || ''}"${m.ideaScore != null ? `\n- Their idea scored ${m.ideaScore}/100` : ''}\n`
    : '';
  return `You are a candid, math-minded operating advisor — warm but willing to disagree. You're producing a LIVING "SWOT" decision board for an operator. Every dimension must end in a concrete NEXT DECISION (an action to take), never a description.
${carry}
WHAT THEY TOLD YOU:
- Business: "${a.ctx || ''}"
- Their claimed edge: "${a.edge || ''}"
- Biggest current bottleneck: "${a.bottleneck || ''}"
- How they're funded: "${a.funding || ''}"
- How they price: "${a.pricing || ''}"
- Who could copy/outpace them: "${a.threat || ''}"

Return ONLY a JSON object (no markdown) with exactly:
{
  "headline": "<one blunt, useful sentence summarizing their strategic position>",
  "score": <integer 0-100, "decision readiness" — how ready they are to act with confidence>,
  "dims": {
    "strengths": { "status": "good|watch|risk", "read": "<1-2 sentences on their edge AND how fast it decays>", "decision": "<the next decision>" },
    "working":   { "status": "good|watch|risk", "read": "<their single biggest constraint>", "decision": "<the next decision>" },
    "open":      { "status": "good|watch|risk", "read": "<an opportunity open NOW, with why-now>", "decision": "<the next decision>" },
    "tempo":     { "status": "good|watch|risk", "read": "<who can copy/outpace them and how fast>", "decision": "<the next decision>" },
    "capital":   { "status": "good|watch|risk", "read": "<is their funding model the right fit for their economics — challenge a default 'raise VC'>", "decision": "<the next decision>" },
    "pricing":   { "status": "good|watch|risk", "read": "<are unit economics real; are they pricing on value>", "decision": "<the next decision; mention running Price-It if relevant>" }
  }
}
Rules: Be direct and specific. Reference what they told you. Where a number belongs but you don't have it, use a bracketed [placeholder] like [target margin] — NEVER invent figures. Decisions must be actions ("Do X by [date]"), not observations. status="risk" means act now, "watch" means monitor, "good" means it's working.`;
}

function parseBoard(raw) {
  const o = _S.parseJSONLoose(raw);
  if (!o || !o.dims) return null;
  const ok = (s) => ['good', 'watch', 'risk'].includes(s) ? s : 'watch';
  const dims = {};
  for (const d of DIMENSIONS) {
    const x = o.dims[d.key];
    if (!x || !x.read || !x.decision) return null;
    dims[d.key] = { status: ok(x.status), read: String(x.read), decision: String(x.decision) };
  }
  const score = Math.round(Number(o.score));
  return {
    headline: String(o.headline || 'Your living decision board'),
    score: isFinite(score) ? _S.clamp(score) : 58,
    dims,
  };
}

// ---- tailored "likely bottleneck" suggestions from the business context ----
function bottleneckExamplesPrompt(ctx) {
  return `An operator just described their business. Suggest 3 short, plausible bottlenecks that a business like theirs commonly hits — phrased in their words, first person, concrete.

BUSINESS: "${ctx}"

Return ONLY JSON: { "options": ["<short bottleneck, max 8 words>", "<another>", "<another>"] }
Rules: exactly 3. First-person fragments (e.g. "Inconsistent lead flow", "Too reliant on one client", "Delivery takes too long"). Specific to this kind of business. No jargon, no full sentences.`;
}
function parseBottleneckExamples(raw) {
  const o = _S.parseJSONLoose(raw);
  const list = o && Array.isArray(o.options) ? o.options : null;
  if (!list) return null;
  const out = list.filter(Boolean).map((s) => String(s).replace(/^["'\s]+|["'\s]+$/g, '').slice(0, 48)).filter((s) => s.length > 2).slice(0, 4);
  return out.length >= 2 ? out : null;
}

window.CST_SWOT = {
  DIMENSIONS, STEPS, ANALYSIS_LINES, STATUS_LABEL,
  heuristicBoard, boardPrompt, parseBoard,
  bottleneckExamplesPrompt, parseBottleneckExamples,
};
