/**
 * AI Prompt Library for Persona Pipeline
 *
 * Generates Persona (Buyer Persona) data in 3 stages using company context
 * and ICP data as seed input. Follows the same pattern as ICP prompts.
 */

// ============================================
// TYPES
// ============================================

export interface PersonaPipelineInputs {
  companyName: string;
  companyDescription?: string;
  companyIndustry?: string;
  icpName?: string;
  icpIndustry?: string;
  icpDescription?: string;
  icpPainPoints?: string[];
  icpBusinessGoals?: string[];
  icpTechStack?: string[];
  icpCompanySize?: string;
  /**
   * Currency for every budget figure on the persona. Resolved upstream: the
   * parent ICP's primary currency, else the Business Profile's country.
   */
  currency?: string;
}

export type PartialPersonaAnalysis = Record<string, any>;

export interface PromptResult {
  systemPrompt: string;
  userPrompt: string;
  maxTokens: number;
}

// ============================================
// HELPERS
// ============================================

function buildContext(inputs: PersonaPipelineInputs): string {
  const parts: string[] = [];
  if (inputs.companyName) parts.push(`Company: ${inputs.companyName}`);
  if (inputs.companyDescription) parts.push(`Company Description: ${inputs.companyDescription}`);
  if (inputs.companyIndustry) parts.push(`Company Industry: ${inputs.companyIndustry}`);

  if (inputs.icpName) {
    parts.push(`\n--- ICP Context ---`);
    parts.push(`ICP Name: ${inputs.icpName}`);
    if (inputs.icpIndustry) parts.push(`ICP Industry: ${inputs.icpIndustry}`);
    if (inputs.icpDescription) parts.push(`ICP Description: ${inputs.icpDescription}`);
    if (inputs.icpCompanySize) parts.push(`ICP Company Size: ${inputs.icpCompanySize}`);
    if (inputs.icpPainPoints?.length) parts.push(`ICP Pain Points: ${inputs.icpPainPoints.join(', ')}`);
    if (inputs.icpBusinessGoals?.length) parts.push(`ICP Business Goals: ${inputs.icpBusinessGoals.join(', ')}`);
    if (inputs.icpTechStack?.length) parts.push(`ICP Tech Stack: ${inputs.icpTechStack.join(', ')}`);
  }

  if (inputs.currency) {
    const meta = getCurrencyMeta(inputs.currency);
    parts.push(`\nBudget Currency: ${meta.name} (${meta.code}, symbol ${meta.symbol})`);
  }

  return parts.join('\n');
}

const JSON_INSTRUCTION = '\n\nIMPORTANT: Respond with ONLY valid JSON. No markdown fences, no explanation before or after the JSON. Do not wrap in ```json``` blocks.';

import { formatCharLimitsInstruction, formatArrayCharLimitsInstruction, PERSONA_FIELD_LIMITS, PERSONA_ARRAY_FIELD_LIMITS } from './fieldCharLimits';
import { getCurrencyMeta } from './contentCurrency';

/**
 * Currency directive for persona generation.
 *
 * Persona budget fields (expected budget, spending authority, approval level)
 * used to come back in USD whatever market the business sells into.
 */
export function buildPersonaCurrencyInstruction(inputs: PersonaPipelineInputs): string {
  const meta = getCurrencyMeta(inputs.currency);
  return `

CURRENCY (STRICT): This persona buys in ${meta.name} (${meta.code}, symbol "${meta.symbol}").
- Every monetary value — expected budget, spending authority, budget ownership, purchase approval level, and any amount mentioned in other fields — MUST use ${meta.code} with the "${meta.symbol}" symbol (e.g. ${meta.example}).
- Do NOT use USD, "$", or any other currency unless that currency is ${meta.code}. Do NOT convert or dual-price.
- Amounts must be realistic for that market at this persona's seniority and company size — never a USD figure with the ${meta.symbol} symbol swapped in.`;
}

/** Currency-aware examples for the persona budget fields. */
function personaBudgetExamples(inputs: PersonaPipelineInputs) {
  const s = getCurrencyMeta(inputs.currency).symbol;
  return {
    expectedBudget: `string — realistic budget range, e.g. '${s}10,000–${s}25,000 annually'`,
    spendingAuthority: `string — spending authority level, e.g. 'Can approve purchases up to ${s}20,000'`,
    purchaseApprovalLevel: `string — purchase approval level, e.g. 'CFO approval above ${s}20,000'`,
  };
}

