import { NextResponse } from "next/server";
import { db } from "@/lib/db";
import { toPersianDigits } from "@/lib/poster";

export const dynamic = "force-dynamic";

const MONTHS_FA = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"];

function lastNMonths(n: number) {
  const arr: { key: string; label: string; year: number; month: number }[] = [];
  const now = new Date();
  for (let i = n - 1; i >= 0; i--) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    arr.push({
      key: `${d.getFullYear()}-${d.getMonth()}`,
      label: MONTHS_FA[d.getMonth()],
      year: d.getFullYear(),
      month: d.getMonth(),
    });
  }
  return arr;
}

export async function GET() {
  const [
    users, movies, series, episodes, tracks, channels,
    payments, allUsers, ads, subscriptions, wallets, auditLogs, securityLogs,
    topMovies, topSeries, searchLogs,
  ] = await Promise.all([
    db.user.count(),
    db.movie.count(),
    db.series.count(),
    db.episode.count(),
    db.musicTrack.count(),
    db.liveChannel.count(),
    db.payment.findMany({ include: { user: true } }),
    db.user.findMany({ select: { id: true, createdAt: true, plan: true, role: true } }),
    db.advertisement.findMany(),
    db.subscription.findMany({ include: { plan: true } }),
    db.wallet.findMany(),
    db.auditLog.count(),
    db.securityLog.count(),
    db.movie.findMany({ orderBy: { views: "desc" }, take: 6, include: { genres: true } }),
    db.series.findMany({ orderBy: { views: "desc" }, take: 6, include: { genres: true } }),
    db.searchLog.findMany({ take: 10, orderBy: { createdAt: "desc" } }),
  ]);

  const totalViews = await db.movie.aggregate({ _sum: { views: true } }).then((r) => r._sum.views ?? 0);

  const paidPayments = payments.filter((p) => p.status === "paid");
  const totalRevenue = paidPayments.reduce((s, p) => s + p.amount, 0);
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
  const yearStart = new Date(today.getFullYear(), 0, 1);

  const revenueToday = paidPayments.filter((p) => new Date(p.createdAt) >= today).reduce((s, p) => s + p.amount, 0);
  const revenueMonth = paidPayments.filter((p) => new Date(p.createdAt) >= monthStart).reduce((s, p) => s + p.amount, 0);
  const revenueYear = paidPayments.filter((p) => new Date(p.createdAt) >= yearStart).reduce((s, p) => s + p.amount, 0);

  const months = lastNMonths(8);

  const revenueByMonth = months.map((m) => ({
    label: m.label,
    revenue: paidPayments
      .filter((p) => {
        const d = new Date(p.createdAt);
        return d.getFullYear() === m.year && d.getMonth() === m.month;
      })
      .reduce((s, p) => s + p.amount, 0),
    subscriptions: subscriptions.filter((s) => {
      const d = new Date(s.startAt);
      return d.getFullYear() === m.year && d.getMonth() === m.month;
    }).length,
  }));

  const usersByMonth = months.map((m) => ({
    label: m.label,
    users: allUsers.filter((u) => {
      const d = new Date(u.createdAt);
      return d.getFullYear() === m.year && d.getMonth() === m.month;
    }).length,
  }));

  // plan distribution
  const planCounts: Record<string, number> = {};
  for (const u of allUsers) planCounts[u.plan] = (planCounts[u.plan] ?? 0) + 1;
  const planDistribution = Object.entries(planCounts).map(([plan, count]) => ({ plan, count }));

  // device/genre distribution for charts
  const genreCounts: Record<string, number> = {};
  for (const m of topMovies) for (const g of m.genres) genreCounts[g.persianName] = (genreCounts[g.persianName] ?? 0) + (m.views || 0);
  const topGenres = Object.entries(genreCounts)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 6)
    .map(([genre, views]) => ({ genre, views }));

  const totalImpressions = ads.reduce((s, a) => s + a.impressions, 0);
  const totalClicks = ads.reduce((s, a) => s + a.clicks, 0);
  const adRevenue = ads.reduce((s, a) => s + a.revenue, 0);

  const activeSubs = subscriptions.filter((s) => s.status === "active").length;
  const paidUsers = new Set(paidPayments.map((p) => p.userId)).size;
  const conversion = users > 0 ? Math.round((paidUsers / users) * 100) : 0;
  const arpu = users > 0 ? Math.round(totalRevenue / users) : 0;

  return NextResponse.json({
    totals: {
      users, movies, series, episodes, tracks, channels,
      totalViews, totalRevenue, revenueToday, revenueMonth, revenueYear,
      activeSubs, paidUsers, conversion, arpu,
      ads: ads.length, totalImpressions, totalClicks, adRevenue,
      auditLogs, securityLogs, wallets: wallets.length,
      totalBalance: wallets.reduce((s, w) => s + w.balance, 0),
    },
    charts: {
      revenueByMonth,
      usersByMonth,
      planDistribution,
      topGenres,
    },
    topContent: {
      movies: topMovies.map((m) => ({ slug: m.slug, title: m.title, persianTitle: m.persianTitle, views: m.views, rating: m.imdbRating })),
      series: topSeries.map((s) => ({ slug: s.slug, title: s.title, persianTitle: s.persianTitle, views: s.views, rating: s.imdbRating })),
    },
    recentPayments: paidPayments.slice(-8).reverse().map((p) => ({
      id: p.id, amount: p.amount, gateway: p.gateway, status: p.status, type: p.type,
      createdAt: p.createdAt, user: { name: p.user.name, email: p.user.email },
    })),
    recentSearches: searchLogs.map((s) => ({ query: s.query, results: s.resultsCount, at: s.createdAt })),
    ads: ads.map((a) => ({
      id: a.id, title: a.title, type: a.type, position: a.position,
      impressions: a.impressions, clicks: a.clicks, revenue: a.revenue,
      ctr: a.impressions > 0 ? Math.round((a.clicks / a.impressions) * 100) : 0, isActive: a.isActive,
    })),
  });
}
