/**
 * Checks whether a resource is already assigned to the same project
 * with overlapping dates. Used to prevent duplicate bookings.
 */

export interface ExistingAssignment {
  id: string;
  resourceId: string;
  projectId: string;
  startDate: Date | string;
  endDate: Date | string;
  status: string;
}

export interface DuplicateCheckResult {
  isDuplicate: boolean;
  conflictingAssignment?: ExistingAssignment;
  message?: string;
}

const ACTIVE_STATUSES = new Set(["CONFIRMED", "ACTIVE", "PROPOSED"]);

function toCalendarParts(value: Date | string): [year: number, month: number, day: number] {
  if (typeof value === "string") {
    const match = value.match(/^(\d{4})-(\d{2})-(\d{2})/u);
    if (match) {
      return [Number(match[1]), Number(match[2]), Number(match[3])];
    }

    const date = new Date(value);
    return [date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate()];
  }

  return [value.getFullYear(), value.getMonth() + 1, value.getDate()];
}

function toCalendarTime(value: Date | string): number {
  const [year, month, day] = toCalendarParts(value);
  return Date.UTC(year, month - 1, day);
}

function formatCalendarDate(value: Date | string): string {
  const [year, month, day] = toCalendarParts(value);
  return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
}

/**
 * Check if assigning a resource to a project with the given dates
 * would create a duplicate (same resource + same project + overlapping dates).
 *
 * @param resourceId - The resource being assigned
 * @param projectId - The project being assigned to
 * @param startDate - Start of the new assignment
 * @param endDate - End of the new assignment
 * @param existingAssignments - All current assignments for this resource
 * @param excludeAssignmentId - Exclude this ID (for updates — don't conflict with self)
 */
export function checkDuplicateAssignment(
  resourceId: string,
  projectId: string,
  startDate: Date | string,
  endDate: Date | string,
  existingAssignments: ExistingAssignment[],
  excludeAssignmentId?: string,
): DuplicateCheckResult {
  const newStart = toCalendarTime(startDate);
  const newEnd = toCalendarTime(endDate);

  for (const existing of existingAssignments) {
    // Skip self (for updates)
    if (excludeAssignmentId && existing.id === excludeAssignmentId) continue;

    // Skip different resource or project
    if (existing.resourceId !== resourceId) continue;
    if (existing.projectId !== projectId) continue;

    // Skip cancelled/inactive
    if (!ACTIVE_STATUSES.has(existing.status)) continue;

    // Check date overlap: existingStart <= newEnd && existingEnd >= newStart
    const existStart = toCalendarTime(existing.startDate);
    const existEnd = toCalendarTime(existing.endDate);

    if (existStart <= newEnd && existEnd >= newStart) {
      const startStr = formatCalendarDate(existing.startDate);
      const endStr = formatCalendarDate(existing.endDate);
      return {
        isDuplicate: true,
        conflictingAssignment: existing,
        message: `Resource is already assigned to this project from ${startStr} to ${endStr}. Consider updating the existing assignment instead.`,
      };
    }
  }

  return { isDuplicate: false };
}