// ============================================
// STAGE 1: DEMOGRAPHICS & PROFESSIONAL
// ============================================

export function buildPersonaDemographicsPrompt(inputs: PersonaPipelineInputs): PromptResult {
  const systemPrompt = `You are a B2B buyer persona research AI. Your task is to define the demographic and professional profile of a key decision-maker or influencer within the ideal customer company (ICP).

Be specific and realistic. The persona should represent a real type of person who would be involved in purchasing decisions for the given offering. Job title and seniority should align with the ICP's company size and industry.${JSON_INSTRUCTION}

Your response must match this exact JSON schema:
{
  "name": "string — a descriptive persona name, e.g. 'Marketing Mary' or 'CTO Chris' — use a catchy first-name-based label",
  "ageRange": "string — typical age range as min-max whole numbers only, e.g. '30-45' — no words, no '+'",
  "gender": "string — one of: male, female, non-binary, prefer-not-say",
  "jobTitle": "string — specific job title, e.g. 'VP of Marketing', 'Director of Operations'",
  "seniorityLevel": "string — one of: entry, mid, senior, c-level, founder",
  "department": "string — primary department, e.g. 'Marketing', 'Operations', 'Engineering'",
  "industry": "string — their specific industry focus, e.g. 'SaaS', 'Healthcare Technology'",
  "experience": "string — years of experience as numbers only, e.g. '8-12' or '10' — never include the word 'years'",
  "skills": ["5-8 key skills this persona possesses"],
  "toolsUsed": ["5-8 software tools this persona uses daily"],
  "certifications": ["2-4 relevant certifications this persona might hold"]
}`;

  const userPrompt = `Define the demographic and professional profile of a key buyer persona for this business:\n\n${buildContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 2000 };
}

// ============================================
// STAGE 2: PSYCHOGRAPHICS & GOALS
// ============================================

export function buildPersonaPsychographicsPrompt(inputs: PersonaPipelineInputs, partial: PartialPersonaAnalysis): PromptResult {
  const priorContext = [];
  if (partial.name) priorContext.push(`Persona: ${partial.name}`);
  if (partial.jobTitle) priorContext.push(`Job Title: ${partial.jobTitle}`);
  if (partial.seniorityLevel) priorContext.push(`Seniority: ${partial.seniorityLevel}`);
  if (partial.department) priorContext.push(`Department: ${partial.department}`);
  if (partial.skills?.length) priorContext.push(`Skills: ${partial.skills.join(', ')}`);
  const contextStr = priorContext.length > 0 ? `\n\nPrior Persona Analysis:\n${priorContext.join('\n')}` : '';

  const systemPrompt = `You are a B2B buyer psychology AI. Based on the persona's demographic profile and ICP context, define the psychographic characteristics, goals, and motivations of this buyer persona.

Goals and pain points should be directly tied to their role and the ICP's challenges. The bio should read like a brief character sketch of a real person. The quote should sound like something this persona would actually say.${JSON_INSTRUCTION}${formatCharLimitsInstruction({ bio: PERSONA_FIELD_LIMITS.bio, quote: PERSONA_FIELD_LIMITS.quote })}${formatArrayCharLimitsInstruction(PERSONA_ARRAY_FIELD_LIMITS)}

Your response must match this exact JSON schema:
{
  "bio": "string — 3-4 sentence character sketch describing this persona's background, role, and outlook",
  "quote": "string — a representative quote this persona might say about their work challenges, e.g. 'I need a solution that just works without requiring my whole team to retrain'",
  "goals": ["4-6 specific goals this persona wants to achieve in their role"],
  "painPoints": ["4-6 specific pain points they experience that the offering could address"],
  "motivations": ["3-5 key motivations driving their decisions, e.g. 'Efficiency', 'Cost reduction', 'Team productivity'"],
  "values": ["3-5 core values this persona holds, e.g. 'Innovation', 'Reliability', 'Transparency'"],
  "fears": ["3-5 fears or concerns this persona has about adopting new solutions"]
}`;

  const userPrompt = `Define the psychographic profile and goals of this buyer persona:${contextStr}\n\n${buildContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 2000 };
}

// ============================================
// STAGE 3: BEHAVIOURAL & BUYING
// ============================================

