import { prisma } from "../../config/prisma";
import { TaskStatus, ApprovalStage, ApprovalStatus } from "@prisma/client";

export async function getTaskStatsForManager(
  organizationId: string,
  departmentId?: string | null,
) {
  const where: any = { organizationId };
  if (departmentId) where.departmentId = departmentId;

  const [
    total,
    byStatus,
    pendingMyReview,
    sentToClient,
    completed,
    rejectedByMe,
  ] = await Promise.all([
    prisma.task.count({ where }),
    prisma.task.groupBy({ by: ["status"], where, _count: { _all: true } }),
    prisma.task.count({
      where: { ...where, status: TaskStatus.MANAGER_APPROVAL },
    }),
    prisma.task.count({
      where: { ...where, status: TaskStatus.CLIENT_APPROVAL },
    }),
    prisma.task.count({ where: { ...where, status: TaskStatus.COMPLETED } }),
    prisma.taskApproval.count({
      where: {
        stage: ApprovalStage.MANAGER,
        status: ApprovalStatus.REJECTED,
        task: where,
      },
    }),
  ]);

  const statusCounts: Record<string, number> = {};
  for (const status of Object.values(TaskStatus)) statusCounts[status] = 0;
  for (const row of byStatus) statusCounts[row.status] = row._count._all;

  return {
    total,
    pendingMyReview,
    sentToClient,
    completed,
    rejectedByMe,
    byStatus: statusCounts,
  };
}

export async function getDecisionTrendForManager(
  organizationId: string,
  days = 30,
  departmentId?: string | null,
) {
  const now = new Date();
  now.setHours(0, 0, 0, 0);
  const rangeStart = new Date(now);
  rangeStart.setDate(rangeStart.getDate() - (days - 1));

  const taskWhere: any = { organizationId };
  if (departmentId) taskWhere.departmentId = departmentId;

  const decisions = await prisma.taskApproval.findMany({
    where: {
      stage: ApprovalStage.MANAGER,
      actedAt: { gte: rangeStart },
      task: taskWhere,
    },
    select: { status: true, actedAt: true },
  });

  const buckets: {
    key: string;
    label: string;
    approved: number;
    rejected: number;
  }[] = [];
  for (let i = days - 1; i >= 0; i--) {
    const d = new Date(now);
    d.setDate(d.getDate() - i);
    buckets.push({
      key: d.toISOString().slice(0, 10),
      label: d.toLocaleDateString("en-IN", { day: "2-digit", month: "short" }),
      approved: 0,
      rejected: 0,
    });
  }

  const bucketMap = new Map(buckets.map((b) => [b.key, b]));

  for (const decision of decisions) {
    if (!decision.actedAt) continue;
    const bucket = bucketMap.get(decision.actedAt.toISOString().slice(0, 10));
    if (!bucket) continue;
    if (decision.status === ApprovalStatus.APPROVED) bucket.approved += 1;
    if (decision.status === ApprovalStatus.REJECTED) bucket.rejected += 1;
  }

  return buckets.map(({ label, approved, rejected }) => ({
    date: label,
    approved,
    rejected,
  }));
}

export async function getTeamPerformanceForManager(
  organizationId: string,
  departmentId?: string | null,
) {
  const where: any = {
    organizationId,
    status: TaskStatus.COMPLETED,
    assignedEmployeeId: { not: null },
  };
  if (departmentId) where.departmentId = departmentId;

  const tasks = await prisma.task.findMany({
    where,
    select: {
      assignedEmployeeId: true,
      assignedEmployee: { select: { name: true } },
    },
  });

  const countMap = new Map<string, { name: string; completed: number }>();
  for (const t of tasks) {
    if (!t.assignedEmployeeId) continue;
    const existing = countMap.get(t.assignedEmployeeId);
    if (existing) existing.completed += 1;
    else
      countMap.set(t.assignedEmployeeId, {
        name: t.assignedEmployee?.name ?? "Unknown",
        completed: 1,
      });
  }

  return Array.from(countMap.values()).sort(
    (a, b) => b.completed - a.completed,
  );
}
