/**
 * OfflineQueue Entity
 * ERP Transportistas
 *
 * Queue for offline operations pending synchronization.
 * Sprint: S4 - TASK-007
 * Module: Offline Sync
 */

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

/**
 * Operation types that can be queued offline
 */
export enum TipoOperacionOffline {
  // GPS Operations
  GPS_POSICION = 'GPS_POSICION',
  GPS_EVENTO = 'GPS_EVENTO',

  // Dispatch Operations
  VIAJE_ESTADO = 'VIAJE_ESTADO',
  VIAJE_EVENTO = 'VIAJE_EVENTO',
  CHECKIN = 'CHECKIN',
  CHECKOUT = 'CHECKOUT',

  // POD Operations
  POD_FOTO = 'POD_FOTO',
  POD_FIRMA = 'POD_FIRMA',
  POD_DOCUMENTO = 'POD_DOCUMENTO',

  // Checklist Operations
  CHECKLIST_ITEM = 'CHECKLIST_ITEM',
  CHECKLIST_COMPLETADO = 'CHECKLIST_COMPLETADO',

  // Generic
  CUSTOM = 'CUSTOM',
}

/**
 * Sync status for queued operations
 */
export enum EstadoSincronizacion {
  PENDIENTE = 'PENDIENTE',
  EN_PROCESO = 'EN_PROCESO',
  COMPLETADO = 'COMPLETADO',
  ERROR = 'ERROR',
  CONFLICTO = 'CONFLICTO',
  DESCARTADO = 'DESCARTADO',
}

/**
 * Priority levels for sync queue
 */
export enum PrioridadSync {
  CRITICA = 1,    // GPS positions, safety events
  ALTA = 2,       // POD, status changes
  NORMAL = 3,     // Checklist items, notes
  BAJA = 4,       // Photos, documents
}

@Entity({ name: 'offline_queue', schema: 'tracking' })
@Index('idx_offline_queue_tenant', ['tenantId'])
@Index('idx_offline_queue_dispositivo', ['dispositivoId'])
@Index('idx_offline_queue_estado', ['estado'])
@Index('idx_offline_queue_prioridad', ['prioridad', 'creadoOfflineEn'])
export class OfflineQueue {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  @Column({ name: 'dispositivo_id', type: 'uuid', nullable: true })
  dispositivoId?: string;

  @Column({ name: 'usuario_id', type: 'uuid', nullable: true })
  usuarioId?: string;

  @Column({ name: 'unidad_id', type: 'uuid', nullable: true })
  unidadId?: string;

  @Column({ name: 'viaje_id', type: 'uuid', nullable: true })
  viajeId?: string;

  // Operation details
  @Column({
    name: 'tipo_operacion',
    type: 'enum',
    enum: TipoOperacionOffline,
  })
  tipoOperacion: TipoOperacionOffline;

  @Column({
    type: 'enum',
    enum: EstadoSincronizacion,
    default: EstadoSincronizacion.PENDIENTE,
  })
  estado: EstadoSincronizacion;

  @Column({
    type: 'enum',
    enum: PrioridadSync,
    default: PrioridadSync.NORMAL,
  })
  prioridad: PrioridadSync;

  // Payload - the actual data to sync
  @Column({ type: 'jsonb' })
  payload: Record<string, any>;

  // Metadata
  @Column({ name: 'endpoint_destino', type: 'varchar', length: 255 })
  endpointDestino: string;

  @Column({ name: 'metodo_http', type: 'varchar', length: 10, default: 'POST' })
  metodoHttp: string;

  // Offline timestamps
  @Column({ name: 'creado_offline_en', type: 'timestamptz' })
  creadoOfflineEn: Date;

  @Column({ name: 'cliente_id', type: 'varchar', length: 100, nullable: true })
  clienteId?: string; // UUID generated on client for deduplication

  // Sync tracking
  @Column({ name: 'intentos_sync', type: 'int', default: 0 })
  intentosSync: number;

  @Column({ name: 'max_intentos', type: 'int', default: 5 })
  maxIntentos: number;

  @Column({ name: 'ultimo_intento_en', type: 'timestamptz', nullable: true })
  ultimoIntentoEn?: Date;

  @Column({ name: 'sincronizado_en', type: 'timestamptz', nullable: true })
  sincronizadoEn?: Date;

  // Error handling
  @Column({ name: 'ultimo_error', type: 'text', nullable: true })
  ultimoError?: string;

  @Column({ name: 'historial_errores', type: 'jsonb', default: [] })
  historialErrores: Array<{ timestamp: string; error: string }>;

  // Conflict resolution
  @Column({ name: 'version_servidor', type: 'int', nullable: true })
  versionServidor?: number;

  @Column({ name: 'resolucion_conflicto', type: 'varchar', length: 50, nullable: true })
  resolucionConflicto?: 'CLIENT_WINS' | 'SERVER_WINS' | 'MERGE' | 'MANUAL';

  // Size tracking for bandwidth optimization
  @Column({ name: 'tamano_bytes', type: 'int', nullable: true })
  tamanoBytes?: number;

  @Column({ name: 'comprimido', type: 'boolean', default: false })
  comprimido: boolean;

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

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