/**
 * AI Prompt Library for Referral Programme Pipeline
 *
 * Generates a complete referral programme in 3 stages:
 * programme identity, structure (rewards/rules/product referrals/strategies), and optimization.
 */

// ============================================
// TYPES
// ============================================

export interface ReferralPipelineInputs {
  /**
   * The user's own brief from the "Generate with AI" popup or the AI Chat
   * generation flow — audience, topics, tone, goals and the chosen data
   * sources. Stated as the highest-priority instruction in the prompt.
   */
  customInstructions?: string;

  companyName: string;
  companyDescription?: string;
  companyIndustry?: string;
  companyBusinessModel?: string;
  companyTargetAudience?: string;
  companyPrimaryOffering?: string;
  companyUsps?: string[];
  brandVoice?: string;
  productNames?: string[];
  productDescriptions?: string[];
  courseTitles?: string[];
  eventTitles?: string[];
}

export type PartialReferralAnalysis = Record<string, any>;

export interface PromptResult {
  systemPrompt: string;
  userPrompt: string;
  maxTokens: number;
}

// ============================================
// HELPERS
// ============================================

function buildCompanyContext(inputs: ReferralPipelineInputs): string {
  const parts: string[] = [];
  // The user's brief goes FIRST and is marked authoritative — it is the one
  // part of the context they typed themselves, so it must win over the derived
  // company/ICP/brand material below when the two disagree.
  if (inputs.customInstructions?.trim()) {
    parts.push(
      `USER BRIEF (highest priority — follow this over the general company context below):\n${inputs.customInstructions.trim()}\n`
    );
  }
  if (inputs.companyName) parts.push(`Company: ${inputs.companyName}`);
  if (inputs.companyDescription) parts.push(`Description: ${inputs.companyDescription}`);
  if (inputs.companyIndustry) parts.push(`Industry: ${inputs.companyIndustry}`);
  if (inputs.companyBusinessModel) parts.push(`Business Model: ${inputs.companyBusinessModel}`);
  if (inputs.companyTargetAudience) parts.push(`Target Audience: ${inputs.companyTargetAudience}`);
  if (inputs.companyPrimaryOffering) parts.push(`Primary Offering: ${inputs.companyPrimaryOffering}`);
  if (inputs.companyUsps?.length) parts.push(`Key USPs: ${inputs.companyUsps.join(', ')}`);
  if (inputs.brandVoice) parts.push(`Brand Voice: ${inputs.brandVoice}`);
  if (inputs.productNames?.length) parts.push(`Products: ${inputs.productNames.join(', ')}`);
  if (inputs.courseTitles?.length) parts.push(`Courses: ${inputs.courseTitles.join(', ')}`);
  if (inputs.eventTitles?.length) parts.push(`Events: ${inputs.eventTitles.join(', ')}`);
  return parts.join('\n');
}

const JSON_INSTRUCTION = '\n\nCRITICAL OUTPUT FORMAT RULES:\n1. Respond with ONLY a single valid JSON object.\n2. Do NOT wrap in markdown code fences (no ```json``` or ``` blocks).\n3. Do NOT include any text, explanation, or commentary before or after the JSON.\n4. Ensure all strings are properly escaped. Ensure all arrays and objects are properly closed.\n5. If the response is too long, reduce detail per item rather than producing broken JSON.';

// ============================================
// STAGE 1: PROGRAMME IDENTITY
// ============================================

export function buildReferralIdentityPrompt(inputs: ReferralPipelineInputs): PromptResult {
  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B referral programme strategist AI. Generate a complete referral programme for the given company. The programme should align with the company's brand, products, and customer base.${JSON_INSTRUCTION}

Your response must match this exact JSON schema:
{
  "programme": {
    "name": "string — compelling programme name, e.g. 'Mengo Referrals'",
    "description": "string — 2-3 sentence programme description",
    "type": "string — one of: single-sided, double-sided, tiered, affiliate, ambassador, custom",
    "referralCodePrefix": "string — short prefix for referral codes, e.g. 'MENGO'",
    "maxReferralsPerUser": "number — max referrals per user, e.g. 50",
    "maxTotalReferrals": "number — max total referrals programme-wide, e.g. 10000",
    "payoutTiming": "string — one of: immediate, on-qualification, monthly, quarterly, annual",
    "settings": {
      "autoApprove": "boolean — whether referrals are auto-approved",
      "requireEmailVerification": "boolean — whether email verification is required",
      "cooldownPeriodDays": "number — cooldown between referrals in days, e.g. 7",
      "fraudPrevention": {
        "level": "string — one of: basic, standard, strict, custom",
        "maxReferralsPerDay": "number — e.g. 5",
        "maxReferralsPerIP": "number — e.g. 3",
        "blockDisposableEmails": "boolean"
      },
      "notifications": {
        "referralSent": "boolean",
        "referralQualified": "boolean",
        "rewardEarned": "boolean",
        "milestoneReached": "boolean"
      },
      "expiryDays": "number — days until referral link expires, e.g. 30",
      "termsUrl": "string — URL or empty string"
    }
  }
}`;

  const userPrompt = `Generate a referral programme for:\n\n${buildCompanyContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 4000 };
}

// ============================================
// STAGE 2: PROGRAMME STRUCTURE
// ============================================

