/**
 * 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 toTime(d: Date | string): number {
  const dt = typeof d === "string" ? new Date(d) : d;
  dt.setHours(0, 0, 0, 0);
  return dt.getTime();
}

/**
 * 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 = toTime(startDate);
  const newEnd = toTime(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 = toTime(existing.startDate);
    const existEnd = toTime(existing.endDate);

    if (existStart <= newEnd && existEnd >= newStart) {
      const startStr = new Date(existing.startDate).toISOString().slice(0, 10);
      const endStr = new Date(existing.endDate).toISOString().slice(0, 10);
      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 };
}
