/**
 * Recommendation Outcome Tracker — measures whether AI recommendations
 * actually improved performance. Feeds success rates back into the AI.
 */

import { prisma } from "@/lib/prisma";

const MIN_SAMPLE_RATES = 10;

export async function trackRecommendationOutcomes(): Promise<number> {
  // Find brands with analysis jobs from 30-90 days ago
  const d30 = new Date(Date.now() - 30 * 86400000);
  const d90 = new Date(Date.now() - 90 * 86400000);

  const analyses = await prisma.analysisJob.findMany({
    where: { status: "completed", createdAt: { gte: d90, lt: d30 } },
    select: { id: true, brandId: true, result: true, createdAt: true },
    take: 50,
  });

  let tracked = 0;
  for (const job of analyses) {
    const brand = await prisma.brand.findUnique({ where: { id: job.brandId }, select: { industry: true } });
    if (!brand?.industry) continue;
    const results = job.result as { recommendations?: Array<{ title?: string; category?: string }> } | null;
    const recs = results?.recommendations ?? [];

    for (const rec of recs.slice(0, 5)) {
      const type = rec.category || "general";
      const existing = await prisma.recommendationOutcome.findFirst({ where: { brandId: job.brandId, recommendationId: job.id, recommendationType: type } });
      if (existing) continue;

      // Measure current state
      let metricAfter: number | null = null;
      let metricBefore: number | null = null;
      const targetMetric = type.includes("ctr") ? "ctr" : type.includes("speed") ? "health" : "clicks";

      if (targetMetric === "clicks") {
        const now30 = await prisma.gscPage.aggregate({ where: { brandId: job.brandId, date: { gte: d30 } }, _sum: { clicks: true } });
        const then30 = await prisma.gscPage.aggregate({ where: { brandId: job.brandId, date: { gte: d90, lt: new Date(d90.getTime() + 30 * 86400000) } }, _sum: { clicks: true } });
        metricAfter = now30._sum.clicks ?? 0;
        metricBefore = then30._sum.clicks ?? 0;
      } else if (targetMetric === "health") {
        const audit = await prisma.technicalAudit.findFirst({ where: { brandId: job.brandId }, orderBy: { createdAt: "desc" }, select: { crawlHealth: true } });
        metricAfter = audit?.crawlHealth ?? null;
      }

      const impactPct = metricBefore && metricAfter ? Math.round(((metricAfter - metricBefore) / metricBefore) * 100) : null;
      const outcome = impactPct == null ? "unknown" : impactPct > 5 ? "improved" : impactPct < -5 ? "declined" : "unchanged";

      await prisma.recommendationOutcome.create({
        data: {
          brandId: job.brandId, recommendationId: job.id, recommendationType: type,
          industry: brand.industry, description: rec.title || type,
          targetMetric, metricBefore, measuredAt: job.createdAt as Date,
          metricAfter, measuredAfterAt: new Date(), outcome, impactPercent: impactPct,
          implemented: outcome === "improved",
        },
      });
      tracked++;
    }
  }
  return tracked;
}

export async function getRecommendationSuccessRates(industry: string): Promise<Array<{ type: string; total: number; implemented: number; improved: number; avgImpact: number }>> {
  const outcomes = await prisma.recommendationOutcome.groupBy({
    by: ["recommendationType"],
    where: { industry },
    _count: true,
  });

  const rates: Array<{ type: string; total: number; implemented: number; improved: number; avgImpact: number }> = [];
  for (const group of outcomes) {
    if (group._count < MIN_SAMPLE_RATES) continue;
    const implemented = await prisma.recommendationOutcome.count({ where: { industry, recommendationType: group.recommendationType, implemented: true } });
    const improved = await prisma.recommendationOutcome.count({ where: { industry, recommendationType: group.recommendationType, outcome: "improved" } });
    const avgImpact = await prisma.recommendationOutcome.aggregate({ where: { industry, recommendationType: group.recommendationType, outcome: "improved", impactPercent: { not: null } }, _avg: { impactPercent: true } });
    rates.push({ type: group.recommendationType, total: group._count, implemented, improved, avgImpact: Math.round((avgImpact._avg.impactPercent ?? 0) * 10) / 10 });
  }
  return rates;
}
