import { type AllocationStatus, type RecurrenceFrequency } from "./enums.js";

export interface RecurrencePattern {
  frequency: RecurrenceFrequency;
  weekdays?: number[];      // 0=Sun..6=Sat — for WEEKLY/BIWEEKLY
  monthDay?: number;        // 1-31 — for MONTHLY
  hoursPerDay?: number;     // override hours on recurring days (for CUSTOM)
  interval?: number;        // week interval (1=weekly, 2=biweekly)
  startDate?: string;       // ISO date — recurrence start (defaults to allocation start)
  endDate?: string;         // ISO date — recurrence end (defaults to allocation end)
}

export interface AllocationMetadata {
  includeSaturday?: boolean;
  recurrence?: RecurrencePattern;
  [key: string]: unknown;
}

export interface DemandRequirementMetadata {
  suggestedResourceId?: string;
  estimateHandoff?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface AssignmentMetadata extends AllocationMetadata {
  estimateHandoff?: Record<string, unknown>;
}

export interface Allocation {
  id: string;
  entityId?: string;
  resourceId: string | null;
  projectId: string;
  startDate: Date;
  endDate: Date;
  hoursPerDay: number;
  percentage: number;
  role: string | null;
  roleId: string | null;
  isPlaceholder: boolean;
  headcount: number;
  dailyCostCents: number;
  status: AllocationStatus;
  metadata: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface AllocationResourceSummary {
  id: string;
  displayName: string;
  eid: string;
  lcrCents: number;
  chapter?: string | null;
  availability?: unknown;
}

export interface AllocationProjectSummary {
  id: string;
  name: string;
  shortCode: string;
  status?: string;
  endDate?: Date | string;
  startDate?: Date | string;
  orderType?: string;
  budgetCents?: number;
  winProbability?: number;
  staffingReqs?: unknown;
  responsiblePerson?: string | null;
}

export interface AllocationRoleSummary {
  id: string;
  name: string;
  color: string | null;
}

export interface DemandRequirementRecord {
  id: string;
  projectId: string;
  startDate: Date;
  endDate: Date;
  hoursPerDay: number;
  percentage: number;
  role: string | null;
  roleId: string | null;
  headcount: number;
  budgetCents: number;
  status: AllocationStatus;
  metadata: DemandRequirementMetadata;
  createdAt: Date;
  updatedAt: Date;
}

export interface AssignmentRecord {
  id: string;
  demandRequirementId?: string | null;
  resourceId: string;
  projectId: string;
  startDate: Date;
  endDate: Date;
  hoursPerDay: number;
  percentage: number;
  role: string | null;
  roleId: string | null;
  dailyCostCents: number;
  status: AllocationStatus;
  metadata: AssignmentMetadata;
  createdAt: Date;
  updatedAt: Date;
}

export interface DemandRequirementRecordWithDetails extends DemandRequirementRecord {
  project?: AllocationProjectSummary;
  roleEntity?: AllocationRoleSummary | null;
  assignments?: AssignmentRecordWithDetails[];
}

export interface AssignmentRecordWithDetails extends AssignmentRecord {
  resource?: AllocationResourceSummary | null;
  project?: AllocationProjectSummary;
  roleEntity?: AllocationRoleSummary | null;
  demandRequirement?: Pick<
    DemandRequirementRecord,
    "id" | "projectId" | "startDate" | "endDate" | "hoursPerDay" | "percentage" | "role" | "roleId" | "headcount" | "status"
  > | null;
}

export interface AllocationWithDetails extends Allocation {
  resource?: AllocationResourceSummary | null;
  project?: AllocationProjectSummary;
  roleEntity?: AllocationRoleSummary | null;
}

export interface AllocationLike {
  id: string;
  entityId?: string;
  resourceId: string | null;
  projectId: string;
  startDate: Date | string;
  endDate: Date | string;
  hoursPerDay: number;
  percentage: number;
  role: string | null;
  roleId: string | null;
  isPlaceholder: boolean;
  headcount: number;
  dailyCostCents: number;
  status: string;
  metadata: unknown;
  createdAt: Date | string;
  updatedAt: Date | string;
  resource?: AllocationResourceSummary | null;
  project?: AllocationProjectSummary;
  roleEntity?: AllocationRoleSummary | null;
}

export type DemandRequirement<TAllocation extends AllocationLike = AllocationWithDetails> =
  Omit<TAllocation, "resourceId" | "isPlaceholder"> & {
    kind: "demand";
    sourceAllocationId: string;
    resourceId: null;
    isPlaceholder: true;
    requestedHeadcount: number;
    unfilledHeadcount: number;
  };

export type Assignment<TAllocation extends AllocationLike = AllocationWithDetails> =
  Omit<TAllocation, "resourceId" | "isPlaceholder"> & {
    kind: "assignment";
    sourceAllocationId: string;
    resourceId: string;
    isPlaceholder: false;
  };

export interface AllocationReadModel<TAllocation extends AllocationLike = AllocationWithDetails> {
  allocations: TAllocation[];
  demands: DemandRequirement<TAllocation>[];
  assignments: Assignment<TAllocation>[];
}
