/**
 * AI Prompt Library for Product Pipeline
 *
 * Generates product data in 3 stages using company context, ICP data,
 * and brand strategy as seed input. Follows the same pattern as FAQ bank prompts.
 */

// ============================================
// TYPES
// ============================================

export interface ProductPipelineInputs {
  // Company context
  companyName: string;
  companyDescription?: string;
  companyIndustry?: string;
  companyBusinessModel?: string;
  companyTargetAudience?: string;
  companyPrimaryOffering?: string;
  companyUsps?: string[];

  // ICP context
  icpName?: string;
  icpIndustry?: string;
  icpCompanySize?: string;
  icpPainPoints?: string[];
  icpBusinessGoals?: string[];

  // Brand strategy context (enrichment)
  brandArchetype?: string;
  brandPersonality?: string[];
  brandValues?: string[];
  brandPositioning?: string;
  brandVoice?: string;

  // Product-specific context
  existingProductNames?: string[];
  productCount?: number;

  // Currency context — every monetary value in the generated content must use
  // this currency. Resolved upstream from the user's selection, falling back to
  // the Business Profile's country (see contentCurrency.ts).
  currency?: string;
  /** The exact price the user entered, expressed in `currency`. */
  price?: number | string;
  /**
   * How the product is sold. Steers the generated pricing narrative: a
   * one-time purchase reads very differently from a subscription, and without
   * this the model defaults to whichever it infers from the description.
   */
  pricingModel?: 'direct' | 'saas';
  /**
   * The subscription terms the user actually entered, when `pricingModel` is
   * 'saas'. Quick Generate collects the same eight fields the Add Product form
   * does; without them the model invented its own tiers, trial lengths and
   * renewal terms and the saved record disagreed with the copy describing it.
   * Every field is optional — only what the user filled in is stated.
   */
  saasPricing?: {
    monthlyPrice?: number;
    yearlyPrice?: number;
    billingCycle?: string;
    setupFee?: number;
    cancellationPeriodDays?: number;
    autoRenewal?: boolean;
    trialAvailable?: boolean;
    trialDurationDays?: number;
  };

  // Quick Generate seed
  shortDescription?: string;

  // Auto Fill inputs
  productName?: string;      // Provided product name to use
  categoryName?: string;      // Category name for context
}

export type PartialProductAnalysis = Record<string, any>;

export interface PromptResult {
  systemPrompt: string;
  userPrompt: string;
  maxTokens: number;
}

// ============================================
// HELPERS
// ============================================

