import { PriorityStatus, Role, TodoStatus } from "@prisma/client";

export type ListParams = {
  page?: number;
  limit?: number;
  search?: string;
  statuses?: string | string[];
  priorities?: string | string[];
  sortBy?: string;
  sortDir?: "asc" | "desc" | string;
  assigneeUserId?: string;
  teamOfManagerId?: string;
};

export type Requester = { id: string; role: Role };

export function parseCsv(value?: string | string[]): string[] {
  if (!value) return [];
  if (Array.isArray(value)) return value.flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
  return value.split(",").map((v) => v.trim()).filter(Boolean);
}

export function buildTodoQuery(params: ListParams, requester: Requester) {
  const page = Math.max(parseInt(String(params.page ?? 1), 10), 1);
  const limit = Math.max(parseInt(String(params.limit ?? 25), 10), 1);
  const search = (params.search ?? "").trim();
  const statuses = parseCsv(params.statuses) as TodoStatus[];
  const priorities = parseCsv(params.priorities) as PriorityStatus[];
  const sortBy = (params.sortBy ?? "") as string;
  const sortDir = String(params.sortDir ?? "asc").toLowerCase() === "desc" ? "desc" : "asc";
  const assigneeUserId = params.assigneeUserId ?? "";
  const teamOfManagerId = params.teamOfManagerId ?? "";

  const where: any = {};
  if (search) {
    where.OR = [
      { title: { contains: search, mode: "insensitive" } },
      { task: { contains: search, mode: "insensitive" } },
    ];
  }
  if (statuses.length) where.status = { in: statuses };
  if (priorities.length) where.priority = { in: priorities };

  const andClauses: any[] = [];
  if (assigneeUserId) andClauses.push({ assignees: { some: { id: assigneeUserId } } });
  if (teamOfManagerId) andClauses.push({ assignees: { some: { managerId: teamOfManagerId } } });

  // Server-side scoping by role
  if (requester.role === Role.ADMIN) {
    andClauses.push({ assignees: { some: { id: requester.id } } });
  } else if (requester.role === Role.MANAGER) {
    andClauses.push({
      OR: [
        { assignees: { some: { id: requester.id } } },
        { assignees: { some: { managerId: requester.id } } },
      ],
    });
  }
  if (andClauses.length) where.AND = [...(where.AND || []), ...andClauses];

  let orderBy: any = undefined;
  if (sortBy) {
    if (sortBy === "title") orderBy = { title: sortDir };
    else if (sortBy === "dueDate") orderBy = { dueDate: sortDir };
    else if (sortBy === "status") orderBy = { status: sortDir };
    else if (sortBy === "priority") orderBy = { priority: sortDir };
    else if (sortBy === "createdAt") orderBy = { createdAt: sortDir };
  }

  return {
    page,
    limit,
    where,
    orderBy,
    skip: (page - 1) * limit,
    take: limit,
  } as const;
}
