import { Request, Response } from "express";
import { sendSuccess, sendPaginated } from "../../common/utils/api-response";
import * as taskService from "./task.service";
import { ApprovalStatus, Priority, TaskStatus } from "@prisma/client";

export async function createTaskWithDocuments(req: Request, res: Response) {
  const files = (req.files as Express.Multer.File[]) ?? [];
  const result = await taskService.createTaskWithDocuments(
    req.user!.id,
    req.body,
    files,
  );
  sendSuccess(res, result, 201);
}

export async function getTasks(req: Request, res: Response) {
  const page = Math.max(1, parseInt(String(req.query.page ?? "1")));
  const limit = Math.min(
    100,
    Math.max(1, parseInt(String(req.query.limit ?? "10"))),
  );
  const search = req.query.search ? String(req.query.search) : "";
  const status = req.query.status as TaskStatus | undefined;
  const priority = req.query.priority as Priority | undefined;
  const { data, total } = await taskService.getTasks(
    req.user!.id,
    page,
    limit,
    search,
    status,
    priority,
  );
  sendPaginated(res, data, total, page, limit, search);
}

export async function clientDecideTask(req: Request, res: Response) {
  const result = await taskService.clientDecideTask(
    req.user!.id,
    req.params.taskId,
    req.body as {
      status: Extract<ApprovalStatus, "APPROVED" | "REJECTED">;
      remarks?: string;
    },
  );
  sendSuccess(res, result);
}

export async function getTask(req: Request, res: Response) {
  const result = await taskService.getTask(req.user!.id, req.params.taskId);
  sendSuccess(res, result);
}

export async function updateTask(req: Request, res: Response) {
  const files = (req.files as Express.Multer.File[]) ?? [];
  const result = await taskService.updateTask(
    req.user!.id,
    req.params.taskId,
    req.body,
    files,
  );
  sendSuccess(res, result);
}

export async function deleteTask(req: Request, res: Response) {
  await taskService.deleteTask(req.user!.id, req.params.taskId);
  sendSuccess(res, { message: "Task deleted successfully" });
}

// ── ADMIN ────────────────────────────────────────────────────

export async function adminGetTasks(req: Request, res: Response) {
  const page = Math.max(1, parseInt(String(req.query.page ?? "1")));
  const limit = Math.min(
    100,
    Math.max(1, parseInt(String(req.query.limit ?? "10"))),
  );
  const { data, total } = await taskService.adminGetTasks(
    req.user!.id,
    page,
    limit,
    {
      status: req.query.status as TaskStatus | undefined,
      search: req.query.search as string | undefined,
      clientId: req.query.clientId as string | undefined,
      departmentId: req.query.departmentId as string | undefined,
      assignedEmployeeId: req.query.assignedEmployeeId as string | undefined,
      priority: req.query.priority as string | undefined,
    },
  );
  sendPaginated(res, data, total, page, limit);
}

export async function adminGetTask(req: Request, res: Response) {
  const result = await taskService.adminGetTask(
    req.user!.id,
    req.params.taskId,
  );
  sendSuccess(res, result);
}

export async function adminUpdateTask(req: Request, res: Response) {
  const result = await taskService.adminUpdateTask(
    req.user!.id,
    req.params.taskId,
    req.body,
  );
  sendSuccess(res, result);
}

export async function adminGetActiveEmployees(req: Request, res: Response) {
  const result = await taskService.adminGetActiveEmployees(req.user!.id);
  sendSuccess(res, result);
}

// get task assigned to employee
export async function getEmployeeTasks(req: Request, res: Response) {
  const page = Math.max(1, Number(req.query.page || 1));
  const limit = Math.min(100, Math.max(1, Number(req.query.limit || 10)));
  const search = req.query.search ? String(req.query.search) : "";
  const status = req.query.status as TaskStatus | undefined;
  const priority = req.query.priority as Priority | undefined;
  const { data, total } = await taskService.getEmployeeTasks(
    req.user!.id,
    page,
    limit,
    search,
    status,
    priority,
  );
  sendPaginated(res, data, total, page, limit, search);
}

export async function getEmployeeTask(req: Request, res: Response) {
  const { taskId } = req.params;
  const task = await taskService.getEmployeeTask(req.user!.id, taskId);
  sendSuccess(res, task);
}

export async function taskApproval(req: Request, res: Response) {
  const result = await taskService.taskApproval(
    req.user!,
    req.params.taskId,
    req.body,
  );

  sendSuccess(res, result);
}
export async function adminDeleteTask(req: Request, res: Response) {
  await taskService.adminDeleteTask(req.user!.id, req.params.taskId);
  sendSuccess(res, { message: "Task deleted successfully" });
}

export async function adminGetActiveClients(req: Request, res: Response) {
  const page = Math.max(1, parseInt(String(req.query.page ?? "1")));
  const limit = Math.min(
    50,
    Math.max(1, parseInt(String(req.query.limit ?? "10"))),
  );
  const search = req.query.search as string | undefined;
  const result = await taskService.adminGetActiveClients(
    req.user!.id,
    search,
    page,
    limit,
  );
  sendPaginated(res, (result as any).data, (result as any).total, page, limit);
}

export async function adminGetEmployeesByDepartment(
  req: Request,
  res: Response,
) {
  const search = req.query.search as string | undefined;
  const result = await taskService.adminGetEmployeesByDepartment(
    req.user!.id,
    req.params.departmentId,
    search,
  );
  sendSuccess(res, result);
}

export async function adminCreateTask(req: Request, res: Response) {
  const files = (req.files as Express.Multer.File[]) ?? [];
  const result = await taskService.adminCreateTask(
    req.user!.id,
    req.body,
    files,
  );
  sendSuccess(res, result, 201);
}

export async function adminGetTaskStats(req: Request, res: Response) {
  const result = await taskService.adminGetTaskStats(req.user!.id);
  sendSuccess(res, result);
}

// Employee task approval
export async function employeeApproveTask(req: Request, res: Response) {
  const result = await taskService.employeeApproveTask(
    req.user!,
    req.params.taskId,
    req.body,
  );
  sendSuccess(res, result);
}

// Manager task approval
export async function getManagerTasks(req: Request, res: Response) {
  const page = Math.max(1, parseInt(String(req.query.page ?? "1")));
  const limit = Math.min(
    100,
    Math.max(1, parseInt(String(req.query.limit ?? "10"))),
  );
  const search = req.query.search ? String(req.query.search) : "";
  const status = req.query.status as TaskStatus | undefined;
  const priority = req.query.priority as Priority | undefined;
  const { data, total } = await taskService.getManagerTasks(
    req.user!.id,
    page,
    limit,
    search,
    status,
    priority,
  );
  sendPaginated(res, data, total, page, limit, search);
}

export async function getManagerTask(req: Request, res: Response) {
  const { taskId } = req.params;
  const task = await taskService.getManagerTask(req.user!.id, taskId);
  sendSuccess(res, task);
}

// manager update the task status and remarks
export async function managerDecideTask(req: Request, res: Response) {
  const result = await taskService.managerDecideTask(
    req.user!.id,
    req.params.taskId,
    req.body as {
      status: Extract<ApprovalStatus, "APPROVED" | "REJECTED">;
      remarks?: string;
    },
  );
  sendSuccess(res, result);
}

export async function getTaskRejections(req: Request, res: Response) {
  const result = await taskService.getTaskRejections(
    req.user!.id,
    req.params.taskId,
  );
  sendSuccess(res, result);
}

export async function getClientRejections(req: Request, res: Response) {
  const result = await taskService.getClientRejections(req.user!.id);
  sendSuccess(res, result);
}