function buildCompanyContext(inputs: ProductPipelineInputs): string {
  const parts: string[] = [];
  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(`USPs: ${inputs.companyUsps.join(', ')}`);

  // ICP context
  if (inputs.icpName) parts.push(`\nICP: ${inputs.icpName}`);
  if (inputs.icpIndustry) parts.push(`ICP Industry: ${inputs.icpIndustry}`);
  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(', ')}`);

  // Brand context
  if (inputs.brandArchetype) parts.push(`\nBrand Archetype: ${inputs.brandArchetype}`);
  if (inputs.brandPersonality?.length) parts.push(`Brand Personality: ${inputs.brandPersonality.join(', ')}`);
  if (inputs.brandValues?.length) parts.push(`Brand Values: ${inputs.brandValues.join(', ')}`);
  if (inputs.brandPositioning) parts.push(`Brand Positioning: ${inputs.brandPositioning}`);
  if (inputs.brandVoice) parts.push(`Brand Voice: ${inputs.brandVoice}`);

  // Pricing currency — keeps every money reference in the generated content
  // aligned with the currency the product is actually sold in.
  if (inputs.currency) {
    const meta = getCurrencyMeta(inputs.currency);
    parts.push(`\nPricing Currency: ${meta.name} (${meta.code}, symbol ${meta.symbol})`);
    if (inputs.price !== undefined && inputs.price !== null && String(inputs.price).trim() !== '') {
      parts.push(`Product Price: ${meta.symbol}${String(inputs.price).trim()} ${meta.code}`);
    }
  }

  // Pricing model — tells the model whether to write one-time purchase pricing
  // or subscription pricing. Omitted entirely when unset, so an existing
  // product with no pricing model produces exactly the prompt it did before.
  if (inputs.pricingModel === 'saas') {
    parts.push(
      '\nPricing Model: SaaS (subscription).',
      'Frame all pricing as a recurring subscription — monthly and/or yearly plans, tiers, trial and renewal terms. Do NOT present it as a one-time purchase.',
    );

    // The user's actual subscription terms. Stated as facts and marked
    // authoritative: left to itself the model invents its own price points and
    // trial lengths, which then contradict the record that gets saved.
    const saas = inputs.saasPricing;
    if (saas) {
      const sym = inputs.currency ? getCurrencyMeta(inputs.currency).symbol : '';
      const terms: string[] = [];
      if (saas.monthlyPrice !== undefined) terms.push(`Monthly price: ${sym}${saas.monthlyPrice}`);
      if (saas.yearlyPrice !== undefined) terms.push(`Yearly price: ${sym}${saas.yearlyPrice}`);
      if (saas.billingCycle) terms.push(`Billing cycle: ${saas.billingCycle}`);
      if (saas.setupFee !== undefined) terms.push(`One-off setup fee: ${sym}${saas.setupFee}`);
      if (saas.cancellationPeriodDays !== undefined) terms.push(`Cancellation notice: ${saas.cancellationPeriodDays} days`);
      if (saas.autoRenewal !== undefined) terms.push(`Auto-renewal: ${saas.autoRenewal ? 'yes' : 'no'}`);
      if (saas.trialAvailable !== undefined) {
        terms.push(saas.trialAvailable
          ? `Free trial: yes${saas.trialDurationDays !== undefined ? ` (${saas.trialDurationDays} days)` : ''}`
          : 'Free trial: no');
      }
      if (terms.length) {
        parts.push(
          'Subscription terms supplied by the user — treat these as authoritative and use them verbatim wherever pricing is mentioned. Do NOT invent different figures, cycles, trial lengths or renewal terms:',
          ...terms.map((t) => `- ${t}`),
        );
      }
    }
  } else if (inputs.pricingModel === 'direct') {
    parts.push(
      '\nPricing Model: Direct Selling (one-time purchase).',
      'Frame all pricing as a single one-time purchase price. Do NOT invent subscription tiers, recurring billing or trials.',
    );
  }

  return parts.join('\n');
}

const JSON_INSTRUCTION = `

IMPORTANT: You MUST respond with ONLY a valid JSON object. Do NOT respond with a bare array. Do NOT include any text before or after the JSON. Do NOT use markdown code fences. The entire response must be a single JSON object like {"key": "value"}.`;

import { formatCharLimitsInstruction, PRODUCT_STRATEGY_LIMITS, PRODUCT_CONTENT_LIMITS, PRODUCT_ENHANCEMENT_LIMITS } from './fieldCharLimits';
import { getCurrencyMeta } from './contentCurrency';

/**
 * Currency directive appended to every stage's system prompt.
 *
 * Without this the model defaults to USD/$ regardless of what the user picked,
 * so prices quoted inside descriptions, benefits and comparisons contradicted
 * the product's own currency field.
 */
export function buildCurrencyInstruction(inputs: ProductPipelineInputs): string {
  const meta = getCurrencyMeta(inputs.currency);
  const priceStr = inputs.price !== undefined && inputs.price !== null && String(inputs.price).trim() !== ''
    ? String(inputs.price).trim()
    : '';

  const priceNote = priceStr
    ? `\n- The product's actual price is ${meta.symbol}${priceStr} (${priceStr} ${meta.code}). Use exactly this figure wherever the price is stated, and base any tier/bundle/ROI maths on it.`
    : '';

  return `

CURRENCY (STRICT): The business prices in ${meta.name} (${meta.code}, symbol "${meta.symbol}").
- Every monetary value you produce — price points, price ranges, tiers, discounts, savings, ROI figures, competitor/pricing comparisons, examples inside descriptions, benefits, use cases and marketing copy — MUST be written in ${meta.code} using the "${meta.symbol}" symbol (e.g. ${meta.example}).
- Do NOT use USD, "$", or any other currency anywhere in the response unless that currency is ${meta.code}.
- Do NOT convert, dual-price, or mention exchange rates. Use ${meta.code} amounts that are realistic for that market — never a USD figure with the ${meta.symbol} symbol swapped in.
- Currency must stay consistent across every field.${priceNote}`;
}

