import type {
  EstimateExportFormat,
  EstimateStatus,
  EstimateVersionStatus,
} from "./enums.js";

export type EstimateDemandLineRateMode = "resource" | "manual";

export interface EstimateDemandLineCalculationMetadata {
  costRateMode: EstimateDemandLineRateMode;
  billRateMode: EstimateDemandLineRateMode;
  totalMode: "computed";
  liveCostRateCents?: number | null;
  liveBillRateCents?: number | null;
  liveCurrency?: string | null;
}

export interface EstimateDemandLineMetadata extends Record<string, unknown> {
  calculation?: EstimateDemandLineCalculationMetadata;
}

export interface Estimate {
  id: string;
  projectId?: string | null;
  name: string;
  opportunityId?: string | null;
  baseCurrency: string;
  status: EstimateStatus;
  latestVersionNumber: number;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateVersion {
  id: string;
  estimateId: string;
  versionNumber: number;
  label?: string | null;
  status: EstimateVersionStatus;
  notes?: string | null;
  lockedAt?: Date | null;
  projectSnapshot: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateAssumption {
  id: string;
  estimateVersionId: string;
  category: string;
  key: string;
  label: string;
  valueType: string;
  value: unknown;
  sortOrder: number;
  notes?: string | null;
  createdAt: Date;
  updatedAt: Date;
}

export interface ScopeItem {
  id: string;
  estimateVersionId: string;
  sequenceNo: number;
  scopeType: string;
  packageCode?: string | null;
  name: string;
  description?: string | null;
  scene?: string | null;
  page?: string | null;
  location?: string | null;
  assumptionCategory?: string | null;
  technicalSpec: Record<string, unknown>;
  frameCount?: number | null;
  itemCount?: number | null;
  unitMode?: string | null;
  internalComments?: string | null;
  externalComments?: string | null;
  sortOrder: number;
  metadata: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateDemandLine {
  id: string;
  estimateVersionId: string;
  scopeItemId?: string | null;
  roleId?: string | null;
  resourceId?: string | null;
  lineType: string;
  name: string;
  chapter?: string | null;
  hours: number;
  days?: number | null;
  fte?: number | null;
  rateSource?: string | null;
  costRateCents: number;
  billRateCents: number;
  currency: string;
  costTotalCents: number;
  priceTotalCents: number;
  monthlySpread: Record<string, number>;
  staffingAttributes: Record<string, unknown>;
  metadata: EstimateDemandLineMetadata;
  createdAt: Date;
  updatedAt: Date;
}

export interface RateCard {
  id: string;
  name: string;
  currency: string;
  effectiveFrom?: Date | null;
  effectiveTo?: Date | null;
  source?: string | null;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

export interface RateCardLine {
  id: string;
  rateCardId: string;
  roleId?: string | null;
  chapter?: string | null;
  location?: string | null;
  seniority?: string | null;
  workType?: string | null;
  serviceGroup?: string | null;
  costRateCents: number;
  billRateCents?: number | null;
  machineRateCents?: number | null;
  attributes: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface ResourceCostSnapshot {
  id: string;
  estimateVersionId: string;
  resourceId?: string | null;
  sourceEid?: string | null;
  displayName: string;
  chapter?: string | null;
  roleId?: string | null;
  currency: string;
  lcrCents: number;
  ucrCents: number;
  fte?: number | null;
  location?: string | null;
  country?: string | null;
  level?: string | null;
  workType?: string | null;
  attributes: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateMetric {
  id: string;
  estimateVersionId: string;
  key: string;
  label: string;
  metricGroup?: string | null;
  valueDecimal: number;
  valueCents?: number | null;
  currency?: string | null;
  metadata: Record<string, unknown>;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateExportSummary {
  estimateId: string;
  estimateName: string;
  versionId: string;
  versionNumber: number;
  versionStatus: EstimateVersionStatus;
  projectId?: string | null;
  projectName?: string | null;
  baseCurrency: string;
  assumptionCount: number;
  scopeItemCount: number;
  demandLineCount: number;
  resourceSnapshotCount: number;
  totalHours: number;
  totalCostCents: number;
  totalPriceCents: number;
  marginCents: number;
  marginPercent: number;
}

export interface EstimateExportArtifactPayload {
  schemaVersion: number;
  format: EstimateExportFormat;
  mimeType: string;
  encoding: "utf8" | "base64";
  fileExtension: string;
  generatedAt: string;
  byteLength: number;
  rowCount?: number | null;
  lineCount?: number | null;
  sheetNames?: string[];
  previewText?: string | null;
  content: string;
  summary: EstimateExportSummary;
}

export interface EstimateExport {
  id: string;
  estimateVersionId: string;
  format: EstimateExportFormat;
  fileName: string;
  storageKey?: string | null;
  payload?: EstimateExportArtifactPayload | Record<string, unknown> | null;
  createdAt: Date;
  updatedAt: Date;
}

export interface EstimateDemandSummary {
  totalHours: number;
  totalCostCents: number;
  totalPriceCents: number;
  marginCents: number;
  marginPercent: number;
}

export interface EstimatePlanningHandoffAllocationRef {
  id: string;
  projectId: string;
  resourceId?: string | null;
  isPlaceholder: boolean;
}

// --- Experience Multipliers ---

export interface ExperienceMultiplierRule {
  id: string;
  multiplierSetId: string;
  chapter?: string | null;
  location?: string | null;
  level?: string | null;
  costMultiplier: number;
  billMultiplier: number;
  shoringRatio?: number | null;
  additionalEffortRatio?: number | null;
  description?: string | null;
  sortOrder: number;
}

export interface ExperienceMultiplierSet {
  id: string;
  name: string;
  description?: string | null;
  isDefault: boolean;
  rules: ExperienceMultiplierRule[];
  createdAt: Date;
  updatedAt: Date;
}

export interface RateAdjustmentInput {
  costRateCents: number;
  billRateCents: number;
  hours: number;
  chapter?: string | null;
  location?: string | null;
  level?: string | null;
}

export interface RateAdjustmentResult {
  adjustedCostRateCents: number;
  adjustedBillRateCents: number;
  adjustedHours: number;
  appliedRules: string[];
}

// --- Effort Rules ---

export type EffortUnitMode = "per_frame" | "per_item" | "flat";

export interface EffortRule {
  id: string;
  ruleSetId: string;
  scopeType: string;
  discipline: string;
  chapter?: string | null;
  unitMode: EffortUnitMode;
  hoursPerUnit: number;
  description?: string | null;
  sortOrder: number;
}

export interface EffortRuleSet {
  id: string;
  name: string;
  description?: string | null;
  isDefault: boolean;
  rules: EffortRule[];
  createdAt: Date;
  updatedAt: Date;
}

export interface EffortRuleExpandedLine {
  scopeItemName: string;
  scopeType: string;
  discipline: string;
  chapter?: string | null;
  hours: number;
  unitMode: EffortUnitMode;
  unitCount: number;
  hoursPerUnit: number;
}

export interface EffortRuleExpansionResult {
  lines: EffortRuleExpandedLine[];
  warnings: string[];
  unmatchedScopeItems: string[];
}

export type PhasingPattern = "even" | "front_loaded" | "back_loaded" | "custom";

export interface WeeklyPhasingConfig {
  startDate: string;
  endDate: string;
  pattern: PhasingPattern;
}

// --- Commercial Terms ---

export type PricingModel = "fixed_price" | "time_and_materials" | "hybrid";

export interface PaymentMilestone {
  label: string;
  percent: number;
  dueDate?: string | null;
  description?: string | null;
}

export interface CommercialTerms {
  pricingModel: PricingModel;
  contingencyPercent: number;
  discountPercent: number;
  paymentTermDays: number;
  paymentMilestones: PaymentMilestone[];
  warrantyMonths: number;
  notes?: string | null;
}

export interface CommercialTermsSummary {
  baseCostCents: number;
  basePriceCents: number;
  contingencyCents: number;
  discountCents: number;
  adjustedCostCents: number;
  adjustedPriceCents: number;
  adjustedMarginCents: number;
  adjustedMarginPercent: number;
}

export interface EstimatePlanningHandoffResult {
  estimateId: string;
  estimateVersionId: string;
  estimateVersionNumber: number;
  projectId: string;
  createdCount: number;
  placeholderCount: number;
  assignedCount: number;
  fallbackPlaceholderCount: number;
  allocations: EstimatePlanningHandoffAllocationRef[];
}
