import type { WeekdayAvailability } from "../types/resource.js";

export const DISPO_RESOURCE_CHAPTER_BY_TOKEN = {
  "2D": "Digital Content Production",
  "3D": "Digital Content Production",
  PM: "Project Management",
  AD: "Art Direction",
} as const;

export const DISPO_ASSIGNMENT_ROLE_BY_TOKEN = {
  "2D": "2D Artist",
  "3D": "3D Artist",
  PM: "Project Manager",
  AD: "Art Director",
} as const;

export const DISPO_UTILIZATION_CODE_BY_TOKEN = {
  CH: "Chg",
  MO: "M&O",
  MD: "MD&I",
  PD: "PD&R",
  AB: "Absence",
  NA: "Absence",
  UN: null,
} as const;

export const DISPO_UTILIZATION_CATEGORIES = [
  {
    code: "Chg",
    name: "Chargeable",
    description: "Billable client project work",
    sortOrder: 1,
    isDefault: true,
  },
  {
    code: "BD",
    name: "Business Development",
    description: "Sales, proposals, presales activities",
    sortOrder: 2,
    isDefault: false,
  },
  {
    code: "MD&I",
    name: "Market Development & Initiatives",
    description: "R&D, innovation, market development",
    sortOrder: 3,
    isDefault: false,
  },
  {
    code: "M&O",
    name: "Management & Operations",
    description: "Internal admin, management overhead",
    sortOrder: 4,
    isDefault: false,
  },
  {
    code: "PD&R",
    name: "People Development & Recruitment",
    description: "Training, hiring, onboarding",
    sortOrder: 5,
    isDefault: false,
  },
  {
    code: "Absence",
    name: "Absence & Non Standard",
    description: "Vacation, illness, non-standard leave (reduces SAH)",
    sortOrder: 6,
    isDefault: false,
  },
] as const;

export const DISPO_INTERNAL_PROJECT_BUCKETS = [
  {
    sourceToken: "MO",
    shortCode: "INT-MO",
    name: "Management & Operations",
    utilizationCategoryCode: "M&O",
  },
  {
    sourceToken: "MD",
    shortCode: "INT-MD",
    name: "Market Development & Initiatives",
    utilizationCategoryCode: "MD&I",
  },
  {
    sourceToken: "PD",
    shortCode: "INT-PD",
    name: "People Development & Recruitment",
    utilizationCategoryCode: "PD&R",
  },
] as const;

export const DISPO_REQUIRED_ROLE_SEEDS = [
  {
    name: "2D Artist",
    description: "Canonical Dispo assignment role for 2D delivery work",
  },
  {
    name: "3D Artist",
    description: "Canonical Dispo assignment role for 3D delivery work",
  },
  {
    name: "Project Manager",
    description: "Canonical Dispo assignment role for project management delivery",
  },
  {
    name: "Art Director",
    description: "Canonical Dispo assignment role for art direction delivery",
  },
] as const;

export type DispoRoleToken = keyof typeof DISPO_ASSIGNMENT_ROLE_BY_TOKEN;
export type DispoChapterToken = keyof typeof DISPO_RESOURCE_CHAPTER_BY_TOKEN;
export type DispoUtilizationToken = keyof typeof DISPO_UTILIZATION_CODE_BY_TOKEN;
export type DispoInternalBucketDefinition = (typeof DISPO_INTERNAL_PROJECT_BUCKETS)[number];

function normalizeDispoTokenValue(value: string): string {
  return value.trim().replace(/\s+/g, " ").toUpperCase();
}

function roundToTwoDecimals(value: number): number {
  return Math.round(value * 100) / 100;
}

export function normalizeCanonicalResourceIdentity(value: string): string {
  return value.trim().toLowerCase();
}

export function resolveCanonicalResourceIdentity(enterpriseId?: string | null, eid?: string | null) {
  const normalizedEnterpriseId = enterpriseId ? normalizeCanonicalResourceIdentity(enterpriseId) : null;
  const normalizedEid = eid ? normalizeCanonicalResourceIdentity(eid) : null;
  const conflict = Boolean(
    normalizedEnterpriseId &&
      normalizedEid &&
      normalizedEnterpriseId !== normalizedEid,
  );

  return {
    canonicalId: conflict ? null : normalizedEnterpriseId ?? normalizedEid,
    normalizedEnterpriseId,
    normalizedEid,
    conflict,
  };
}

export function normalizeDispoChapterToken(token?: string | null): string | null {
  if (!token) return null;
  const normalizedToken = normalizeDispoTokenValue(token) as DispoChapterToken;
  return DISPO_RESOURCE_CHAPTER_BY_TOKEN[normalizedToken] ?? null;
}

export function normalizeDispoRoleToken(token?: string | null): string | null {
  if (!token) return null;
  const normalizedToken = normalizeDispoTokenValue(token) as DispoRoleToken;
  return DISPO_ASSIGNMENT_ROLE_BY_TOKEN[normalizedToken] ?? null;
}

export function normalizeDispoUtilizationToken(token?: string | null): string | null {
  if (!token) return null;
  const normalizedToken = normalizeDispoTokenValue(token) as DispoUtilizationToken;
  return DISPO_UTILIZATION_CODE_BY_TOKEN[normalizedToken] ?? null;
}

export function createWeekdayAvailabilityFromFte(
  fte: number,
  dailyWorkingHours = 8,
): WeekdayAvailability {
  const safeFte = Math.min(Math.max(fte, 0), 1);
  const hoursPerDay = roundToTwoDecimals(dailyWorkingHours * safeFte);

  return {
    monday: hoursPerDay,
    tuesday: hoursPerDay,
    wednesday: hoursPerDay,
    thursday: hoursPerDay,
    friday: hoursPerDay,
  };
}
