import prisma from '../config/db.js';
import { getTenantAdminSnapshot } from './organization.model.js';

const DAY_MS = 24 * 60 * 60 * 1000;

function daysUntil(date: Date) {
  return Math.ceil((date.getTime() - Date.now()) / DAY_MS);
}

// GET /dashboard/summary — matches blenaxis-super-admin's DashboardSummary
// exactly. No pagination/params; this scans every organization once, same
// as its own mock implementation did — fine at today's scale, revisit if
// the organization count grows large.
export async function getDashboardSummary() {
  const [organizations, userCounts, projectCounts] = await Promise.all([
    prisma.organization.findMany({ include: { plan: { select: { name: true } } }, orderBy: { createdAt: 'desc' } }),
    prisma.user.groupBy({ by: ['organizationId'], _count: true, where: { organizationId: { not: null } } }),
    prisma.project.groupBy({ by: ['organizationId'], _count: true, where: { organizationId: { not: null } } }),
  ]);

  const usersByOrg = new Map(userCounts.map((row) => [row.organizationId, row._count]));
  const projectsByOrg = new Map(projectCounts.map((row) => [row.organizationId, row._count]));

  const organizationsByStatus: Record<string, number> = { pending: 0, trial: 0, active: 0, suspended: 0 };
  const needsAttention: {
    organizationId: number; organizationName: string;
    kind: 'past_due' | 'trial_ending' | 'invite_pending' | 'near_limit';
    detail: string; since: Date;
  }[] = [];
  let totalUsers = 0;
  let totalProjects = 0;
  let seatsSold = 0;
  let monthlyRecurringRevenue = 0;

  for (const org of organizations) {
    const usage = { maxUsers: usersByOrg.get(org.id) ?? 0, maxProjects: projectsByOrg.get(org.id) ?? 0 };
    organizationsByStatus[org.status] = (organizationsByStatus[org.status] ?? 0) + 1;
    totalUsers += usage.maxUsers;
    totalProjects += usage.maxProjects;
    seatsSold += org.maxUsers;
    if (org.status === 'active') monthlyRecurringRevenue += org.priceMonthly;

    if (org.subscriptionStatus === 'past_due') {
      needsAttention.push({
        organizationId: org.id, organizationName: org.name, kind: 'past_due',
        detail: `${org.plan?.name ?? 'Custom'} · renewal was due`,
        since: org.subscriptionRenewsAt ?? org.updatedAt,
      });
    }
    if (org.status === 'trial' && org.subscriptionRenewsAt && daysUntil(org.subscriptionRenewsAt) <= 7) {
      needsAttention.push({
        organizationId: org.id, organizationName: org.name, kind: 'trial_ending',
        detail: `Trial ends in ${Math.max(0, daysUntil(org.subscriptionRenewsAt))} days`,
        since: org.subscriptionStartsAt ?? org.createdAt,
      });
    }
    const tenantAdmin = await getTenantAdminSnapshot(org.id);
    if (tenantAdmin?.status === 'invited') {
      needsAttention.push({
        organizationId: org.id, organizationName: org.name, kind: 'invite_pending',
        detail: `${tenantAdmin.name} hasn't accepted the invite`,
        since: tenantAdmin.invitedAt,
      });
    }
    if (org.status !== 'suspended' && org.maxUsers > 0 && usage.maxUsers >= org.maxUsers * 0.9) {
      needsAttention.push({
        organizationId: org.id, organizationName: org.name, kind: 'near_limit',
        detail: `${usage.maxUsers} / ${org.maxUsers} users`,
        since: new Date(),
      });
    }
  }

  return {
    totals: {
      organizations: organizations.length,
      activeOrganizations: organizationsByStatus.active,
      users: totalUsers,
      projects: totalProjects,
      monthlyRecurringRevenue,
      currency: 'INR',
    },
    seats: { used: totalUsers, sold: seatsSold },
    organizationsByStatus,
    needsAttention,
    recentOrganizations: organizations.slice(0, 5).map((org) => ({
      id: org.id, name: org.name, planName: org.plan?.name ?? 'Custom', status: org.status, createdAt: org.createdAt,
    })),
  };
}
