import { Entity, Column, Index, ManyToOne, OneToMany, JoinColumn } from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { BookingEntity } from './booking.entity';
import { HotelEntity } from './hotel.entity';
import { SupplierEntity } from './supplier.entity';
import { BookingHotelPeriodEntity } from './booking-hotel-period.entity';
import { BookingHotelExtraEntity } from './booking-hotel-extra.entity';

/**
 * The "stay envelope" — one row per continuous check-in / check-out
 * pair on a booking. Per-night structural data (room type, meal plan,
 * rate) lives on the child `periods` table; add-ons (AWEB / CWEB /
 * CNB / meal upgrade / room upgrade / custom) live on `extras`.
 *
 * `subtotal` is a denormalized rollup of the children's line totals,
 * recomputed by the service on every save. It stays here (rather than
 * being a live SUM) so settlement, accounting, and MD list views can
 * read a single number without joining.
 */
@Entity('booking_hotel_items')
@Index('ix_booking_hotel_items_tenant_booking', ['tenant_id', 'booking_id'], {
  where: '"is_deleted" = false',
})
export class BookingHotelItemEntity extends BaseEntity {
  @ManyToOne(() => BookingEntity, (b) => b.hotel_items, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'booking_id' })
  booking: BookingEntity;

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

  @ManyToOne(() => HotelEntity)
  @JoinColumn({ name: 'hotel_id' })
  hotel: HotelEntity;

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

  @Column({ type: 'date' })
  check_in_date: string;

  @Column({ type: 'date' })
  check_out_date: string;

  @Column({ type: 'int' })
  nights: number;

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

  @Column({ type: 'text', nullable: true })
  notes: string | null;

  // ── Tax snapshot (added 2026-05-07 — see migration 1777700000000) ────
  // Per stakeholder Q1=C this is RE-snapshotted at booking-create
  // from quote (don't carry the quote's snapshot forward), then
  // immutable on edit per Q2=B unless refresh_tax: true.
  @Column({ type: 'jsonb', nullable: true })
  tax_breakdown: Record<string, Record<string, number>> | null;

  @Column({ type: 'decimal', precision: 12, scale: 2, nullable: true })
  tax_amount: number | null;

  // ── Supplier assignment + cost (parallel to transport/activity) ─────
  // Hotels are priced per-room-per-night with no Floor matrix, so
  // actual_supplier_cost is NEVER snapshotted at booking-create. Ops
  // fills it manually when assigning a hotel supplier.
  @ManyToOne(() => SupplierEntity, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'supplier_id' })
  supplier: SupplierEntity | null;

  @Column({ type: 'uuid', nullable: true })
  supplier_id: string | null;

  @Column({ type: 'varchar', length: 255, nullable: true })
  supplier_name_text: string | null;

  @Column({ type: 'varchar', length: 20, nullable: true })
  supplier_phone_text: string | null;

  /** What we owe the hotel supplier — ops-entered after assignment. */
  @Column({ type: 'decimal', precision: 12, scale: 2, nullable: true })
  actual_supplier_cost: number | null;

  /** Per-line customer-side slab snapshot (added in migration
   *  1781100000000). See query-quote-hotel.entity.ts for the policy. */
  @Column({ type: 'jsonb', nullable: true })
  tax_snapshot: Record<string, unknown> | null;

  // ── Children (per-night config) ───────────────────────────────────
  @OneToMany(() => BookingHotelPeriodEntity, (p) => p.hotel_item, {
    cascade: false,
  })
  periods: BookingHotelPeriodEntity[];

  @OneToMany(() => BookingHotelExtraEntity, (e) => e.hotel_item, {
    cascade: false,
  })
  extras: BookingHotelExtraEntity[];
}