// ============================================
// STAGE 1: Product Strategy
// ============================================

export function buildProductStrategyPrompt(inputs: ProductPipelineInputs): PromptResult {
  const context = buildCompanyContext(inputs);
  const existingProductNote = inputs.existingProductNames?.length
    ? `\nExisting products (avoid duplicating these): ${inputs.existingProductNames.join(', ')}`
    : '';
  const quickGenNote = inputs.shortDescription
    ? `\n\nSEED DESCRIPTION (use this as the foundation for all generated content): "${inputs.shortDescription}"`
    : '';

  // Product name constraint - use provided name or generate one
  const productNameInstruction = inputs.productName
    ? `\n\nIMPORTANT: The product name MUST be exactly "${inputs.productName}". Do NOT generate a new name. Use this exact name for the "name" field.`
    : '';

  // Category context - use category name for better targeting
  const categoryNote = inputs.categoryName
    ? `\n\nCATEGORY: This product belongs to the "${inputs.categoryName}" category. Use this context to inform features, USP, and positioning.`
    : '';

  // The price range must be quoted in the resolved currency — and must echo the
  // user's own price when they supplied one.
  const currencyMeta = getCurrencyMeta(inputs.currency);
  const hasPrice = inputs.price !== undefined && inputs.price !== null && String(inputs.price).trim() !== '';
  const priceRangeInstruction = hasPrice
    ? `The price point stated in ${currencyMeta.code} — it MUST be exactly '${currencyMeta.symbol}${String(inputs.price).trim()}' (add a billing period such as '/month' only if the product is clearly subscription-based)`
    : `A suggested price point or range in ${currencyMeta.code} only (e.g., '${currencyMeta.example}/month', '${currencyMeta.example} one-time', 'Contact for pricing')`;

  const systemPrompt = `You are an expert product strategist for businesses. You create compelling product strategies that align with company positioning, target audience needs, and competitive landscape.${JSON_INSTRUCTION}${buildCurrencyInstruction(inputs)}${formatCharLimitsInstruction(PRODUCT_STRATEGY_LIMITS)}`;

  const userPrompt = `Generate a comprehensive product strategy for a business based on the following context:

${context}${existingProductNote}${quickGenNote}${productNameInstruction}${categoryNote}

${inputs.productCount ? `The business currently has ${inputs.productCount} product(s).` : ''}

Generate a JSON object with these fields:
{
  "name": "A compelling, market-ready product name (short, memorable, descriptive)${inputs.productName ? ` - MUST be exactly "${inputs.productName}"` : ''}",
  "status": "One of: active, draft, discontinued",
  "audienceType": "One of: b2b, b2c, both",
  "usp": "A powerful Unique Selling Proposition (2-3 sentences) that differentiates this product",
  "features": ["5-8 key product features as short strings, each under 80 characters"],
  "primaryKeywords": ["5-10 SEO-relevant keywords for this product"],
  "competitivePositioning": "How this product stands out from competitors (1-2 sentences)",
  "priceRange": "${priceRangeInstruction}"
}`;

  return { systemPrompt, userPrompt, maxTokens: 2000 };
}

// ============================================
// STAGE 2: Product Content
// ============================================

