import { ClientCompanyContact } from "src/modules/client-company-contacts/entities/client-company-contact.entity"
import { ClientsCompany } from "src/modules/clients-companies/entities/clients-company.entity"
import { Customer } from "src/modules/customers/entities/customer.entity"
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  ManyToOne,
  JoinColumn,
  CreateDateColumn,
  UpdateDateColumn,
  DeleteDateColumn,
  OneToMany,
  ManyToMany,
  JoinTable,
  BeforeInsert,
  OneToOne,
  AfterLoad,
  BeforeUpdate,
} from "typeorm"
import { TripType } from "./trip-type.entity"
import { Hospital } from "src/modules/hospitals/entities/hospital.entity"
import { TripIntermediateStop } from "src/modules/trip-intermediate-stops/entities/trip-intermediate-stop.entity"
import { AddOn } from "src/modules/add-ons/entities/add-ons.entity"
import { TripFleetAssignment } from "./fleet-trip-management.entity"
import { TripBabySeat } from "./trip-baby-seat.entity"
import { Escort } from "src/modules/escorts/entities/escort.entity"
import { IncidentReporting } from "src/modules/incident-reporting/entities/incident-reporting.entity"
import { randomInt } from "crypto"
import { Rating } from "src/modules/rating/entities/rating.entity"
import { City } from "src/modules/city/entities/city.entity"
import { TripCancellation } from "./trip-cancellations.entity"
import { TripBasePricing } from "./trip-base-pricing.entity"
import { TripAddonsPricing } from "./trip-addons-pricing.entity"
import { TripServicePricing } from "./trip-service-pricing.entity"
import { Plan } from "src/modules/plans/entities/plan.entity"
import { TripTracking } from "./trip-tracking.entity"
import { InvoiceTrips } from "src/modules/invoices/entities/trip-invoice.entity"
import { TripLog } from "./trip-logs.entity"
import { TripTimelineHistory } from "./trip-timeline.entity"

@Entity("trips")
export class Trip {
  @PrimaryGeneratedColumn()
  id: number

  @Column({ type: "boolean", nullable: true })
  is_direct_customer?: boolean

  @Column({ type: "varchar", nullable: true })
  prn_number: string

  @Column({ type: "int", nullable: true })
  client_id: number

  @Column({ type: "int", nullable: true })
  client_contact_billing_id: number

  @Column({ type: "int", nullable: true })
  client_booking_id: number

  @Column({ type: "int", nullable: true })
  customer_id: number

  @Column({ type: "int", nullable: true })
  city_id: number

  @Column({ type: "int", nullable: true })
  plan_id: number

  @Column({ type: "varchar", nullable: true })
  customer_phone_number?: string

  @Column({ type: "varchar", nullable: true })
  customer_email?: string

  @Column({ type: "varchar", nullable: true })
  customer_country_code?: string

  @Column({ type: "varchar", nullable: true })
  customer_ref_no?: string

  @Column({ type: "int", nullable: true })
  trip_type_id?: number

  @Column({ type: "timestamp", nullable: true })
  pickup_datetime?: Date

  @Column({ type: "timestamp", nullable: true })
  dropoff_datetime?: Date

  @Column({ type: "varchar", nullable: true })
  arrive_before?: string

  @Column({ type: "varchar", nullable: true })
  pick_up_location?: string

  @Column({ type: "varchar", nullable: true })
  drop_off_location?: string

  @Column({ type: "varchar", nullable: true })
  pickup_location_type?: string

  @Column({ type: "varchar", nullable: true })
  pickup_place_id?: string

  @Column({ type: "varchar", nullable: true })
  dropoff_place_id?: string

  @Column({ type: "int", nullable: true })
  pickup_hospital_id?: number

  @Column({ type: "varchar", nullable: true })
  dropoff_location_type?: string

  @Column({ type: "int", nullable: true })
  dropoff_hospital_id?: number

  @Column({ type: "varchar", nullable: true })
  service_details?: string

  @Column({ type: "varchar", nullable: true })
  luggage_information?: string

  @Column({ type: "varchar", nullable: true })
  no_of_taxi?: number

  @Column({ type: "int", default: 1 })
  current_step: number

  @Column({ type: "boolean", nullable: true })
  greet_customer?: boolean

  @Column({ type: "varchar", nullable: true })
  greet_message?: string

  @Column({ type: "boolean", nullable: true })
  is_trip_open?: boolean

  @Column({ type: "varchar", nullable: true })
  promo_code?: string

  @Column({ type: "varchar", nullable: true })
  additional_notes?: string

  @Column({ type: "varchar", nullable: true })
  dispatch_note?: string

  @Column({ type: "boolean", default: true })
  is_patient_in_trip?: string

  @Column({ type: "varchar", nullable: true })
  flight_number?: string

  @Column({ type: "varchar", nullable: true })
  pickup_location_lan?: string

  @Column({ type: "varchar", nullable: true })
  pickup_location_long?: string

  @Column({ type: "varchar", nullable: true })
  dropoff_location_lan?: string

  @Column({ type: "varchar", nullable: true })
  dropoff_location_long?: string

  @Column({ type: "jsonb", nullable: true })
  flight_details?: any

  @Column({ type: "varchar", default: "active" })
  status: string

  @Column({ type: "varchar", nullable: true })
  trip_otp?: number

  @Column({ type: "boolean", default: true })
  is_trip_otp_required: boolean

  @Column({ type: "timestamp", nullable: true })
  trip_start_time?: Date

  @Column({ type: "timestamp", nullable: true })
  trip_end_time?: Date

  @Column({ type: "inet", nullable: true })
  current_stop_id?: number

  @Column({ type: "varchar", nullable: true })
  total_passenger?: string