export function buildReferralStructurePrompt(inputs: ReferralPipelineInputs, partial: PartialReferralAnalysis): PromptResult {
  const programmeSummary = [
    partial.programme?.name ? `Programme: ${partial.programme.name}` : '',
    partial.programme?.type ? `Type: ${partial.programme.type}` : '',
    partial.programme?.description ? `Description: ${partial.programme.description}` : '',
  ].filter(Boolean).join('\n');

  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B referral programme architect AI. Generate the programme structure: 4-6 rewards, 3-5 rules, 2-4 product referrals, and strategies.

Keep each field concise — shorter valid JSON is better than longer broken JSON.${JSON_INSTRUCTION}

Your response must match this exact JSON schema:
{
  "rewards": [
    {
      "id": "string — unique ID, e.g. 'rw-1'",
      "name": "string — reward name, e.g. 'Referrer $25 Credit'",
      "type": "string — one of: discount, credit, cash, free-product, upgrade, gift-card, points, custom",
      "description": "string — 1-2 sentence description",
      "referrerReward": { "value": "number — reward value", "valueType": "string — one of: percentage, fixed, points", "description": "string — what the referrer gets" },
      "refereeReward": { "value": "number — reward value", "valueType": "string — one of: percentage, fixed, points", "description": "string — what the referee gets" },
      "tierRestrictions": ["array of tier name strings, or empty for all"],
      "minimumSpend": "number or null — minimum spend to qualify",
      "maximumSpend": "number or null — maximum spend cap",
      "status": "string — one of: draft, active, sold-out, archived",
      "featured": "boolean"
    }
  ],
  "rules": [
    {
      "id": "string — e.g. 'rule-1'",
      "name": "string — rule name, e.g. 'New Signup Bonus'",
      "trigger": "string — one of: signup, purchase, subscription, referral-qualified, milestone, social-share, review",
      "description": "string — 1-2 sentence description",
      "conditions": ["array of condition strings"],
      "rewardReferral": "string — referrer reward description",
      "rewardReferee": "string — referee reward description",
      "qualificationCriteria": ["array of criteria strings"],
      "cap": { "maxPerUser": "number or null", "maxTotal": "number or null" },
      "active": true,
      "priority": "number — e.g. 1, 2, 3"
    }
  ],
  "productReferrals": [
    {
      "id": "string — e.g. 'pr-1'",
      "productId": "string or null",
      "productName": "string — product name from the company's catalog",
      "referralBonus": "string — bonus description, e.g. '15% commission on each sale'",
      "conditions": ["array of condition strings"],
      "active": true
    }
  ],
  "strategies": {
    "channels": ["array of channels — one or more of: email, social, link, qr-code, sms, in-app, affiliate, custom"],
    "targetAudience": "string — target audience description, e.g. 'Existing customers aged 25-45'",
    "messaging": "string — referral messaging strategy, 2-3 sentences",
    "landingPageSuggestions": ["array of 3-4 landing page suggestions"],
    "promotionTips": ["array of 3-4 promotion tips"],
    "referralMilestoneRewards": [
      { "milestone": "string — e.g. '5 referrals'", "reward": "string — e.g. '$50 bonus credit'" }
    ]
  }
}

Generate 4-6 rewards, 3-5 rules, 2-4 product referrals, and strategies. All should be relevant to the company's products and industry.`;

  const userPrompt = `Generate programme structure for:\n\n${programmeSummary}\n\n${buildCompanyContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 6000 };
}

// ============================================
// STAGE 3: PROGRAMME OPTIMIZATION
// ============================================

export function buildReferralStrategyPrompt(inputs: ReferralPipelineInputs, partial: PartialReferralAnalysis): PromptResult {
  const rewardsSummary = (partial.rewards || []).map((r: any, i: number) =>
    `Reward ${i + 1}: ${r.name || 'N/A'} | Type: ${r.type || 'N/A'}`
  ).join('\n');

  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B referral programme strategist AI. Generate programme terms, branding, and optimization data.${JSON_INSTRUCTION}

Your response must match this exact JSON schema:
{
  "programme": {
    "termsConditions": "string — programme terms and conditions, 2-3 paragraphs",
    "privacyPolicy": "string — programme privacy policy, 1-2 paragraphs",
    "primaryColour": "string — hex colour for programme branding, e.g. '#00d4ff'",
    "secondaryColour": "string — hex colour for secondary branding, e.g. '#0d1117'"
  },
  "bestPractices": ["array of 3-5 referral programme best practices"],
  "optimizationTips": ["array of 2-3 tips for maximizing referral engagement"]
}`;

  const userPrompt = `Generate programme strategy for:\n\n${rewardsSummary}\n\n${buildCompanyContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 3000 };
}

// ============================================
// ENHANCEMENT PROMPT
// ============================================

export function buildReferralEnhancementPrompt(
  stageName: string,
  stageOutput: Record<string, any>,
  lowConfidenceFields: string[]
): PromptResult {
  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B referral programme strategist AI performing a refinement pass. The previous analysis for "${stageName}" had low confidence on certain fields. Provide more specific, detailed content for the indicated fields.${JSON_INSTRUCTION}

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.`;

  return { systemPrompt, userPrompt, maxTokens: 3000 };
}