/**
 * WorkOrder Entity - Ordenes de Trabajo de Mantenimiento
 *
 * Registro de mantenimientos preventivos y correctivos.
 *
 * @module Assets (MAE-015)
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  OneToMany,
  JoinColumn,
  Index,
} from 'typeorm';
import { Asset } from './asset.entity';
import { WorkOrderPart } from './work-order-part.entity';

export type MaintenanceType = 'preventive' | 'corrective' | 'predictive' | 'emergency';
export type WorkOrderStatus = 'draft' | 'scheduled' | 'in_progress' | 'on_hold' | 'completed' | 'cancelled';
export type WorkOrderPriority = 'low' | 'medium' | 'high' | 'critical';

// Const objects for runtime use
export const WorkOrderStatusValues: Record<string, WorkOrderStatus> = {
  DRAFT: 'draft',
  SCHEDULED: 'scheduled',
  IN_PROGRESS: 'in_progress',
  ON_HOLD: 'on_hold',
  COMPLETED: 'completed',
  CANCELLED: 'cancelled',
} as const;

export const WorkOrderPriorityValues: Record<string, WorkOrderPriority> = {
  LOW: 'low',
  MEDIUM: 'medium',
  HIGH: 'high',
  CRITICAL: 'critical',
} as const;

@Entity('work_orders', { schema: 'assets' })
@Index(['tenantId', 'workOrderNumber'], { unique: true })
@Index(['tenantId', 'assetId'])
@Index(['tenantId', 'status'])
@Index(['tenantId', 'scheduledStartDate'])
@Index(['tenantId', 'projectId'])
export class WorkOrder {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

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

  // Identificacion
  @Column({ name: 'work_order_number', length: 50 })
  workOrderNumber!: string;

  // Activo
  @Column({ name: 'asset_id', type: 'uuid' })
  assetId!: string;

  @ManyToOne(() => Asset)
  @JoinColumn({ name: 'asset_id' })
  asset!: Asset;

  @Column({ name: 'asset_code', length: 50, nullable: true })
  assetCode?: string;

  @Column({ name: 'asset_name', length: 255, nullable: true })
  assetName?: string;

  // Tipo y estado
  @Column({
    name: 'maintenance_type',
    type: 'enum',
    enum: ['preventive', 'corrective', 'predictive', 'emergency'],
    enumName: 'maintenance_type',
  })
  maintenanceType!: MaintenanceType;

  @Column({
    type: 'enum',
    enum: ['draft', 'scheduled', 'in_progress', 'on_hold', 'completed', 'cancelled'],
    enumName: 'work_order_status',
    default: 'draft',
  })
  status!: WorkOrderStatus;

  @Column({
    type: 'enum',
    enum: ['low', 'medium', 'high', 'critical'],
    enumName: 'work_order_priority',
    default: 'medium',
  })
  priority!: WorkOrderPriority;

  // Origen
  @Column({ name: 'schedule_id', type: 'uuid', nullable: true })
  scheduleId?: string;

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

  @Column({ name: 'is_scheduled', type: 'boolean', default: false })
  isScheduled!: boolean;

  // Descripcion
  @Column({ length: 255 })
  title!: string;

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

  @Column({ name: 'problem_reported', type: 'text', nullable: true })
  problemReported?: string;

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

  // Ubicacion
  @Column({ name: 'project_id', type: 'uuid', nullable: true })
  projectId?: string;

  @Column({ name: 'project_name', length: 255, nullable: true })
  projectName?: string;

  @Column({ name: 'location_description', length: 255, nullable: true })
  locationDescription?: string;

  // Fechas
  @Column({ name: 'requested_date', type: 'date' })
  requestedDate!: Date;

  @Column({ name: 'scheduled_start_date', type: 'date', nullable: true })
  scheduledStartDate?: Date;

  @Column({ name: 'scheduled_end_date', type: 'date', nullable: true })
  scheduledEndDate?: Date;

  @Column({ name: 'actual_start_date', type: 'date', nullable: true })
  actualStartDate?: Date;

  @Column({ name: 'actual_end_date', type: 'date', nullable: true })
  actualEndDate?: Date;

  // Metricas del equipo al momento
  @Column({ name: 'hours_at_work_order', type: 'decimal', precision: 12, scale: 2, nullable: true })
  hoursAtWorkOrder?: number;

  @Column({ name: 'kilometers_at_work_order', type: 'decimal', precision: 12, scale: 2, nullable: true })
  kilometersAtWorkOrder?: number;

  // Asignacion
  @Column({ name: 'assigned_to_id', type: 'uuid', nullable: true })
  assignedToId?: string;

  @Column({ name: 'assigned_to_name', length: 255, nullable: true })
  assignedToName?: string;

  @Column({ name: 'team_ids', type: 'uuid', array: true, nullable: true })
  teamIds?: string[];

  // Solicitante
  @Column({ name: 'requested_by_id', type: 'uuid', nullable: true })
  requestedById?: string;

  @Column({ name: 'requested_by_name', length: 255, nullable: true })
  requestedByName?: string;

  // Aprobacion
  @Column({ name: 'approved_by_id', type: 'uuid', nullable: true })
  approvedById?: string;

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

  // Trabajo realizado
  @Column({ name: 'work_performed', type: 'text', nullable: true })
  workPerformed?: string;

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

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

  // Checklist de actividades
  @Column({ name: 'activities_checklist', type: 'jsonb', nullable: true })
  activitiesChecklist?: Record<string, any>[];

  // Tiempos
  @Column({ name: 'estimated_hours', type: 'decimal', precision: 5, scale: 2, nullable: true })
  estimatedHours?: number;

  @Column({ name: 'actual_hours', type: 'decimal', precision: 5, scale: 2, nullable: true })
  actualHours?: number;

  // Costos
  @Column({ name: 'labor_cost', type: 'decimal', precision: 18, scale: 2, default: 0 })
  laborCost!: number;

  @Column({ name: 'parts_cost', type: 'decimal', precision: 18, scale: 2, default: 0 })
  partsCost!: number;

  @Column({ name: 'external_service_cost', type: 'decimal', precision: 18, scale: 2, default: 0 })
  externalServiceCost!: number;

  @Column({ name: 'other_costs', type: 'decimal', precision: 18, scale: 2, default: 0 })
  otherCosts!: number;

  @Column({ name: 'total_cost', type: 'decimal', precision: 18, scale: 2, default: 0 })
  totalCost!: number;

  // Partes utilizadas
  @Column({ name: 'parts_used_count', type: 'int', default: 0 })
  partsUsedCount!: number;

  @OneToMany(() => WorkOrderPart, (part) => part.workOrder, { cascade: true })
  partsUsed?: WorkOrderPart[];

  // Documentos
  @Column({ name: 'photos_before', type: 'jsonb', nullable: true })
  photosBefore?: string[];

  @Column({ name: 'photos_after', type: 'jsonb', nullable: true })
  photosAfter?: string[];

  @Column({ type: 'jsonb', nullable: true })
  documents?: string[];

  // Firma de conformidad
  @Column({ name: 'completed_by_id', type: 'uuid', nullable: true })
  completedById?: string;

  @Column({ name: 'completed_by_name', length: 255, nullable: true })
  completedByName?: string;

  @Column({ name: 'completion_signature_url', length: 500, nullable: true })
  completionSignatureUrl?: string;

  @Column({ name: 'completion_notes', type: 'text', nullable: true })
  completionNotes?: string;

  // Seguimiento
  @Column({ name: 'requires_followup', type: 'boolean', default: false })
  requiresFollowup!: boolean;

  @Column({ name: 'followup_notes', type: 'text', nullable: true })
  followupNotes?: string;

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

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

  @Column({ type: 'jsonb', nullable: true })
  metadata?: Record<string, any>;

  // Auditoria
  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy?: string;

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

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

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

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