import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  OneToMany,
} from 'typeorm';
import { UbicacionCartaPorte } from './ubicacion-carta-porte.entity';
import { MercanciaCartaPorte } from './mercancia-carta-porte.entity';
import { FiguraTransporte } from './figura-transporte.entity';
import { AutotransporteCartaPorte } from './autotransporte-carta-porte.entity';

/**
 * Estado de Carta Porte
 */
export enum EstadoCartaPorte {
  BORRADOR = 'BORRADOR',
  VALIDADA = 'VALIDADA',
  TIMBRADA = 'TIMBRADA',
  CANCELADA = 'CANCELADA',
}

/**
 * Tipo de CFDI para Carta Porte
 */
export enum TipoCfdiCartaPorte {
  INGRESO = 'INGRESO',   // Servicio de transporte (factura)
  TRASLADO = 'TRASLADO', // Traslado propio (sin cobro)
}

@Entity({ schema: 'compliance', name: 'cartas_porte' })
@Index('idx_carta_porte_tenant', ['tenantId'])
@Index('idx_carta_porte_viaje', ['viajeId'])
@Index('idx_carta_porte_uuid', ['uuidCfdi'])
@Index('idx_carta_porte_estado', ['tenantId', 'estado'])
export class CartaPorte {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  // Viaje relacionado
  @Column({ name: 'viaje_id', type: 'uuid' })
  viajeId: string;

  // CFDI
  @Column({ name: 'tipo_cfdi', type: 'enum', enum: TipoCfdiCartaPorte })
  tipoCfdi: TipoCfdiCartaPorte;

  @Column({ name: 'version_carta_porte', type: 'varchar', length: 10, default: '3.1' })
  versionCartaPorte: string;

  // Identificación CFDI
  @Column({ type: 'varchar', length: 10, nullable: true })
  serie: string | null;

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

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

  @Column({ name: 'fecha_timbrado', type: 'timestamptz', nullable: true })
  fechaTimbrado: Date | null;

  // Emisor
  @Column({ name: 'emisor_rfc', type: 'varchar', length: 13 })
  emisorRfc: string;

  @Column({ name: 'emisor_nombre', type: 'varchar', length: 200 })
  emisorNombre: string;

  @Column({ name: 'emisor_regimen_fiscal', type: 'varchar', length: 10, nullable: true })
  emisorRegimenFiscal: string | null;

  // Receptor
  @Column({ name: 'receptor_rfc', type: 'varchar', length: 13 })
  receptorRfc: string;

  @Column({ name: 'receptor_nombre', type: 'varchar', length: 200 })
  receptorNombre: string;

  @Column({ name: 'receptor_uso_cfdi', type: 'varchar', length: 10, nullable: true })
  receptorUsoCfdi: string | null;

  @Column({ name: 'receptor_domicilio_fiscal_cp', type: 'varchar', length: 10, nullable: true })
  receptorDomicilioFiscalCp: string | null;

  // Totales CFDI
  @Column({ type: 'decimal', precision: 15, scale: 2, nullable: true })
  subtotal: number | null;

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

  @Column({ type: 'varchar', length: 3, default: 'MXN' })
  moneda: string;

  // Datos transporte federal
  @Column({ name: 'transporte_internacional', type: 'boolean', default: false })
  transporteInternacional: boolean;

  @Column({ name: 'entrada_salida_merc', type: 'varchar', length: 10, nullable: true })
  entradaSalidaMerc: string | null;

  @Column({ name: 'pais_origen_destino', type: 'varchar', length: 3, nullable: true })
  paisOrigenDestino: string | null;

  // Datos autotransporte
  @Column({ name: 'permiso_sct', type: 'varchar', length: 50, nullable: true })
  permisoSct: string | null;

  @Column({ name: 'num_permiso_sct', type: 'varchar', length: 50, nullable: true })
  numPermisoSct: string | null;

  @Column({ name: 'config_vehicular', type: 'varchar', length: 10, nullable: true })
  configVehicular: string | null;

  @Column({ name: 'peso_bruto_total', type: 'decimal', precision: 12, scale: 3, nullable: true })
  pesoBrutoTotal: number | null;

  @Column({ name: 'unidad_peso', type: 'varchar', length: 10, default: 'KGM' })
  unidadPeso: string;

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

  // Seguro
  @Column({ name: 'asegura_resp_civil', type: 'varchar', length: 100, nullable: true })
  aseguraRespCivil: string | null;

  @Column({ name: 'poliza_resp_civil', type: 'varchar', length: 50, nullable: true })
  polizaRespCivil: string | null;

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

  @Column({ name: 'poliza_med_ambiente', type: 'varchar', length: 50, nullable: true })
  polizaMedAmbiente: string | null;

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

  @Column({ name: 'poliza_carga', type: 'varchar', length: 50, nullable: true })
  polizaCarga: string | null;

  @Column({ name: 'prima_seguro', type: 'decimal', precision: 15, scale: 2, nullable: true })
  primaSeguro: number | null;

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

  // XML y PDF
  @Column({ name: 'xml_cfdi', type: 'text', nullable: true })
  xmlCfdi: string | null;

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

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

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

  // Cancelación
  @Column({ name: 'fecha_cancelacion', type: 'timestamptz', nullable: true })
  fechaCancelacion: Date | null;

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

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

  // Relations
  @OneToMany(() => UbicacionCartaPorte, (ubicacion) => ubicacion.cartaPorte)
  ubicaciones: UbicacionCartaPorte[];

  @OneToMany(() => MercanciaCartaPorte, (mercancia) => mercancia.cartaPorte)
  mercancias: MercanciaCartaPorte[];

  @OneToMany(() => FiguraTransporte, (figura) => figura.cartaPorte)
  figuras: FiguraTransporte[];

  @OneToMany(() => AutotransporteCartaPorte, (auto) => auto.cartaPorte)
  autotransporte: AutotransporteCartaPorte[];

  // 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;

  // Helpers
  get estaTimbrada(): boolean {
    return this.estado === EstadoCartaPorte.TIMBRADA && !!this.uuidCfdi;
  }

  get estaCancelada(): boolean {
    return this.estado === EstadoCartaPorte.CANCELADA;
  }

  get folioCompleto(): string {
    if (!this.folio) return '';
    return this.serie ? `${this.serie}-${this.folio}` : this.folio;
  }

  get esIngreso(): boolean {
    return this.tipoCfdi === TipoCfdiCartaPorte.INGRESO;
  }
}
