import { prisma } from "@/lib/prisma";
import { getDateRange, getComparisonRange, DateRange, CompareMode } from "./date-utils";

export type AiPlatform = "chatgpt" | "claude" | "perplexity" | "gemini" | "google_aio";

/**
 * Get AI visibility data for a brand within a date range.
 */
export async function getAiVisibility(
  brandId: string,
  range: DateRange = "30d",
  compare: CompareMode = "previous"
) {
  const { start, end } = getDateRange(range);
  const comp = getComparisonRange(start, end, compare);

  const current = await prisma.aiVisibilitySnapshot.findMany({
    where: { brandId, date: { gte: start, lte: end } },
    orderBy: { date: "asc" },
  });

  const previous = await prisma.aiVisibilitySnapshot.findMany({
    where: { brandId, date: { gte: comp.start, lte: comp.end } },
    orderBy: { date: "asc" },
  });

  // Group by platform
  const byPlatform = groupBy(current, "platform");
  const prevByPlatform = groupBy(previous, "platform");

  const platformSummaries = Object.entries(byPlatform).map(([platform, items]) => {
    const prevItems = prevByPlatform[platform] || [];
    const totalMentions = items.reduce((s, i) => s + i.mentions, 0);
    const prevMentions = prevItems.reduce((s, i) => s + i.mentions, 0);
    const totalCitations = items.reduce((s, i) => s + i.citations, 0);
    const avgScore = items.length > 0 ? Math.round(items.reduce((s, i) => s + i.visibilityScore, 0) / items.length) : 0;

    return {
      platform,
      mentions: totalMentions,
      citations: totalCitations,
      visibilityScore: avgScore,
      mentionChange: totalMentions - prevMentions,
      trend: items.map((i) => ({ date: i.date, mentions: i.mentions, citations: i.citations, score: i.visibilityScore })),
    };
  });

  // Group by topic
  const byTopic = groupBy(current, "topic");
  const topicSummaries = Object.entries(byTopic).map(([topic, items]) => ({
    topic,
    mentions: items.reduce((s, i) => s + i.mentions, 0),
    citations: items.reduce((s, i) => s + i.citations, 0),
    platforms: Array.from(new Set(items.map((i) => i.platform))),
    topSource: items.find((i) => i.sourceUrl)?.sourceUrl || null,
  }));

  // Group by source page
  const byPage = groupBy(current.filter((i) => i.sourceUrl), "sourceUrl");
  const pageSummaries = Object.entries(byPage).map(([page, items]) => ({
    page,
    mentions: items.reduce((s, i) => s + i.mentions, 0),
    citations: items.reduce((s, i) => s + i.citations, 0),
    platforms: Array.from(new Set(items.map((i) => i.platform))),
  }));

  // Totals
  const totalMentions = current.reduce((s, i) => s + i.mentions, 0);
  const prevTotalMentions = previous.reduce((s, i) => s + i.mentions, 0);
  const totalCitations = current.reduce((s, i) => s + i.citations, 0);
  const avgVisibility = current.length > 0 ? Math.round(current.reduce((s, i) => s + i.visibilityScore, 0) / current.length) : 0;

  return {
    period: { start, end, range, compare },
    totals: {
      mentions: totalMentions,
      citations: totalCitations,
      visibilityScore: avgVisibility,
      mentionChange: totalMentions - prevTotalMentions,
      mentionChangePct: prevTotalMentions > 0 ? Math.round(((totalMentions - prevTotalMentions) / prevTotalMentions) * 100) : 0,
    },
    byPlatform: platformSummaries.sort((a, b) => b.mentions - a.mentions),
    byTopic: topicSummaries.sort((a, b) => b.mentions - a.mentions),
    byPage: pageSummaries.sort((a, b) => b.mentions - a.mentions),
  };
}

/**
 * Get recommendation-ready AI visibility insights.
 */
export async function getAiVisibilityRecommendations(brandId: string) {
  const data = await getAiVisibility(brandId, "30d", "previous");
  const recs: Array<{ title: string; detail: string; severity: string; platform?: string }> = [];

  for (const p of data.byPlatform) {
    if (p.mentionChange < 0) {
      recs.push({
        title: `${p.platform} mentions dropped by ${Math.abs(p.mentionChange)}`,
        detail: `Your visibility on ${p.platform} decreased. Consider updating content to match ${p.platform}'s citation patterns.`,
        severity: Math.abs(p.mentionChange) >= 3 ? "high" : "medium",
        platform: p.platform,
      });
    }
  }

  if (data.totals.mentions === 0) {
    recs.push({
      title: "No AI mentions detected",
      detail: "Your brand is not being cited by any tracked AI platform. Add FAQ schema and structured content to improve visibility.",
      severity: "critical",
    });
  }

  const missingPlatforms = ["chatgpt", "claude", "perplexity", "gemini"].filter(
    (p) => !data.byPlatform.some((bp) => bp.platform === p && bp.mentions > 0)
  );
  for (const p of missingPlatforms.slice(0, 2)) {
    recs.push({
      title: `Not visible on ${p}`,
      detail: `Your brand has no mentions on ${p}. Create authoritative content targeting queries ${p} commonly answers.`,
      severity: "medium",
      platform: p,
    });
  }

  return recs;
}

/**
 * Get a condensed summary of AI visibility for a brand.
 * Returns the key highlights in one clean object.
 */
export async function getAiVisibilitySummary(brandId: string, range: DateRange = "30d") {
  const data = await getAiVisibility(brandId, range, "previous");

  // Top platform (most mentions)
  const topPlatform = data.byPlatform.length > 0
    ? { name: data.byPlatform[0].platform, mentions: data.byPlatform[0].mentions, score: data.byPlatform[0].visibilityScore }
    : null;

  // Top topic (most mentions)
  const topTopic = data.byTopic.length > 0
    ? { name: data.byTopic[0].topic, mentions: data.byTopic[0].mentions, platforms: data.byTopic[0].platforms }
    : null;

  // Biggest gain (platform with largest positive change)
  const gains = data.byPlatform.filter((p) => p.mentionChange > 0).sort((a, b) => b.mentionChange - a.mentionChange);
  const biggestGain = gains.length > 0
    ? { platform: gains[0].platform, change: gains[0].mentionChange, currentMentions: gains[0].mentions }
    : null;

  // Biggest drop (platform with largest negative change)
  const drops = data.byPlatform.filter((p) => p.mentionChange < 0).sort((a, b) => a.mentionChange - b.mentionChange);
  const biggestDrop = drops.length > 0
    ? { platform: drops[0].platform, change: drops[0].mentionChange, currentMentions: drops[0].mentions }
    : null;

  // Top cited page
  const topPage = data.byPage.length > 0
    ? { url: data.byPage[0].page, mentions: data.byPage[0].mentions, citations: data.byPage[0].citations }
    : null;

  return {
    period: data.period,
    totalMentions: data.totals.mentions,
    totalCitations: data.totals.citations,
    visibilityScore: data.totals.visibilityScore,
    mentionChange: data.totals.mentionChange,
    mentionChangePct: data.totals.mentionChangePct,
    topPlatform,
    topTopic,
    biggestGain,
    biggestDrop,
    topPage,
    platformCount: data.byPlatform.length,
    topicCount: data.byTopic.length,
  };
}

function groupBy<T>(items: T[], key: keyof T): Record<string, T[]> {
  const result: Record<string, T[]> = {};
  for (const item of items) {
    const k = String(item[key] || "unknown");
    if (!result[k]) result[k] = [];
    result[k].push(item);
  }
  return result;
}
