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

/**
 * 🎯 Route Entity - Entidade TypeORM para gerenciamento de rotas
 * 
 * Entidade principal para o sistema de gestão de rotas do PraFrota
 * usando padrão number autoincremento para IDs.
 * 
 * ✨ Suporta diferentes tipos de rotas:
 * - First Mile: Coleta em centros de distribuição
 * - Line Haul: Transporte entre cidades/regiões
 * - Last Mile: Entrega final ao cliente
 * - Custom: Rotas personalizadas
 */

// ========================================
// 🎯 ENUMS PARA TIPAGEM
// ========================================

export enum RouteType {
  FIRST_MILE = 'firstMile',
  LINE_HAUL = 'lineHaul',
  LAST_MILE = 'lastMile',
  CUSTOM = 'custom'
}

export enum RouteStatus {
  PENDING = 'pending',
  IN_PROGRESS = 'inProgress',
  COMPLETED = 'completed',
  DELAYED = 'delayed',
  CANCELLED = 'cancelled'
}

export enum RoutePriority {
  LOW = 'low',
  NORMAL = 'normal',
  HIGH = 'high',
  URGENT = 'urgent'
}

export enum Marketplace {
  MERCADO_LIVRE = 'mercadolivre',
  SHOPEE = 'shopee',
  AMAZON = 'amazon',
  CUSTOM = 'custom'
}

export enum SyncStatus {
  PENDING = 'pending',
  SYNCED = 'synced',
  ERROR = 'error'
}

// ========================================
// 🎯 ENUMS PARA CAMPOS AUXILIARES
// ========================================

export enum RouteStopType {
  PICKUP = 'pickup',
  DELIVERY = 'delivery',
  REST = 'rest',
  FUEL = 'fuel',
  MAINTENANCE = 'maintenance'
}

export enum RouteStopStatus {
  PENDING = 'pending',
  COMPLETED = 'completed',
  SKIPPED = 'skipped',
  FAILED = 'failed'
}

export enum RouteAlertType {
  DELAY = 'delay',
  ROUTE_DEVIATION = 'route_deviation',
  VEHICLE_ISSUE = 'vehicle_issue',
  WEATHER = 'weather',
  TRAFFIC = 'traffic',
  SECURITY = 'security'
}

export enum RouteAlertSeverity {
  LOW = 'low',
  MEDIUM = 'medium',
  HIGH = 'high',
  CRITICAL = 'critical'
}

export enum NotificationType {
  SMS = 'sms',
  EMAIL = 'email',
  PUSH = 'push',
  WHATSAPP = 'whatsapp'
}

export enum NotificationStatus {
  PENDING = 'pending',
  SENT = 'sent',
  DELIVERED = 'delivered',
  FAILED = 'failed'
}

export enum DocumentType {
  INVOICE = 'invoice',
  RECEIPT = 'receipt',
  MANIFEST = 'manifest',
  INSURANCE = 'insurance',
  PERMIT = 'permit',
  OTHER = 'other'
}

// ========================================
// 🏢 INTERFACES PARA CAMPOS JSON
// ========================================

export interface RouteLocationJson {
  address: string;
  city: string;
  state: string;
  zipCode?: string;
  country?: string;
  latitude?: number;
  longitude?: number;
  facility?: string;
  contactName?: string;
  contactPhone?: string;
  accessInstructions?: string;
}

export interface RouteStopJson {
  stopId: number;
  sequence: number;
  location: RouteLocationJson;
  type: RouteStopType;
  scheduledTime: Date;
  actualTime?: Date;
  duration?: number;
  packages?: number;
  status: RouteStopStatus;
  notes?: string;
  photos?: string[];
  signature?: string;
}

export interface RouteAlertJson {
  alertId: number;
  type: RouteAlertType;
  severity: RouteAlertSeverity;
  message: string;
  timestamp: Date;
  resolved?: boolean;
  resolvedAt?: Date;
  resolvedBy?: string;
}

export interface RouteNotificationJson {
  notificationId: number;
  type: NotificationType;
  recipient: string;
  message: string;
  sentAt: Date;
  status: NotificationStatus;
  templateId?: string;
}

export interface RouteDocumentJson {
  documentId: number;
  type: DocumentType;
  name: string;
  url: string;
  uploadedAt: Date;
  uploadedBy: string;
  size?: number;
  mimeType?: string;
}

// ========================================
// 🎯 ENTIDADE PRINCIPAL ROUTE
// ========================================

