import {
  getContratById,
  getContratByBusinessId,
  listContrats,
  listContratsBySalarie,
  createContrat,
  updateContratById,
  deleteContratById,
} from "@/services/contrats.service";
import { toPublicContract, toPublicContractList } from "@/server/public-entity";
import type { PublicContrat, PublicFeed } from "@/types";
import type { ContratUpdateInput, ContratCreateInput } from "@/validators/contrats";
import type { EmployeeAccessScope } from "@/lib/authorization";

type ContractScopeFields = Pick<
  ContratUpdateInput,
  "ETB" | "Secteur" | "CAT" | "TCS"
>;

function normalizeScopeValue(value: string | null | undefined) {
  return (value ?? "")
    .trim()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/\s+/g, " ")
    .toLocaleUpperCase("fr");
}

function isValueAllowed(
  value: string | null | undefined,
  allowedValues: string[] | undefined,
) {
  if (allowedValues === undefined) return true;

  const normalizedValue = normalizeScopeValue(value);
  return allowedValues.some(
    (allowed) => normalizeScopeValue(allowed) === normalizedValue,
  );
}

export function findForbiddenContractField(
  data: ContractScopeFields,
  scope: EmployeeAccessScope,
) {
  const fields = [
    { field: "ETB", value: data.ETB, allowed: scope.establishments },
    { field: "Secteur", value: data.Secteur, allowed: scope.sectors },
    { field: "CAT", value: data.CAT, allowed: scope.categories },
    { field: "TCS", value: data.TCS, allowed: scope.contractTypes },
  ] as const;

  return fields.find((item) => !isValueAllowed(item.value, item.allowed))?.field;
}

export async function getContratsFeed(
  limit: number,
  offset: number,
  scope: EmployeeAccessScope,
): Promise<PublicFeed<PublicContrat>> {
  const contrats = await listContrats(limit, offset, scope);

  return {
    items: toPublicContractList(contrats),
    count: contrats.length,
  };
}

export async function getContratDetails(id: number): Promise<{ contrat: PublicContrat | null | undefined }> {
  const contrat = await getContratById(id);

  return {
    contrat: toPublicContract(contrat),
  };
}

export async function getContratByBusinessIdFeed(idContrat: number): Promise<{ contrat: PublicContrat | null | undefined }> {
  const contrat = await getContratByBusinessId(idContrat);

  return {
    contrat: toPublicContract(contrat),
  };
}

export async function createContratFeed(data: ContratCreateInput): Promise<{ contrat: PublicContrat | null | undefined }> {
  const contrat = await createContrat(data);

  return {
    contrat: toPublicContract(contrat),
  };
}

export async function updateContratFeed(id: number, data: ContratUpdateInput): Promise<{ contrat: PublicContrat | null | undefined }> {
  const contrat = await updateContratById(id, data);

  return{
    contrat: toPublicContract(contrat),
  };
}

export async function deleteContratFeed(id: number): Promise<{ contrat: PublicContrat | null | undefined }> {
  const contrat = await deleteContratById(id);

  return {
    contrat: toPublicContract(contrat),
  };
}

export async function getContratsBySalarieFeed(
  cos: number
): Promise<PublicFeed<PublicContrat>> {
  const contrats = await listContratsBySalarie(cos);

  return {
    items: toPublicContractList(contrats),
    count: contrats.length,
  };
}
