import { Entity, Column, Index, ManyToOne, JoinColumn } from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { DestinationEntity } from './destination.entity';

/**
 * Transport Service entity — tenant-scoped.
 *
 * Represents a transport route between two locations within a destination.
 * Categories: PICKUP, DROPOFF, ONE_WAY, TWO_WAY
 *
 * Sections:
 * - Basic Details: Short Code, Destination, Category
 * - Route: From (city/address/GPS), To (city/address/GPS)
 * - Distance & Duration
 * - Description
 */
@Entity('transport_services')
@Index(['tenant_id', 'short_code'], { unique: true, where: '"is_deleted" = false' })
export class TransportServiceEntity extends BaseEntity {
  // --- Destination FK ---
  @ManyToOne(() => DestinationEntity)
  @JoinColumn({ name: 'destination_id' })
  destination: DestinationEntity;

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

  // --- Basic Details ---
  @Column({ type: 'varchar', length: 50 })
  short_code: string;

  @Column({ type: 'varchar', length: 50 })
  category: string; // PICKUP | DROPOFF | ONE_WAY | TWO_WAY | DISPOSAL

  /**
   * Disposal services only — the at-disposal package shape:
   *   HALF_DAY_4H | FULL_DAY_8H | FULL_DAY_10H | FULL_DAY_12H | HOURLY
   * NULL for point-to-point services. When set, category MUST be
   * DISPOSAL and from_city/to_city act as descriptors (e.g. "Dubai"),
   * not real route endpoints.
   */
  @Column({ type: 'varchar', length: 20, nullable: true })
  duty_type: string | null;

  /**
   * Window length in hours — populated for every disposal service so
   * the UI can render "09:00 → 19:00" without re-deriving from the
   * enum. Fixed-duty rows mirror the enum (4/8/10/12); HOURLY captures
   * the ops-typed custom duration.
   */
  @Column({ type: 'decimal', precision: 4, scale: 1, nullable: true })
  duration_hours: number | null;

  // --- Route: From ---
  @Column({ type: 'varchar', length: 100 })
  from_city: string;

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

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

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

  // --- Route: To ---
  @Column({ type: 'varchar', length: 100 })
  to_city: string;

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

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

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

  // --- Return Route (Two-way only) ---
  @Column({ type: 'varchar', length: 100, nullable: true })
  return_from_city: string | null;

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

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

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

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

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

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

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

  // --- Distance & Duration ---
  @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
  distance_km: number | null;

  @Column({ type: 'int', nullable: true })
  duration_mins: number | null;

  /**
   * Return-leg duration in minutes — only meaningful for TWO_WAY
   * services. Null means "mirror the outbound" (`duration_mins`).
   * Separate column because airport runs / ferry crossings often
   * have asymmetric legs (outbound 45m, return 80m due to traffic
   * direction), and the Movement Planner's tentative free-at time
   * estimate reads this for TWO_WAY rows.
   */
  @Column({ type: 'int', nullable: true })
  return_duration_mins: number | null;

  // --- Description ---
  @Column({ type: 'text', nullable: true })
  description: string | null;

  // --- Airport flag ---
  // When true, this service represents an airport transfer. Booking
  // forms expose flight-detail fields (flight number, terminal,
  // arrival/departure time) on transport items that reference this
  // service, and the Movement Planner surfaces those details in a
  // hover tooltip on the corresponding row.
  @Column({ type: 'boolean', default: false })
  is_airport_service: boolean;

  // --- Status ---
  @Column({ type: 'boolean', default: true })
  is_active: boolean;

  /**
   * Per-service tax-slab override (added in migration 1781100000000).
   * When set, overrides the destination's default tax slab for any
   * transport line referencing this service — handles "this specific
   * route is taxed differently" without forcing a destination-wide
   * change. Null → resolves to destinations.tax_slab_id.
   */
  @Column({ type: 'uuid', nullable: true })
  tax_slab_id: string | null;

  /**
   * Per-service WhatsApp body content (added migration 1783100000000).
   * Same rationale as activities.customer_whatsapp_body — the
   * MOVEMENT template wrappers carry the greeting / footer, this
   * column holds the transport-specific copy (transfer rules, luggage
   * limits, special driver instructions, etc.) that gets interpolated
   * via the `{{service_body}}` token.
   */
  @Column({ type: 'text', nullable: true })
  customer_whatsapp_body: string | null;

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