/**
 * Entidade principal para rotas do sistema PraFrota
 * 
 * Índices estratégicos para performance:
 * - ['companyId', 'status']
 * - ['type', 'status'] 
 * - ['scheduledDeparture']
 * - ['driverId']
 * - ['vehicleId']
 * - ['customerId']
 */
@Entity('routes')
@Index(['companyId', 'status'])
@Index(['type', 'status'])
@Index(['scheduledDeparture'])
@Index(['driverId'])
@Index(['vehicleId'])
@Index(['customerId'])
export class RouteEntity {
  
  // ========================================
  // 🆔 IDENTIFICAÇÃO
  // ========================================
  
  /**
   * ID único da rota (autoincremento)
   */
  @PrimaryGeneratedColumn()
  routeId!: number;

  /**
   * Número identificador único da rota
   */
  @Column({ type: 'varchar', length: 50, unique: true })
  @Index()
  routeNumber!: string;

  /**
   * ID da empresa proprietária da rota
   */
  @Column({ type: 'integer' })
  @Index()
  companyId!: number;

  /**
   * Nome da empresa
   */
  @Column({ type: 'varchar', length: 255, nullable: true })
  company_name?: string;

  /**
   * URL do logo da empresa ou null para usar iniciais
   */
  @Column({ type: 'text', nullable: true })
  icon_logo?: string;

  /**
   * ID do cliente
   */
  @Column({ type: 'integer', nullable: true })
  @Index()
  customerId?: number;

  /**
   * Nome do cliente
   */
  @Column({ type: 'varchar', length: 255, nullable: true })
  customer_name?: string;

  /**
   * ID do contrato
   */
  @Column({ type: 'integer', nullable: true })
  contractId?: number;

  /**
   * Nome do contrato
   */
  @Column({ type: 'varchar', length: 255, nullable: true })
  contractName?: string;

  /**
   * ID da tabela de fretes
   */
  @Column({ type: 'integer', nullable: true })
  freightTableId?: number;

  /**
   * Nome da tabela de preços
   */
  @Column({ type: 'varchar', length: 255, nullable: true })
  freightTableName?: string;

  // ========================================
  // 📋 INFORMAÇÕES BÁSICAS
  // ========================================

  /**
   * Tipo da rota
   */
  @Column({
    type: 'enum',
    enum: RouteType,
    default: RouteType.CUSTOM
  })
  @Index()
  type!: RouteType;

  /**
   * Status atual da rota
   */
  @Column({
    type: 'enum',
    enum: RouteStatus,
    default: RouteStatus.PENDING
  })
  @Index()
  status!: RouteStatus;

  /**
   * Prioridade da rota
   */
  @Column({
    type: 'enum',
    enum: RoutePriority,
    default: RoutePriority.NORMAL
  })
  priority!: RoutePriority;

  /**
   * @Column({ type: 'text', nullable: true })
   * Descrição da rota
   */
  description?: string;

  /**
   * @Column({ type: 'text', nullable: true })
   * Observações adicionais
   */
  notes?: string;

  // ========================================
  // 📍 LOCALIZAÇÃO E ROTA
  // ========================================

  /**
   * @Column({ type: 'jsonb' })
   * Localização de origem
   */
  origin!: RouteLocationJson;

  /**
   * @Column({ type: 'jsonb' })
   * Localização de destino
   */
  destination!: RouteLocationJson;

  /**
   * @Column({ type: 'jsonb', nullable: true })
   * Localização atual do veículo
   */
  currentLocation?: RouteLocationJson;

  /**
   * @Column({ type: 'jsonb', nullable: true })
   * Array de paradas da rota
   */
  stops?: RouteStopJson[];

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Distância total em km
   */
  totalDistance?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Duração estimada em minutos
   */
  estimatedDuration?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Duração real em minutos
   */
  actualDuration?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * KM Programado
   */
  plannedKm?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * KM Realizado
   */
  actualKm?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Duração Programada (em minutos)
   */
  plannedDuration?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Duração Realizada (em minutos)
   */
  actualDurationComplete?: number;

  // ========================================
  // ⏰ CRONOGRAMA
  // ========================================

  /**
   * @Column({ type: 'timestamp' })
   * @Index()
   * Data e hora programada de saída
   */
  scheduledDeparture!: Date;

  /**
   * @Column({ type: 'timestamp', nullable: true })
   * Data e hora real de saída
   */
  actualDeparture?: Date;

  /**
   * @Column({ type: 'timestamp' })
   * @Index()
   * Data e hora programada de chegada
   */
  scheduledArrival!: Date;

  /**
   * @Column({ type: 'timestamp', nullable: true })
   * Data e hora real de chegada
   */
  actualArrival?: Date;