export function buildPersonaBuyingPrompt(inputs: PersonaPipelineInputs, partial: PartialPersonaAnalysis): PromptResult {
  const priorContext = [];
  if (partial.name) priorContext.push(`Persona: ${partial.name}`);
  if (partial.jobTitle) priorContext.push(`Job Title: ${partial.jobTitle}`);
  if (partial.goals?.length) priorContext.push(`Goals: ${partial.goals.join(', ')}`);
  if (partial.painPoints?.length) priorContext.push(`Pain Points: ${partial.painPoints.join(', ')}`);
  if (partial.motivations?.length) priorContext.push(`Motivations: ${partial.motivations.join(', ')}`);
  const contextStr = priorContext.length > 0 ? `\n\nPrior Persona Analysis:\n${priorContext.join('\n')}` : '';

  const systemPrompt = `You are a B2B sales and buying behaviour AI. Based on the full persona profile and ICP context, define the behavioural traits, daily challenges, and buying behaviour of this buyer persona.

Decision-making style should reflect their seniority level. Research habits and content preferences should be realistic for their role. Buying role and objections should be specific to the type of solution being offered. Budget fields should be realistic for the persona's job title, seniority, company size, and industry.${JSON_INSTRUCTION}${buildPersonaCurrencyInstruction(inputs)}

Your response must match this exact JSON schema:
{
  "decisionMakingStyle": "string — one of: analytical, intuitive, collaborative, authoritative",
  "researchHabits": "string — how this persona researches solutions, e.g. 'Reads industry reports, consults peers, runs small pilot tests'",
  "contentPreferences": ["4-6 content types they prefer, from: blog-posts, videos, whitepapers, case-studies, webinars, podcasts, infographics, email"],
  "communicationChannel": ["3-5 preferred communication channels, from: email, phone, slack, linkedin, in-person, video-call"],
  "dailyChallenges": ["4-6 daily challenges they face in their role"],
  "successMetrics": ["4-6 metrics by which their success is measured, e.g. 'MQL growth', 'Customer retention rate'"],
  "kpi": ["3-5 key KPIs they track, e.g. 'Revenue growth', 'Customer satisfaction score'"],
  "budgetAuthority": "boolean — whether this persona has direct budget authority",
  "influenceLevel": "string — one of: low, medium, high",
  "buyingRole": "string — one of: decision-maker, influencer, end-user, technical-evaluator, procurement, executive-sponsor, budget-approver, recommender, champion, gatekeeper",
  "expectedBudget": "${personaBudgetExamples(inputs).expectedBudget}",
  "spendingAuthority": "${personaBudgetExamples(inputs).spendingAuthority}",
  "budgetOwnership": "string — their budget ownership, e.g. 'Department Head'",
  "purchaseApprovalLevel": "${personaBudgetExamples(inputs).purchaseApprovalLevel}",
  "objections": ["3-5 common objections this persona would raise during a sales conversation"]
}`;

  const userPrompt = `Define the behavioural traits and buying behaviour of this buyer persona:${contextStr}\n\n${buildContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 2000 };
}

// ============================================
// ENHANCEMENT PROMPT (for low-confidence retry)
// ============================================

export function buildPersonaEnhancementPrompt(
  stageName: string,
  stageOutput: Record<string, any>,
  lowConfidenceFields: string[],
  inputs?: PersonaPipelineInputs
): PromptResult {
  // The retry regenerates real content, so it needs the same currency rule as
  // the stage it is repairing — otherwise repaired budgets drift back to USD.
  const currencyInstruction = inputs ? buildPersonaCurrencyInstruction(inputs) : '';
  const systemPrompt = `You are a B2B buyer persona research AI performing a refinement pass. The previous analysis for "${stageName}" had low confidence on certain fields. Please provide more specific, detailed, and well-reasoned analysis for the indicated fields.${JSON_INSTRUCTION}${currencyInstruction}

Respond with the SAME JSON schema as before, but with improved values for the flagged fields. Keep the fields that already had good results unchanged.`;

  const userPrompt = `Previous analysis:\n${JSON.stringify(stageOutput, null, 2)}\n\nFields needing improvement (low confidence): ${lowConfidenceFields.join(', ')}\n\nPlease refine the analysis, providing more specific and detailed values for the flagged fields.`;

  return { systemPrompt, userPrompt, maxTokens: 1500 };
}

// ============================================
// BULK MULTI-PERSONA GENERATION
// Generates 4-5 distinct personas in a single AI call
// ============================================

export interface BulkPersonaInputs extends PersonaPipelineInputs {
  icpName: string;
  icpIndustry?: string;
  icpDescription?: string;
}

export function buildBulkPersonaPrompt(inputs: BulkPersonaInputs, count: number = 5): PromptResult {
  const clampedCount = Math.min(Math.max(count, 1), 100);
  const systemPrompt = `You are a B2B buyer persona research AI. Your task is to define ${clampedCount} DISTINCT buyer personas that represent different stakeholders involved in purchasing decisions within the given ICP (Ideal Customer Profile).

Each persona must cover a DIFFERENT buying role — vary roles across the personas from: Decision Maker, Influencer, End User, Technical Evaluator, Procurement, Executive Sponsor, Budget Approver, Recommender, Champion, Gatekeeper. Each should have a distinct personality, background, and set of concerns.

For each persona, provide complete data across demographics, psychographics, and buying behaviour. Be specific and realistic. Names should be catchy first-name-based labels. Budget fields should be realistic for the persona's job title, seniority, company size, and industry.${JSON_INSTRUCTION}${buildPersonaCurrencyInstruction(inputs)}${formatCharLimitsInstruction(PERSONA_FIELD_LIMITS)}${formatArrayCharLimitsInstruction(PERSONA_ARRAY_FIELD_LIMITS)}

Your response must match this exact JSON schema — an array of ${clampedCount} persona objects:
{
  "personas": [
    {
      "name": "string — catchy persona name, e.g. 'Marketing Mary', 'CTO Chris'",
      "ageRange": "string — typical age range as min-max whole numbers only, e.g. '30-45'",
      "gender": "string — one of: male, female, non-binary, prefer-not-say",
      "jobTitle": "string — specific job title",
      "seniorityLevel": "string — one of: entry, mid, senior, c-level, founder",
      "department": "string — primary department",
      "industry": "string — specific industry focus",
      "experience": "string — years of experience as numbers only, e.g. '8-12' — no words",
      "skills": ["5-8 key skills"],
      "toolsUsed": ["5-8 software tools"],
      "certifications": ["2-4 relevant certifications"],
      "bio": "string — 3-4 sentence character sketch",
      "quote": "string — representative quote about their work challenges",
      "goals": ["4-6 specific goals"],
      "painPoints": ["4-6 specific pain points"],
      "motivations": ["3-5 key motivations"],
      "values": ["3-5 core values"],
      "fears": ["3-5 fears about adopting new solutions"],
      "decisionMakingStyle": "string — one of: analytical, intuitive, collaborative, authoritative",
      "researchHabits": "string — how they research solutions",
      "contentPreferences": ["4-6 content types from: blog-posts, videos, whitepapers, case-studies, webinars, podcasts, infographics, email"],
      "communicationChannel": ["3-5 channels from: email, phone, slack, linkedin, in-person, video-call"],
      "dailyChallenges": ["4-6 daily challenges"],
      "successMetrics": ["4-6 success metrics"],
      "kpi": ["3-5 key KPIs"],
      "budgetAuthority": "boolean — has direct budget authority",
      "influenceLevel": "string — one of: low, medium, high",
      "buyingRole": "string — one of: decision-maker, influencer, end-user, technical-evaluator, procurement, executive-sponsor, budget-approver, recommender, champion, gatekeeper",
      "expectedBudget": "${personaBudgetExamples(inputs).expectedBudget}",
      "spendingAuthority": "${personaBudgetExamples(inputs).spendingAuthority}",
      "budgetOwnership": "string — budget ownership, e.g. 'Department Head'",
      "purchaseApprovalLevel": "${personaBudgetExamples(inputs).purchaseApprovalLevel}",
      "objections": ["3-5 common objections"]
    }
  ]
}

IMPORTANT: Generate exactly ${clampedCount} personas. Each must have a DIFFERENT buying role. Prioritise Decision Maker, Champion, and Influencer roles first, then fill remaining slots with Technical Evaluator, Budget Approver, and End User roles.`;

  const userPrompt = `Define ${clampedCount} distinct buyer personas covering different buying roles within this ICP:\n\n${buildContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: Math.min(20000 * clampedCount, 200000) };
}