import { DepartmentKey } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { canManageProjects } from "@/lib/projects/persistence";

type CaptureAccessInput = {
  userId: string;
  role?: string;
  department?: string | null;
  initiativeId?: string | null;
  taskId?: string | null;
};

type CaptureAccessResult = {
  ok: boolean;
  status: number;
  error?: string;
  initiativeId: string | null;
  taskId: string | null;
};

export async function validateCaptureAccess(input: CaptureAccessInput): Promise<CaptureAccessResult> {
  let initiativeId = input.initiativeId?.trim() || null;
  const taskId = input.taskId?.trim() || null;

  if (!initiativeId && !taskId) {
    return {
      ok: false,
      status: 400,
      error: "initiativeId or taskId is required.",
      initiativeId: null,
      taskId: null,
    };
  }

  const canManage = canManageProjects(input.role, input.department);

  let taskRecord:
    | {
        id: string;
        initiativeId: string;
        assigneeId: string | null;
      }
    | null = null;

  if (taskId) {
    taskRecord = await prisma.marketingTask.findFirst({
      where: {
        id: taskId,
        initiative: {
          department: DepartmentKey.proyectos,
        },
      },
      select: {
        id: true,
        initiativeId: true,
        assigneeId: true,
      },
    });

    if (!taskRecord) {
      return {
        ok: false,
        status: 404,
        error: "Task not found.",
        initiativeId,
        taskId,
      };
    }

    if (initiativeId && initiativeId !== taskRecord.initiativeId) {
      return {
        ok: false,
        status: 400,
        error: "taskId does not belong to initiativeId.",
        initiativeId,
        taskId,
      };
    }

    initiativeId = taskRecord.initiativeId;
  }

  if (!initiativeId) {
    return {
      ok: false,
      status: 400,
      error: "initiativeId could not be resolved.",
      initiativeId,
      taskId,
    };
  }

  const initiative = await prisma.marketingInitiative.findFirst({
    where: {
      id: initiativeId,
      department: DepartmentKey.proyectos,
    },
    select: {
      id: true,
      ownerId: true,
      contributors: {
        where: { userId: input.userId },
        select: { userId: true },
        take: 1,
      },
      tasks: {
        where: { assigneeId: input.userId },
        select: { id: true },
        take: 1,
      },
    },
  });

  if (!initiative) {
    return {
      ok: false,
      status: 404,
      error: "Initiative not found.",
      initiativeId,
      taskId,
    };
  }

  if (canManage) {
    return {
      ok: true,
      status: 200,
      initiativeId,
      taskId,
    };
  }

  const isProjectsEmployee = input.role === "employee" && input.department === DepartmentKey.proyectos;
  if (!isProjectsEmployee) {
    return {
      ok: false,
      status: 403,
      error: "Forbidden.",
      initiativeId,
      taskId,
    };
  }

  const canUploadForTask = Boolean(taskRecord && taskRecord.assigneeId === input.userId);
  const canUploadForInitiative =
    initiative.ownerId === input.userId || initiative.contributors.length > 0 || initiative.tasks.length > 0;

  if (!canUploadForTask && !canUploadForInitiative) {
    return {
      ok: false,
      status: 403,
      error: "Employees can only upload evidence for their own tasks or assigned projects.",
      initiativeId,
      taskId,
    };
  }

  return {
    ok: true,
    status: 200,
    initiativeId,
    taskId,
  };
}