  // ========================================
  // 🚛 RECURSOS ALOCADOS
  // ========================================

  /**
   * @Column({ type: 'integer', nullable: true })
   * @Index()
   * ID do motorista
   */
  driverId?: number;

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * Nome do motorista
   */
  driverName?: string;

  /**
   * @Column({ type: 'decimal', precision: 3, scale: 2, nullable: true })
   * Rating do motorista de 1-5
   */
  driverRating?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * @Index()
   * ID do veículo
   */
  vehicleId?: number;

  /**
   * @Column({ type: 'varchar', length: 20, nullable: true })
   * Placa do veículo
   */
  vehiclePlate?: string;

  /**
   * @Column({ type: 'varchar', length: 100, nullable: true })
   * Tipo do veículo
   */
  vehicleType?: string;

  // ========================================
  // 📦 CARGA E PRODUTOS
  // ========================================

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * Tipo de produto
   */
  productType?: string;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Número estimado de volumes
   */
  estimatedPackages?: number;

  /**
   * @Column({ type: 'integer', nullable: true })
   * Número real de volumes
   */
  actualPackages?: number;

  /**
   * @Column({ type: 'decimal', precision: 15, scale: 2, nullable: true })
   * Valor da carga transportada (R$)
   */
  cargoValue?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Peso da carga (kg)
   */
  weight?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Peso total (kg)
   */
  totalWeight?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 3, nullable: true })
   * Volume total (m³)
   */
  totalVolume?: number;

  /**
   * @Column({ type: 'enum', enum: Marketplace, nullable: true })
   * Marketplace de origem
   */
  marketplace?: Marketplace;

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * ID do pedido externo
   */
  externalOrderId?: string;

  // ========================================
  // 💰 FINANCEIRO
  // ========================================

  /**
   * @Column({ type: 'decimal', precision: 15, scale: 2 })
   * Valor total da rota
   */
  totalValue!: number;

  /**
   * @Column({ type: 'decimal', precision: 15, scale: 2, nullable: true })
   * Valor pago (pode ser diferente do valor total)
   */
  paidValue?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 4, nullable: true })
   * Custo por km
   */
  costPerKm?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Custo de combustível
   */
  fuelCost?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Custo de pedágio
   */
  tollCost?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Pagamento do motorista
   */
  driverPayment?: number;

  /**
   * @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true })
   * Custos adicionais
   */
  additionalCosts?: number;

  // ========================================
  // 📊 PERFORMANCE E MÉTRICAS
  // ========================================

  /**
   * @Column({ type: 'boolean', nullable: true })
   * Entrega no prazo
   */
  onTimeDelivery?: boolean;

  /**
   * @Column({ type: 'decimal', precision: 3, scale: 2, nullable: true })
   * Avaliação do cliente (1-5)
   */
  customerRating?: number;

  /**
   * @Column({ type: 'integer', nullable: true, default: 1 })
   * Número de tentativas de entrega
   */
  deliveryAttempts?: number;

  /**
   * @Column({ type: 'decimal', precision: 6, scale: 2, nullable: true })
   * Velocidade média (km/h)
   */
  averageSpeed?: number;

  /**
   * @Column({ type: 'decimal', precision: 8, scale: 2, nullable: true })
   * Consumo de combustível (litros)
   */
  fuelConsumption?: number;

  // ========================================
  // 🔔 ALERTAS E NOTIFICAÇÕES
  // ========================================

  /**
   * @Column({ type: 'jsonb', nullable: true })
   * Array de alertas da rota
   */
  alerts?: RouteAlertJson[];

  /**
   * @Column({ type: 'jsonb', nullable: true })
   * Array de notificações enviadas
   */
  notifications?: RouteNotificationJson[];

  // ========================================
  // 📄 DOCUMENTAÇÃO
  // ========================================

  /**
   * @Column({ type: 'jsonb', nullable: true })
   * Array de documentos relacionados
   */
  documents?: RouteDocumentJson[];

  /**
   * @Column({ type: 'text', array: true, nullable: true })
   * URLs das fotos
   */
  photos?: string[];

  /**
   * @Column({ type: 'text', nullable: true })
   * URL da assinatura de entrega
   */
  signature?: string;

  // ========================================
  // 🗃️ METADADOS
  // ========================================

  /**
   * @CreateDateColumn()
   * Data de criação do registro
   */
  createdAt!: Date;

  /**
   * @UpdateDateColumn()
   * Data da última atualização
   */
  updatedAt!: Date;

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * Usuário que criou o registro
   */
  createdBy?: string;

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * Usuário que fez a última atualização
   */
  updatedBy?: string;

  /**
   * @Column({ type: 'integer', default: 1 })
   * Versão do registro
   */
  version?: number;

  // ========================================
  // 🔗 CAMPOS DE INTEGRAÇÃO
  // ========================================

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   * ID no sistema externo
   */
  externalId?: string;

  /**
   * @Column({ type: 'enum', enum: SyncStatus, nullable: true })
   * Status de sincronização
   */
  syncStatus?: SyncStatus;

  /**
   * @Column({ type: 'timestamp', nullable: true })
   * Data da última sincronização
   */
  lastSync?: Date;

  // ========================================
  // 🔗 RELACIONAMENTOS (Para futuras expansões)
  // ========================================

  /**
   * Relacionamentos comentados para quando as entidades existirem:
   * 
   * @ManyToOne(() => CompanyEntity)
   * @JoinColumn({ name: 'companyId' })
   * company?: CompanyEntity;
   * 
   * @ManyToOne(() => DriverEntity)
   * @JoinColumn({ name: 'driverId' })
   * driver?: DriverEntity;
   * 
   * @ManyToOne(() => VehicleEntity)
   * @JoinColumn({ name: 'vehicleId' })
   * vehicle?: VehicleEntity;
   * 
   * @ManyToOne(() => CustomerEntity)
   * @JoinColumn({ name: 'customerId' })
   * customer?: CustomerEntity;
   */
}

