import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index } from 'typeorm';

export const FEE_RULE_TYPES = [
  'STORAGE_FEE',
  'DEMURRAGE_FEE',
  'DOUBLE_HANDLING_FEE',
  'TRUCK_DETENTION_FEE',
] as const;
export type FeeRuleType = (typeof FEE_RULE_TYPES)[number];

/**
 * Charge basis for a DOUBLE_HANDLING_FEE rule (flat rate × the chosen quantity):
 *  - PER_CONTAINER: booking container count
 *  - PER_TON:  cargo total in tonnes (bulk cargo)
 *  - PER_ITEM: cargo total item count (break-bulk cargo, e.g. machinery)
 */
export const FEE_RULE_BASES = ['PER_CONTAINER', 'PER_TON', 'PER_ITEM'] as const;
export type FeeRuleBasis = (typeof FEE_RULE_BASES)[number];

export interface WarehouseFeeTier {
  fromDay: number;
  toDay: number | null;
  ratePerDay: number;
}

/**
 * Batch 5 — configurable storage / demurrage fee rules (no invoice/payment here — that is Batch 6).
 * The most specific active rule (highest `specificity` then lowest `priority`) applies to an item.
 * `freeDays` is the grace period; charging starts the day after it expires.
 */
@Entity({ schema: 'freight', name: 'warehouse_fee_rules' })
@Index(['ruleType'])
@Index(['isActive'])
export class WarehouseFeeRule extends BaseEntity {
  @Column({ name: 'name', type: 'varchar', length: 160 })
  name!: string;

  @Column({ name: 'rule_type', type: 'varchar', length: 20 })
  ruleType!: FeeRuleType;

  @Column({ name: 'priority', type: 'int', default: 100 })
  priority!: number;

  // ── Scope (null = applies to all) ─────────────────────────────────────────
  @Column({ name: 'freight_type', type: 'varchar', length: 16, nullable: true })
  freightType?: string | null; // CONTAINER | BULK

  @Column({ name: 'trade_direction', type: 'varchar', length: 16, nullable: true })
  tradeDirection?: string | null; // IMPORT | EXPORT | DOMESTIC | BOTH

  @Column({ name: 'cargo_type_code', type: 'varchar', length: 50, nullable: true })
  cargoTypeCode?: string | null;

  @Column({ name: 'container_type', type: 'varchar', length: 40, nullable: true })
  containerType?: string | null;

  // Truck detention only: scope by vehicle type (TRUCK | VAN | TRAILER | TANKER
  // | FLATBED | …). Null = any truck type.
  @Column({ name: 'vehicle_type', type: 'varchar', length: 20, nullable: true })
  vehicleType?: string | null;

  @Column({ name: 'facility_id', type: 'uuid', nullable: true })
  facilityId?: string | null;

  @Column({ name: 'warehouse_id', type: 'uuid', nullable: true })
  warehouseId?: string | null;

  @Column({ name: 'yard_id', type: 'uuid', nullable: true })
  yardId?: string | null;

  @Column({ name: 'zone_id', type: 'uuid', nullable: true })
  zoneId?: string | null;

  // ── Fee definition ────────────────────────────────────────────────────────
  @Column({ name: 'free_days', type: 'int', default: 0 })
  freeDays!: number;

  // Truck detention only: grace window in HOURS before detention accrues
  // (contract default 3h). Null/0 → the 3-hour default.
  @Column({ name: 'free_hours', type: 'int', nullable: true })
  freeHours?: number | null;

  @Column({ name: 'rate_per_day', type: 'numeric', precision: 14, scale: 2, default: 0 })
  ratePerDay!: number;

  // Double-handling only: PER_CONTAINER | PER_TON | PER_MACHINERY. The flat rate
  // (rate_per_day, reused as rate-per-unit) is multiplied by the basis quantity;
  // free days and tiers do not apply. Null for the day-based fee types.
  @Column({ name: 'basis', type: 'varchar', length: 20, nullable: true })
  basis?: FeeRuleBasis | null;

  @Column({ name: 'tiers', type: 'jsonb', default: () => "'[]'" })
  tiers!: WarehouseFeeTier[];

  @Column({ name: 'currency', type: 'varchar', length: 8, default: 'USD' })
  currency!: string;

  @Column({ name: 'is_active', type: 'boolean', default: true })
  isActive!: boolean;
}
