import { prisma } from "../../config/prisma";
import { TaskStatus } from "@prisma/client";

const PENDING_STATUSES: TaskStatus[] = [
  "PENDING",
  "IN_PROGRESS",
  "EMPLOYEE_DONE",
  "MANAGER_APPROVAL",
  "CLIENT_APPROVAL",
  "FILING_PENDING",
];

const TASK_SELECT = {
  id: true,
  title: true,
  status: true,
  priority: true,
  dueDate: true,
  createdAt: true,
  client: { select: { name: true } },
  service: { select: { name: true } },
  assignedEmployee: { select: { name: true } },
};

export async function getRecentPendingTasks(organizationId: string) {
  return prisma.task.findMany({
    where: { organizationId, status: { in: PENDING_STATUSES } },
    orderBy: { createdAt: "desc" },
    take: 5,
    select: TASK_SELECT,
  });
}

export async function getRecentRejectedTasks(organizationId: string) {
  return prisma.task.findMany({
    where: { organizationId, status: "REJECTED" },
    orderBy: { createdAt: "desc" },
    take: 5,
    select: TASK_SELECT,
  });
}

export async function getAdminDashboardStats(organizationId: string) {
  const [
    totalClients,
    totalEmployees,
    totalManagers,
    totalTasks,
    tasksByStatus,
    clientsByStatus,
    departmentWorkload,
  ] = await Promise.all([
    // Total clients (non-invited)
    prisma.client.count({
      where: { organizationId, status: { not: "INVITED" } },
    }),

    // Total employees (role=EMPLOYEE, active)
    prisma.employee.count({
      where: { organizationId, role: "EMPLOYEE", status: "ACTIVE" },
    }),

    // Total managers (role=MANAGER, active)
    prisma.employee.count({
      where: { organizationId, role: "MANAGER", status: "ACTIVE" },
    }),

    // Total tasks
    prisma.task.count({ where: { organizationId } }),

    // Tasks grouped by status
    prisma.task.groupBy({
      by: ["status"],
      where: { organizationId },
      _count: { _all: true },
    }),

    // Clients grouped by status
    prisma.client.groupBy({
      by: ["status"],
      where: { organizationId },
      _count: { _all: true },
    }),

    // Department workload: tasks per department
    prisma.task.groupBy({
      by: ["departmentId"],
      where: { organizationId, departmentId: { not: null } },
      _count: { _all: true },
    }),
  ]);

  // Build task status map
  const taskStatusMap: Record<string, number> = {};
  for (const s of Object.values(TaskStatus)) taskStatusMap[s] = 0;
  for (const row of tasksByStatus) taskStatusMap[row.status] = row._count._all;

  // Build client status map
  const clientStatusMap: Record<string, number> = {};
  for (const row of clientsByStatus) clientStatusMap[row.status] = row._count._all;

  // Resolve department names
  const deptIds = departmentWorkload
    .map((d) => d.departmentId)
    .filter(Boolean) as string[];

  const departments = deptIds.length
    ? await prisma.department.findMany({
        where: { id: { in: deptIds } },
        select: { id: true, name: true },
      })
    : [];

  const deptNameMap: Record<string, string> = {};
  for (const d of departments) deptNameMap[d.id] = d.name;

  const departmentTaskGraph = departmentWorkload.map((d) => ({
    department: deptNameMap[d.departmentId!] ?? "Unassigned",
    tasks: d._count._all,
  }));

  const pendingTasks =
    (taskStatusMap["PENDING"] ?? 0) +
    (taskStatusMap["IN_PROGRESS"] ?? 0) +
    (taskStatusMap["EMPLOYEE_DONE"] ?? 0) +
    (taskStatusMap["MANAGER_APPROVAL"] ?? 0) +
    (taskStatusMap["CLIENT_APPROVAL"] ?? 0) +
    (taskStatusMap["FILING_PENDING"] ?? 0);

  return {
    cards: {
      totalClients,
      totalEmployees,
      totalManagers,
      totalTasks,
      pendingTasks,
      completedTasks: taskStatusMap["COMPLETED"] ?? 0,
    },
    taskStatusGraph: Object.entries(taskStatusMap).map(([status, count]) => ({
      status,
      count,
    })),
    departmentTaskGraph,
    clientStatusGraph: Object.entries(clientStatusMap).map(([status, count]) => ({
      status,
      count,
    })),
  };
}