// ========================================
// 🎯 ENTIDADES AUXILIARES (Opcional)
// ========================================

/**
 * @Entity('route_stops')
 * Entidade para paradas normalizadas da rota
 */
export class RouteStopEntity {
  /**
   * @PrimaryGeneratedColumn()
   */
  stopId!: number;

  /**
   * @Column({ type: 'integer' })
   */
  routeId!: number;

  /**
   * @Column({ type: 'integer' })
   */
  sequence!: number;

  /**
   * @Column({ type: 'jsonb' })
   */
  location!: RouteLocationJson;

  /**
   * Tipo da parada
   */
  @Column({
    type: 'enum',
    enum: RouteStopType
  })
  type!: RouteStopType;

  /**
   * Data/hora programada
   */
  @Column({ type: 'timestamp' })
  scheduledTime!: Date;

  /**
   * Data/hora real
   */
  @Column({ type: 'timestamp', nullable: true })
  actualTime?: Date;

  /**
   * Duração em minutos
   */
  @Column({ type: 'integer', nullable: true })
  duration?: number;

  /**
   * Número de volumes
   */
  @Column({ type: 'integer', nullable: true })
  packages?: number;

  /**
   * Status da parada
   */
  @Column({
    type: 'enum',
    enum: RouteStopStatus,
    default: RouteStopStatus.PENDING
  })
  status!: RouteStopStatus;

  /**
   * @Column({ type: 'text', nullable: true })
   */
  notes?: string;

  /**
   * @Column({ type: 'text', array: true, nullable: true })
   */
  photos?: string[];

  /**
   * @Column({ type: 'text', nullable: true })
   */
  signature?: string;

  /**
   * @ManyToOne(() => RouteEntity)
   * @JoinColumn({ name: 'routeId' })
   */
  route!: RouteEntity;
}

/**
 * @Entity('route_alerts')
 * Entidade para alertas normalizados da rota
 */
export class RouteAlertEntity {
  /**
   * @PrimaryGeneratedColumn()
   */
  alertId!: number;

  /**
   * @Column({ type: 'integer' })
   */
  routeId!: number;

  /**
   * Tipo do alerta
   */
  @Column({
    type: 'enum',
    enum: RouteAlertType
  })
  type!: RouteAlertType;

  /**
   * Severidade do alerta
   */
  @Column({
    type: 'enum',
    enum: RouteAlertSeverity
  })
  severity!: RouteAlertSeverity;

  /**
   * @Column({ type: 'text' })
   */
  message!: string;

  /**
   * @Column({ type: 'timestamp' })
   */
  timestamp!: Date;

  /**
   * @Column({ type: 'boolean', default: false })
   */
  resolved!: boolean;

  /**
   * @Column({ type: 'timestamp', nullable: true })
   */
  resolvedAt?: Date;

  /**
   * @Column({ type: 'varchar', length: 255, nullable: true })
   */
  resolvedBy?: string;

  /**
   * @ManyToOne(() => RouteEntity)
   * @JoinColumn({ name: 'routeId' })
   */
  route!: RouteEntity;
}
