import { Entity, Column, Index, ManyToOne, JoinColumn, Check } from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { BookingHotelItemEntity } from './booking-hotel-item.entity';

/**
 * A fee-like line item on a booking hotel stay — extra bed /
 * mattress, child-no-bed, or a free-form custom charge. Sits
 * alongside the periods (room-bookings) grid.
 *
 * `kind` drives auto-fill defaults on the frontend (rate preset,
 * whether to multiply by rooms) but is stored as-is here so ops
 * can override any preset on the row.
 *
 * Line total (computed in service, not stored):
 *     quantity × rate × nights.length
 *     × (scale_by_rooms ? Σ periods.num_rooms : 1)
 */
@Entity('booking_hotel_extras')
@Index('ix_booking_hotel_extras_tenant_item', ['tenant_id', 'hotel_item_id'], {
  where: '"is_deleted" = false',
})
@Index(
  'ux_booking_hotel_extras_item_sort',
  ['hotel_item_id', 'sort_order'],
  { unique: true, where: '"is_deleted" = false' },
)
@Check(
  'ck_booking_hotel_extras_kind',
  `"kind" IN ('AWEB','CNB','CUSTOM')`,
)
@Check('ck_booking_hotel_extras_qty', '"quantity" >= 0')
@Check('ck_booking_hotel_extras_rate_non_neg', '"rate" >= 0')
@Check(
  'ck_booking_hotel_extras_nights_range',
  `"nights" = '{}'::integer[] OR (0 <= ALL("nights") AND 99 >= ALL("nights"))`,
)
export class BookingHotelExtraEntity extends BaseEntity {
  @ManyToOne(() => BookingHotelItemEntity, (h) => h.extras, {
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'hotel_item_id' })
  hotel_item: BookingHotelItemEntity;

  @Column({ type: 'uuid' })
  hotel_item_id: string;

  @Column({ type: 'int', default: 0 })
  sort_order: number;

  @Column({ type: 'varchar', length: 20 })
  kind: 'AWEB' | 'CNB' | 'CUSTOM';

  /** Free-text label — required at the app layer when kind = CUSTOM,
   *  optional otherwise (kind carries the semantic meaning). */
  @Column({ type: 'varchar', length: 200, nullable: true })
  description: string | null;

  @Column({ type: 'int', default: 1 })
  quantity: number;

  @Column({ type: 'decimal', precision: 12, scale: 2, default: 0 })
  rate: number;

  /** 0-based night indexes the extra applies to. Empty = does not
   *  contribute to the stay total. */
  @Column({ type: 'integer', array: true, default: () => "'{}'::integer[]" })
  nights: number[];

  /** When true, line total multiplies by the sum of num_rooms across
   *  all periods on the stay (e.g. AWEB "per room per night"). When
   *  false, quantity is the total pax count regardless of rooms. */
  @Column({ type: 'boolean', default: false })
  scale_by_rooms: boolean;
}
