import {
  BadRequestError,
  ForbiddenError,
  NotFoundError,
} from "../../common/errors/http-errors";
import * as serviceRepo from "./service.repo";
import { prisma } from "../../config/prisma";

async function getAdminOrg(userId: string) {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: { role: true, organizationId: true },
  });
  if (!user) throw new BadRequestError("User not found");
  if (!["ADMIN", "SUPER_ADMIN", "MANAGER", "EMPLOYEE"].includes(user.role))
    throw new ForbiddenError("Access denied");
  if (!user.organizationId)
    throw new BadRequestError("User has no organization");
  return user.organizationId;
}

async function getAdminOnlyOrg(userId: string) {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: { role: true, organizationId: true },
  });
  console.log("user", user);
  if (!user) throw new BadRequestError("User not found");
  if (!["ADMIN", "SUPER_ADMIN"].includes(user.role))
    throw new ForbiddenError("Only admin can manage services");
  if (!user.organizationId)
    throw new BadRequestError("Admin has no organization");
  return user.organizationId;
}

export async function createService(userId: string, data: any) {
  const organizationId = await getAdminOnlyOrg(userId);
  return serviceRepo.createService(organizationId, data);
}

export async function getAllServices(
  userId: string,
  page: number,
  limit: number,
  search?: string,
  category?: string
) {
  const organizationId = await getAdminOrg(userId);
  const validCategories = [
    "GST",
    "ITR",
    "TDS",
    "AUDIT",
    "ROC",
    "MSME",
    "PAN",
    "TAN",
    "DSC",
    "IEC",
    "TRADEMARK",
    "OTHER",
  ];
  const safeCategory =
    category && validCategories.includes(category)
      ? (category as any)
      : undefined;
  return serviceRepo.findServicesByOrg(
    organizationId,
    page,
    limit,
    search,
    safeCategory
  );
}

export async function getService(userId: string, serviceId: string) {
  const organizationId = await getAdminOrg(userId);
  const service = await serviceRepo.findServiceById(serviceId, organizationId);
  if (!service) throw new NotFoundError("Service not found");
  return service;
}

export async function updateService(
  userId: string,
  serviceId: string,
  data: any
) {
  const organizationId = await getAdminOnlyOrg(userId);
  const service = await serviceRepo.findServiceById(serviceId, organizationId);
  if (!service) throw new NotFoundError("Service not found");
  return serviceRepo.updateServiceById(serviceId, organizationId, data);
}

export async function deleteService(userId: string, serviceId: string) {
  const organizationId = await getAdminOnlyOrg(userId);
  const service = await serviceRepo.findServiceById(serviceId, organizationId);
  if (!service) throw new NotFoundError("Service not found");
  return serviceRepo.deleteServiceById(serviceId);
}

export async function getServicesForClient(userId: string) {
  const client = await prisma.client.findUnique({
    where: { userId },
    select: { organizationId: true },
  });
  if (!client) throw new BadRequestError("Client profile not found");
  return prisma.service.findMany({
    where: { organizationId: client.organizationId },
    orderBy: { name: "asc" },
  });
}

export async function getServiceForClient(userId: string, serviceId: string) {
  const client = await prisma.client.findUnique({
    where: { userId },
    select: { organizationId: true },
  });
  if (!client) throw new BadRequestError("Client profile not found");

  const service = await prisma.service.findFirst({
    where: { id: serviceId, organizationId: client.organizationId },
    include: { serviceDocuments: { orderBy: { name: "asc" } } },
  });
  if (!service) throw new NotFoundError("Service not found");
  return service;
}
