import "server-only";
import { prisma } from "@/lib/prisma";
import type { ProjectStatus, Priority } from "@prisma/client";

export type MilestoneDTO = {
  id: string;
  title: string;
  dueDate: string | null;
  done: boolean;
};

export type ProjectMemberDTO = { id: string; name: string; avatarUrl: string | null };

export type ProjectDTO = {
  id: string;
  key: string;
  name: string;
  description: string | null;
  status: ProjectStatus;
  priority: Priority;
  progress: number;
  color: string | null;
  startDate: string | null;
  deadline: string | null;
  leadId: string | null;
  lead: ProjectMemberDTO | null;
  members: ProjectMemberDTO[];
  memberIds: string[];
  milestones: MilestoneDTO[];
  taskCount: number;
  boardCount: number;
};

const displayName = (u: { name: string; displayName: string | null }) => u.displayName ?? u.name;

export async function getProjects(): Promise<ProjectDTO[]> {
  const rows = await prisma.project.findMany({
    orderBy: [{ status: "asc" }, { createdAt: "desc" }],
    select: {
      id: true,
      key: true,
      name: true,
      description: true,
      status: true,
      priority: true,
      progress: true,
      color: true,
      startDate: true,
      deadline: true,
      leadId: true,
      lead: { select: { id: true, name: true, displayName: true, avatarUrl: true } },
      members: {
        select: { user: { select: { id: true, name: true, displayName: true, avatarUrl: true } } },
      },
      milestones: {
        orderBy: [{ done: "asc" }, { position: "asc" }],
        select: { id: true, title: true, dueDate: true, done: true },
      },
      _count: { select: { tasks: true, boards: true } },
    },
  });

  return rows.map((p) => ({
    id: p.id,
    key: p.key,
    name: p.name,
    description: p.description,
    status: p.status,
    priority: p.priority,
    progress: p.progress,
    color: p.color,
    startDate: p.startDate ? p.startDate.toISOString() : null,
    deadline: p.deadline ? p.deadline.toISOString() : null,
    leadId: p.leadId,
    lead: p.lead
      ? { id: p.lead.id, name: displayName(p.lead), avatarUrl: p.lead.avatarUrl }
      : null,
    members: p.members.map((m) => ({
      id: m.user.id,
      name: displayName(m.user),
      avatarUrl: m.user.avatarUrl,
    })),
    memberIds: p.members.map((m) => m.user.id),
    milestones: p.milestones.map((m) => ({
      id: m.id,
      title: m.title,
      dueDate: m.dueDate ? m.dueDate.toISOString() : null,
      done: m.done,
    })),
    taskCount: p._count.tasks,
    boardCount: p._count.boards,
  }));
}

export async function getProjectUsers(): Promise<ProjectMemberDTO[]> {
  const users = await prisma.user.findMany({
    where: { status: { not: "SUSPENDED" } },
    orderBy: { name: "asc" },
    select: { id: true, name: true, displayName: true, avatarUrl: true },
  });
  return users.map((u) => ({ id: u.id, name: displayName(u), avatarUrl: u.avatarUrl }));
}

export type ProjectTeamDTO = { id: string; name: string; color: string | null; memberIds: string[] };

export async function getProjectTeams(): Promise<ProjectTeamDTO[]> {
  const teams = await prisma.team.findMany({
    orderBy: { name: "asc" },
    select: { id: true, name: true, color: true, members: { select: { userId: true } } },
  });
  return teams.map((t) => ({
    id: t.id,
    name: t.name,
    color: t.color,
    memberIds: t.members.map((m) => m.userId),
  }));
}
