/**
 * AI Prompt Library for Loyalty Programme Pipeline
 *
 * Generates a complete loyalty programme in 3 stages:
 * programme identity, structure (tiers/rules/rewards), and optimization.
 */

// ============================================
// TYPES
// ============================================

export interface LoyaltyPipelineInputs {
  /**
   * 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 PartialLoyaltyAnalysis = Record<string, any>;

export interface PromptResult {
  systemPrompt: string;
  userPrompt: string;
  maxTokens: number;
}

// ============================================
// HELPERS
// ============================================

function buildCompanyContext(inputs: LoyaltyPipelineInputs): 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 buildLoyaltyIdentityPrompt(inputs: LoyaltyPipelineInputs): PromptResult {
  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B loyalty programme strategist AI. Generate a complete loyalty 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 Rewards'",
    "description": "string — 2-3 sentence programme description",
    "type": "string — one of: points-based, tiered, cashback, punch-card, coalition, hybrid, custom",
    "baseEarnRate": "number — base earn rate (points per currency unit), e.g. 1",
    "settings": {
      "currency": "string — e.g. 'USD'",
      "pointsName": "string — custom points name, e.g. 'Stars', 'Credits'",
      "pointsPerCurrency": "number — e.g. 1",
      "pointsExpiry": { "enabled": "boolean", "months": "number — e.g. 12", "warningDays": "number — e.g. 30" },
      "tierDowngrade": { "enabled": "boolean", "period": "string — one of: yearly, quarterly, monthly", "retainPercentage": "number 0-100" },
      "pointsTransfer": { "enabled": "boolean", "fee": "number or null", "minAmount": "number or null", "maxAmount": "number or null" },
      "fraudPrevention": { "maxPointsPerDay": "number — e.g. 10000", "suspiciousActivityThreshold": "number — e.g. 50000" },
      "integrations": { "channels": ["array of: pos, ecommerce, mobile-app, kiosk, web"] }
    }
  }
}`;

  const userPrompt = `Generate a loyalty programme for:\n\n${buildCompanyContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 40000 };
}

// ============================================
// STAGE 2: PROGRAMME STRUCTURE
// ============================================

export function buildLoyaltyStructurePrompt(inputs: LoyaltyPipelineInputs, partial: PartialLoyaltyAnalysis): 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 loyalty programme architect AI. Generate the programme structure: 3-4 tiers, 3-5 earn rules, 3-5 redeem rules, and 4-6 rewards.

Keep each field concise — shorter valid JSON is better than longer broken JSON.${JSON_INSTRUCTION}

Your response must match this exact JSON schema:
{
  "tiers": [
    {
      "id": "string — unique ID, e.g. 'tier-1'",
      "name": "string — tier name, e.g. 'Silver'",
      "level": "number — tier level, starting from 1",
      "minPoints": "number — minimum points to qualify",
      "maxPoints": "number or null — max points for this tier, null for highest",
      "colour": "string — hex colour, e.g. '#C0C0C0'",
      "description": "string — 1-2 sentence tier description",
      "earnMultiplier": "number — earn multiplier, e.g. 1, 1.5, 2",
      "benefits": [
        { "id": "string — e.g. 'tier1-b1'", "name": "string — benefit name", "description": "string", "type": "string — one of: discount, free-shipping, priority-support, exclusive-access, bonus-points, perk, custom", "value": "number", "unit": "string — one of: percentage, fixed, points, item" }
      ],
      "perks": ["array of perk descriptions as strings"]
    }
  ],
  "earnRules": [
    {
      "id": "string — e.g. 'er-1'",
      "name": "string — rule name, e.g. 'Purchase Points'",
      "description": "string — 1-2 sentence description",
      "trigger": "string — one of: purchase, action, referral, social-share, review, birthday, anniversary, signup, milestone",
      "calculation": "string — one of: fixed, percentage, multiplier, custom",
      "value": "number — earn value",
      "cap": { "daily": "number or null", "weekly": "number or null", "monthly": "number or null", "perTransaction": "number or null" },
      "active": true,
      "priority": "number — e.g. 1, 2, 3"
    }
  ],
  "redeemRules": [
    {
      "id": "string — e.g. 'rr-1'",
      "name": "string — rule name, e.g. 'Free Product Voucher'",
      "description": "string — 1-2 sentence description",
      "type": "string — one of: discount, product, voucher, experience, cash-equivalent, donation, upgrade",
      "pointsCost": "number — points required to redeem",
      "value": "number — redemption value",
      "valueUnit": "string — one of: percentage, fixed, item",
      "active": true
    }
  ],
  "rewards": [
    {
      "id": "string — e.g. 'rw-1'",
      "name": "string — reward name",
      "description": "string — 1-2 sentence description",
      "type": "string — one of: discount, free-product, upgrade, experience, gift-card, donation, voucher",
      "pointsRequired": "number — points to claim",
      "cashValue": "number — approximate cash value",
      "tierRestrictions": ["array of tier IDs that can access, or empty for all"],
      "status": "string — one of: draft, active, sold-out, archived",
      "featured": "boolean"
    }
  ],
  "notifications": [
    {
      "id": "string — e.g. 'ntf-1'",
      "type": "string — one of: points-earned, points-expiring, tier-upgrade, tier-downgrade, reward-available, milestone, welcome, birthday",
      "triggers": ["array of trigger strings"],
      "active": true
    }
  ]
}

Generate 3-4 tiers (Bronze/Silver/Gold/Platinum pattern), 3-5 earn rules, 3-5 redeem rules, 4-6 rewards, and 3-4 notifications. 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: 60000 };
}

// ============================================
// STAGE 3: PROGRAMME OPTIMIZATION
// ============================================

export function buildLoyaltyStrategyPrompt(inputs: LoyaltyPipelineInputs, partial: PartialLoyaltyAnalysis): PromptResult {
  const tiersSummary = (partial.tiers || []).map((t: any, i: number) =>
    `Tier ${i + 1}: ${t.name || 'N/A'} | Level: ${t.level || 'N/A'} | Min Points: ${t.minPoints || 'N/A'}`
  ).join('\n');

  const systemPrompt = `RESPOND WITH ONLY VALID JSON. No markdown, no explanation, no code fences.

You are a B2B loyalty 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. '#7C6BF0'",
    "secondaryColour": "string — hex colour for secondary branding, e.g. '#4ECDC4'"
  },
  "bestPractices": ["array of 3-5 loyalty programme best practices"],
  "optimizationTips": ["array of 2-3 tips for maximizing programme engagement"]
}`;

  const userPrompt = `Generate programme strategy for:\n\n${tiersSummary}\n\n${buildCompanyContext(inputs)}`;

  return { systemPrompt, userPrompt, maxTokens: 30000 };
}

// ============================================
// ENHANCEMENT PROMPT
// ============================================

export function buildLoyaltyEnhancementPrompt(
  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 loyalty 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: 30000 };
}