import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  OneToMany,
  ManyToOne,
  JoinColumn,
} from 'typeorm';

/**
 * Estado del Viaje
 */
export enum EstadoViaje {
  BORRADOR = 'BORRADOR',
  PLANEADO = 'PLANEADO',
  DESPACHADO = 'DESPACHADO',
  EN_TRANSITO = 'EN_TRANSITO',
  EN_DESTINO = 'EN_DESTINO',
  ENTREGADO = 'ENTREGADO',
  CERRADO = 'CERRADO',
  FACTURADO = 'FACTURADO',
  COBRADO = 'COBRADO',
  CANCELADO = 'CANCELADO',
}

/**
 * Información de Sello
 */
export interface InfoSello {
  numero: string;
  tipo: 'PLASTICO' | 'METALICO' | 'ELECTRONICO' | 'CANDADO';
  colocadoPor?: string;
  foto?: string;
  timestamp?: Date;
}

@Entity({ schema: 'transport', name: 'viajes' })
@Index('idx_viaje_tenant', ['tenantId'])
@Index('idx_viaje_estado', ['tenantId', 'estado'])
@Index('idx_viaje_unidad', ['tenantId', 'unidadId'])
@Index('idx_viaje_operador', ['tenantId', 'operadorId'])
@Index('idx_viaje_fechas', ['tenantId', 'fechaSalidaProgramada'])
export class Viaje {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  tenantId: string;

  // Identificación
  @Column({ type: 'varchar', length: 50 })
  codigo: string;

  @Column({ name: 'numero_viaje', type: 'varchar', length: 50, nullable: true })
  numeroViaje: string;

  // Cliente
  @Column({ name: 'cliente_id', type: 'uuid', nullable: true })
  clienteId: string;

  // Unidad y operador (referencias a fleet schema)
  @Column({ name: 'unidad_id', type: 'uuid' })
  unidadId: string;

  @Column({ name: 'remolque_id', type: 'uuid', nullable: true })
  remolqueId: string;

  @Column({ name: 'operador_id', type: 'uuid' })
  operadorId: string;

  // Ruta
  @Column({ name: 'origen_principal', type: 'varchar', length: 200, nullable: true })
  origenPrincipal: string;

  @Column({ name: 'origen_ciudad', type: 'varchar', length: 100, nullable: true })
  origenCiudad: string;

  @Column({ name: 'destino_principal', type: 'varchar', length: 200, nullable: true })
  destinoPrincipal: string;

  @Column({ name: 'destino_ciudad', type: 'varchar', length: 100, nullable: true })
  destinoCiudad: string;

  @Column({ name: 'distancia_estimada_km', type: 'decimal', precision: 10, scale: 2, nullable: true })
  distanciaEstimadaKm: number;

  @Column({ name: 'tiempo_estimado_horas', type: 'decimal', precision: 6, scale: 2, nullable: true })
  tiempoEstimadoHoras: number;

  // Fechas programadas
  @Column({ name: 'fecha_salida_programada', type: 'timestamptz', nullable: true })
  fechaSalidaProgramada: Date;

  @Column({ name: 'fecha_programada_salida', type: 'timestamptz', nullable: true })
  fechaProgramadaSalida: Date;

  @Column({ name: 'fecha_llegada_programada', type: 'timestamptz', nullable: true })
  fechaLlegadaProgramada: Date;

  // Fechas reales
  @Column({ name: 'fecha_salida_real', type: 'timestamptz', nullable: true })
  fechaSalidaReal: Date;

  @Column({ name: 'fecha_real_salida', type: 'timestamptz', nullable: true })
  fechaRealSalida: Date;

  @Column({ name: 'fecha_llegada_real', type: 'timestamptz', nullable: true })
  fechaLlegadaReal: Date;

  @Column({ name: 'fecha_real_llegada', type: 'timestamptz', nullable: true })
  fechaRealLlegada: Date;

  // Kilometraje
  @Column({ name: 'km_inicio', type: 'int', nullable: true })
  kmInicio: number;

  @Column({ name: 'km_fin', type: 'int', nullable: true })
  kmFin: number;

  // Calculado: km_recorridos = km_fin - km_inicio
  get kmRecorridos(): number | null {
    if (this.kmInicio != null && this.kmFin != null) {
      return this.kmFin - this.kmInicio;
    }
    return null;
  }

  // Estado
  @Column({ type: 'enum', enum: EstadoViaje, default: EstadoViaje.BORRADOR })
  estado: EstadoViaje;

  // Checklist pre-viaje
  @Column({ name: 'checklist_completado', type: 'boolean', default: false })
  checklistCompletado: boolean;

  @Column({ name: 'checklist_fecha', type: 'timestamptz', nullable: true })
  checklistFecha: Date;

  @Column({ name: 'checklist_observaciones', type: 'text', nullable: true })
  checklistObservaciones: string;

  // Sellos
  @Column({ name: 'sellos_salida', type: 'jsonb', nullable: true })
  sellosSalida: InfoSello[];

  @Column({ name: 'sellos_llegada', type: 'jsonb', nullable: true })
  sellosLlegada: InfoSello[];

  // Costos
  @Column({ name: 'costo_combustible', type: 'decimal', precision: 15, scale: 2, default: 0 })
  costoCombustible: number;

  @Column({ name: 'costo_peajes', type: 'decimal', precision: 15, scale: 2, default: 0 })
  costoPeajes: number;

  @Column({ name: 'costo_viaticos', type: 'decimal', precision: 15, scale: 2, default: 0 })
  costoViaticos: number;

  @Column({ name: 'costo_otros', type: 'decimal', precision: 15, scale: 2, default: 0 })
  costoOtros: number;

  @Column({ name: 'costo_total', type: 'decimal', precision: 15, scale: 2, default: 0 })
  costoTotal: number;

  // Ingresos
  @Column({ name: 'ingreso_total', type: 'decimal', precision: 15, scale: 2, default: 0 })
  ingresoTotal: number;

  // Calculado: margen = ingreso_total - costo_total
  get margen(): number {
    return (this.ingresoTotal || 0) - (this.costoTotal || 0);
  }

  // Auditoría
  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt: Date;

  @Column({ name: 'created_by_id', type: 'uuid' })
  createdById: string;

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
  updatedAt: Date;

  @Column({ name: 'updated_by_id', type: 'uuid', nullable: true })
  updatedById: string;
}