  @Column({ type: "varchar", nullable: true })
  estimated_time?: string

  @Column({ type: "varchar", nullable: true })
  estimated_distance?: string

  @Column({ type: "varchar", nullable: true })
  last_leg_distance?: string

  @Column({ type: "varchar", nullable: true })
  last_leg_time?: string

  @Column({ type: "boolean", default: true })
  is_client_sponsored: boolean

  @Column({ type: "varchar", nullable: true })
  appointment_type?: string

  @Column({ type: "varchar", nullable: true })
  trip_document?: string

  @Column({ type: "varchar", nullable: true })
  document_type: string

  @Column({ type: "varchar", nullable: true })
  trip_timezone: string

  @CreateDateColumn({ type: "timestamp", default: () => "NOW()" })
  created_at: Date

  @UpdateDateColumn({ type: "timestamp", default: () => "NOW()" })
  updated_at: Date

  @DeleteDateColumn({ type: "timestamp", nullable: true })
  deleted_at: Date

  @ManyToOne(() => ClientsCompany)
  @JoinColumn({ name: "client_id" })
  client: ClientsCompany

  @ManyToOne(() => ClientCompanyContact)
  @JoinColumn({ name: "client_contact_billing_id" })
  client_contact_billing: ClientCompanyContact

  @ManyToOne(() => ClientCompanyContact)
  @JoinColumn({ name: "client_booking_id" })
  client_booking: ClientCompanyContact

  @ManyToOne(() => Customer)
  @JoinColumn({ name: "customer_id" })
  customer: Customer

  @ManyToOne(() => TripType, { nullable: true })
  @JoinColumn({ name: "trip_type_id" })
  trip_type?: TripType

  @ManyToOne(() => Hospital, { nullable: true })
  @JoinColumn({ name: "pickup_hospital_id" })
  pickup_hospital?: Hospital

  @ManyToOne(() => Hospital, { nullable: true })
  @JoinColumn({ name: "dropoff_hospital_id" })
  dropoff_hospital?: Hospital

  @OneToMany(() => TripCancellation, (cancellation) => cancellation.trip)
  cancellations: TripCancellation[]

  @OneToMany(
    () => TripIntermediateStop,
    (intermediate_stop) => intermediate_stop.trip,
  )
  intermediate_stop: TripIntermediateStop[]

  @OneToOne(() => TripIntermediateStop, { nullable: true })
  @JoinColumn({ name: "current_stop_id" })
  current_stop: TripIntermediateStop

  @OneToMany(
    () => IncidentReporting,
    (incident_reporting) => incident_reporting.trip,
  )
  incident_reporting: IncidentReporting[]

  @ManyToMany(() => AddOn, (addon) => addon.trips, { cascade: true })
  @JoinTable({
    name: "trip_addons",
    joinColumn: {
      name: "trip_id",
      referencedColumnName: "id",
    },
    inverseJoinColumn: {
      name: "addon_id",
      referencedColumnName: "id",
    },
  })
  addons: AddOn[]

  @OneToMany(() => TripFleetAssignment, (assignment) => assignment.trip)
  assignments: TripFleetAssignment[]

  @OneToMany(() => TripBabySeat, (baby_seats) => baby_seats.trip)
  baby_seats: TripBabySeat

  @OneToMany(() => Rating, (rating) => rating.trip)
  ratings: Rating[]

  @OneToMany(() => TripLog, (trip_logs) => trip_logs.trip)
  trip_logs: TripLog[]

  @OneToMany(
    () => TripServicePricing,
    (trip_service_pricing) => trip_service_pricing.trip,
  )
  trip_service_pricing: TripServicePricing[]

  @ManyToMany(() => Escort, (escort) => escort.trips, { cascade: true })
  @JoinTable({
    name: "trip_escorts",
    joinColumn: {
      name: "trip_id",
      referencedColumnName: "id",
    },
    inverseJoinColumn: {
      name: "escort_id",
      referencedColumnName: "id",
    },
  })
  escorts: Escort[]

  @ManyToOne(() => City, (city) => city.trips)
  @JoinColumn({ name: "city_id" })
  city: City

  @OneToMany(() => TripBasePricing, (base_pricing) => base_pricing.trip)
  base_pricing: TripBasePricing[]

  @OneToMany(
    () => TripAddonsPricing,
    (trip_addons_pricing) => trip_addons_pricing.trip,
  )
  trip_addons_pricing: TripAddonsPricing[]

  @ManyToOne(() => Plan, (plan) => plan.trips, { onDelete: "SET NULL" })
  @JoinColumn({ name: "plan_id" })
  plan: Plan

  @OneToMany(() => TripTracking, (trip_tracking) => trip_tracking.trip)
  trip_tracking: TripTracking[]

  @OneToMany(() => InvoiceTrips, (invoice_trips) => invoice_trips.trip)
  invoice_trips: InvoiceTrips[]

  @OneToMany(() => TripTimelineHistory, (history) => history.trip)
  timeline_history: TripTimelineHistory[]

  // Generate OTP before inserting the trip
  @BeforeInsert()
  @BeforeUpdate()
  generateTripOtp() {
    // OTP generate only when flag is TRUE
    if (this.is_trip_otp_required === true && !this.trip_otp) {
      this.trip_otp = randomInt(1000, 10000)
    }

    // If flag turned OFF, remove OTP
    if (this.is_trip_otp_required === false) {
      this.trip_otp = null
    }
  }

  @AfterLoad()
  async tripSupportDocument() {
    if (this.trip_document) {
      this.trip_document =
        process.env.FILE_UPLOAD === "Local"
          ? `${process.env.BACK_URL}/${this.trip_document}`
          : `${process.env.CLOUDFLARE_R2_PUBLIC_URL}/${this.trip_document}`
    }
  }
}
