/**
 * AI module — uses OpenAI GPT-4o-mini (nano model, ~$0.15/1M input tokens)
 * Falls back to smart heuristics when no API key is set
 */

const OPENAI_KEY = process.env.OPENAI_API_KEY
const MODEL = "gpt-4o-mini"

interface ChatMessage {
  role: "system" | "user" | "assistant"
  content: string
}

async function chat(messages: ChatMessage[], maxTokens = 300): Promise<string> {
  if (!OPENAI_KEY) return ""

  try {
    const res = await fetch("https://api.openai.com/v1/chat/completions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${OPENAI_KEY}`,
      },
      body: JSON.stringify({ model: MODEL, messages, max_tokens: maxTokens, temperature: 0.7 }),
    })
    const data = await res.json()
    return data.choices?.[0]?.message?.content || ""
  } catch {
    return ""
  }
}

/**
 * Generate smart amount suggestions based on event context + peer data
 */
export async function suggestAmounts(context: {
  eventName: string
  avgPledge?: number
  medianPledge?: number
  pledgeCount?: number
  topAmount?: number
  currency?: string
}): Promise<{ amounts: number[]; nudge: string; socialProof: string }> {
  const avg = context.avgPledge || 5000 // 50 quid default
  const median = context.medianPledge || avg

  // Smart anchoring: show amounts around the median, biased upward
  const base = Math.round(median / 1000) * 1000 || 5000
  const amounts = [
    Math.max(1000, Math.round(base * 0.5 / 500) * 500),
    base,
    Math.round(base * 2 / 1000) * 1000,
    Math.round(base * 5 / 1000) * 1000,
    Math.round(base * 10 / 1000) * 1000,
    Math.round(base * 20 / 1000) * 1000,
  ].filter((v, i, a) => a.indexOf(v) === i && v >= 500) // dedup, min £5

  // Social proof text
  let socialProof = ""
  if (context.pledgeCount && context.pledgeCount > 3) {
    socialProof = `${context.pledgeCount} people have pledged so far`
    if (context.avgPledge) {
      socialProof += ` · Average £${Math.round(context.avgPledge / 100)}`
    }
  }

  // AI-generated nudge (or fallback)
  let nudge = ""
  if (OPENAI_KEY && context.pledgeCount && context.pledgeCount > 5) {
    nudge = await chat([
      {
        role: "system",
        content: "You write one short, warm, encouraging line (max 12 words) to nudge a charity donor to pledge generously. UK English. No emojis. No pressure.",
      },
      {
        role: "user",
        content: `Event: ${context.eventName}. ${context.pledgeCount} people pledged avg £${Math.round((context.avgPledge || 5000) / 100)}. Generate a nudge.`,
      },
    ], 30)
  }

  if (!nudge) {
    const nudges = [
      "Every pound makes a real difference",
      "Your generosity changes lives",
      "Join others making an impact today",
      "Be part of something meaningful",
    ]
    nudge = nudges[Math.floor(Math.random() * nudges.length)]
  }

  return { amounts: amounts.slice(0, 6), nudge, socialProof }
}

/**
 * Generate a personalized thank-you / reminder message
 */
export async function generateMessage(type: "thank_you" | "reminder_gentle" | "reminder_urgent" | "whatsapp_receipt", vars: {
  donorName?: string
  amount: string
  eventName: string
  reference: string
  orgName?: string
  daysSincePledge?: number
}): Promise<string> {
  const name = vars.donorName?.split(" ")[0] || "there"

  // Templates with AI enhancement
  const templates: Record<string, string> = {
    thank_you: `Thank you${name !== "there" ? `, ${name}` : ""}! Your £${vars.amount} pledge to ${vars.eventName} means the world. Ref: ${vars.reference}`,
    reminder_gentle: `Hi ${name}, just a friendly nudge about your £${vars.amount} pledge to ${vars.eventName}. If you've already paid — thank you! Ref: ${vars.reference}`,
    reminder_urgent: `Hi ${name}, your £${vars.amount} pledge to ${vars.eventName} is still pending after ${vars.daysSincePledge || "a few"} days. We'd love to close this out — every penny counts. Ref: ${vars.reference}`,
    whatsapp_receipt: `🤲 *Pledge Confirmed!*\n\n💷 Amount: £${vars.amount}\n📋 Event: ${vars.eventName}\n🔖 Reference: \`${vars.reference}\`\n\n${name !== "there" ? `Thank you, ${name}!` : "Thank you!"} Your generosity makes a real difference.\n\n_Powered by Pledge Now, Pay Later_`,
  }

  let msg = templates[type] || templates.thank_you

  // Try AI-enhanced version for reminders
  if (OPENAI_KEY && (type === "reminder_gentle" || type === "reminder_urgent")) {
    const aiMsg = await chat([
      {
        role: "system",
        content: `You write short, warm ${type === "reminder_urgent" ? "but firm" : "and gentle"} payment reminder messages for a UK charity. Max 3 sentences. Include the reference number. UK English. Be human, not corporate.`,
      },
      {
        role: "user",
        content: `Donor: ${name}. Amount: £${vars.amount}. Event: ${vars.eventName}. Reference: ${vars.reference}. Days since pledge: ${vars.daysSincePledge || "?"}. Generate the message.`,
      },
    ], 100)
    if (aiMsg) msg = aiMsg
  }

  return msg
}

/**
 * AI-powered fuzzy reference matching for bank reconciliation
 */
export async function smartMatch(bankDescription: string, candidates: Array<{ ref: string; amount: number; donor: string }>): Promise<{
  matchedRef: string | null
  confidence: number
  reasoning: string
}> {
  if (!OPENAI_KEY || candidates.length === 0) {
    return { matchedRef: null, confidence: 0, reasoning: "No AI key or no candidates" }
  }

  const candidateList = candidates.map(c => `${c.ref} (£${(c.amount / 100).toFixed(2)}, ${c.donor || "anonymous"})`).join(", ")

  const result = await chat([
    {
      role: "system",
      content: 'You match bank transaction descriptions to pledge references. Return ONLY valid JSON: {"ref":"MATCHED_REF","confidence":0.0-1.0,"reasoning":"short reason"}. If no match, ref should be null.',
    },
    {
      role: "user",
      content: `Bank description: "${bankDescription}"\nPossible pledge refs: ${candidateList}\n\nWhich pledge reference does this bank transaction match?`,
    },
  ], 80)

  try {
    const parsed = JSON.parse(result)
    return {
      matchedRef: parsed.ref || null,
      confidence: parsed.confidence || 0,
      reasoning: parsed.reasoning || "",
    }
  } catch {
    return { matchedRef: null, confidence: 0, reasoning: "Parse error" }
  }
}

/**
 * Generate event description from a simple prompt
 */
export async function generateEventDescription(prompt: string): Promise<string> {
  if (!OPENAI_KEY) return ""

  return chat([
    {
      role: "system",
      content: "You write concise, compelling charity event descriptions for a UK audience. Max 2 sentences. Warm and inviting.",
    },
    { role: "user", content: prompt },
  ], 60)
}