export function buildProductContentPrompt(inputs: ProductPipelineInputs, accumulated: PartialProductAnalysis): PromptResult {
  const context = buildCompanyContext(inputs);
  const strategyNote = accumulated.name ? `\nProduct Name: ${accumulated.name}` : (inputs.productName ? `\nProduct Name: ${inputs.productName}` : '');
  const strategyUsp = accumulated.usp ? `\nUSP: ${accumulated.usp}` : '';
  const strategyFeatures = accumulated.features?.length ? `\nFeatures: ${accumulated.features.join(', ')}` : '';
  const strategyAudience = accumulated.audienceType ? `\nTarget Audience: ${accumulated.audienceType}` : '';
  const quickGenNote = inputs.shortDescription ? `\nOriginal Description Seed: "${inputs.shortDescription}"` : '';
  const categoryNote = inputs.categoryName ? `\nCategory: ${inputs.categoryName}` : '';

  const systemPrompt = `You are an expert product marketer and copywriter. You create compelling product descriptions and marketing content that drives conversions.${JSON_INSTRUCTION}${buildCurrencyInstruction(inputs)}${formatCharLimitsInstruction(PRODUCT_CONTENT_LIMITS)}`;

  const userPrompt = `Generate comprehensive product content based on the following context:

${context}${strategyNote}${strategyUsp}${strategyFeatures}${strategyAudience}${quickGenNote}${categoryNote}

Generate a JSON object with these fields:
{
  "description": "A detailed product description (3-5 paragraphs, 200-500 words) that explains what the product does, who it's for, and why it matters",
  "marketingCopy": "Short-form marketing copy (2-3 paragraphs, 100-200 words) suitable for ads, social media, and landing pages",
  "keyBenefits": ["4-6 key benefits as short strings, each under 100 characters"],
  "useCases": ["3-5 real-world use cases as short strings"],
  "valueProposition": "A concise value proposition statement (1-2 sentences)",
  "elevatorPitch": "A 30-second elevator pitch for this product (1-2 sentences)"
}`;

  return { systemPrompt, userPrompt, maxTokens: 3000 };
}

// ============================================
// STAGE 3: Product Enhancement (SEO + AI readiness)
// ============================================

export function buildProductEnhancementPrompt(inputs: ProductPipelineInputs, accumulated: PartialProductAnalysis): PromptResult {
  const context = buildCompanyContext(inputs);
  const productName = accumulated.name || 'this product';
  const contentSummary = [
    accumulated.usp ? `USP: ${accumulated.usp}` : '',
    accumulated.description ? `Description preview: ${String(accumulated.description).slice(0, 200)}...` : '',
    accumulated.marketingCopy ? `Marketing copy preview: ${String(accumulated.marketingCopy).slice(0, 200)}...` : '',
    accumulated.features?.length ? `Features: ${accumulated.features.slice(0, 5).join(', ')}` : '',
  ].filter(Boolean).join('\n');

  const systemPrompt = `You are an expert SEO strategist and product enhancement specialist. You optimize product listings for search visibility and AI readiness.${JSON_INSTRUCTION}${buildCurrencyInstruction(inputs)}${formatCharLimitsInstruction(PRODUCT_ENHANCEMENT_LIMITS)}`;

  const userPrompt = `Enhance the product "${productName}" with SEO metadata and AI readiness data based on the following context:

${context}

Existing product data:
${contentSummary}

Generate a JSON object with these fields:
{
  "seoTitle": "An SEO-optimized product title (50-60 characters)",
  "seoDescription": "An SEO meta description (150-160 characters) that includes primary keywords",
  "seoKeywords": ["8-12 relevant SEO keywords for this product"],
  "searchIntent": "One of: informational, navigational, transactional, commercial",
  "aiPriority": "One of: critical, high, medium, low",
  "aiContextWeight": "A number from 1-10 indicating how important this product is for AI-generated context",
  "suggestedImprovements": ["2-3 actionable suggestions for improving this product listing"]
}`;

  return { systemPrompt, userPrompt, maxTokens: 2500 };
}

// ============================================
// ENHANCEMENT PROMPT (retry for low-confidence fields)
// ============================================

export function buildProductEnhancementRetryPrompt(
  stageName: string,
  stageOutput: string,
  lowConfidenceFields: string[],
  inputs?: ProductPipelineInputs,
): PromptResult {
  // The retry regenerates real content, so it needs the same currency rules as
  // the stage it is repairing — otherwise the repaired fields drift back to USD.
  const currencyInstruction = inputs ? buildCurrencyInstruction(inputs) : '';
  const systemPrompt = `You are an expert product content enhancer. Improve the specified fields with better quality, more specific, and more actionable content.${JSON_INSTRUCTION}${currencyInstruction}`;

  const userPrompt = `The following product data from the "${stageName}" stage has low-confidence fields that need improvement.

Current output:
${stageOutput}

Fields that need improvement: ${lowConfidenceFields.join(', ')}

Please regenerate ONLY the low-confidence fields with higher quality content, maintaining the same JSON structure:
${lowConfidenceFields.map(f => `"${f}": "improved value"`).join(',\n')}`;

  return { systemPrompt, userPrompt, maxTokens: 1500 };
}