-- =============================================================================
-- ERP TRANSPORTISTAS - Schema Maintenance DDL
-- =============================================================================
-- Archivo: 05-maintenance-schema-ddl.sql
-- Version: 1.0.0
-- Fecha: 2026-01-25
-- Descripcion: Mantenimiento preventivo, correctivo, ordenes de trabajo
-- =============================================================================

-- =============================================================================
-- TIPOS ENUMERADOS
-- =============================================================================

CREATE TYPE maintenance.tipo_mantenimiento AS ENUM (
  'PREVENTIVO',
  'CORRECTIVO',
  'PREDICTIVO',
  'EMERGENCIA'
);

CREATE TYPE maintenance.prioridad AS ENUM (
  'BAJA',
  'MEDIA',
  'ALTA',
  'URGENTE'
);

CREATE TYPE maintenance.estado_orden AS ENUM (
  'BORRADOR',
  'PROGRAMADA',
  'EN_PROCESO',
  'ESPERANDO_REFACCIONES',
  'COMPLETADA',
  'CANCELADA'
);

CREATE TYPE maintenance.tipo_servicio AS ENUM (
  'CAMBIO_ACEITE',
  'FRENOS',
  'LLANTAS',
  'SUSPENSION',
  'MOTOR',
  'TRANSMISION',
  'ELECTRICO',
  'CARROCERIA',
  'REFRIGERACION',
  'ALINEACION_BALANCEO',
  'REVISION_GENERAL',
  'OTRO'
);

-- =============================================================================
-- TABLA: planes_mantenimiento
-- =============================================================================

CREATE TABLE maintenance.planes_mantenimiento (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES public.tenants(id),

  -- Identificación
  codigo VARCHAR(50) NOT NULL,
  nombre VARCHAR(200) NOT NULL,
  descripcion TEXT,

  -- Tipo de unidad que aplica
  aplica_tipo_unidad fleet.tipo_unidad[],
  aplica_todas_unidades BOOLEAN DEFAULT FALSE,

  -- Frecuencia
  frecuencia_km INT,
  frecuencia_dias INT,
  frecuencia_horas_motor INT,

  -- Servicios incluidos
  servicios maintenance.tipo_servicio[] NOT NULL,

  -- Costos estimados
  costo_estimado_mano_obra DECIMAL(12, 2),
  costo_estimado_refacciones DECIMAL(12, 2),
  tiempo_estimado_horas DECIMAL(6, 2),

  -- Estado
  activo BOOLEAN DEFAULT TRUE,

  -- Auditoría
  created_at TIMESTAMPTZ DEFAULT NOW(),
  created_by_id UUID NOT NULL,
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_plan_tenant ON maintenance.planes_mantenimiento(tenant_id);
CREATE UNIQUE INDEX idx_plan_codigo ON maintenance.planes_mantenimiento(tenant_id, codigo);

-- =============================================================================
-- TABLA: programacion_mantenimiento
-- =============================================================================

CREATE TABLE maintenance.programacion_mantenimiento (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES public.tenants(id),

  -- Unidad y plan
  unidad_id UUID NOT NULL,
  plan_id UUID REFERENCES maintenance.planes_mantenimiento(id),

  -- Tipo
  tipo maintenance.tipo_mantenimiento NOT NULL,

  -- Próximo mantenimiento
  proximo_km INT,
  proxima_fecha DATE,
  proximas_horas_motor INT,

  -- Último mantenimiento
  ultimo_km INT,
  ultima_fecha DATE,
  ultima_orden_id UUID,

  -- Estado
  vencido BOOLEAN DEFAULT FALSE,
  dias_para_vencer INT,

  -- Auditoría
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_programacion_unidad ON maintenance.programacion_mantenimiento(unidad_id);
CREATE INDEX idx_programacion_vencido ON maintenance.programacion_mantenimiento(tenant_id, vencido);
CREATE INDEX idx_programacion_proxima ON maintenance.programacion_mantenimiento(proxima_fecha);

-- =============================================================================
-- TABLA: ordenes_trabajo
-- =============================================================================

CREATE TABLE maintenance.ordenes_trabajo (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES public.tenants(id),

  -- Identificación
  numero_orden VARCHAR(50) NOT NULL,

  -- Unidad
  unidad_id UUID NOT NULL,
  remolque_id UUID,

  -- Tipo y prioridad
  tipo maintenance.tipo_mantenimiento NOT NULL,
  prioridad maintenance.prioridad DEFAULT 'MEDIA',

  -- Diagnóstico inicial
  descripcion_falla TEXT,
  reportado_por VARCHAR(200),
  reportado_fecha TIMESTAMPTZ,

  -- Programación
  fecha_programada DATE,
  hora_programada TIME,
  taller_id UUID,
  taller_externo_nombre VARCHAR(200),
  es_taller_externo BOOLEAN DEFAULT FALSE,

  -- Ejecución
  fecha_inicio TIMESTAMPTZ,
  fecha_fin TIMESTAMPTZ,
  mecanico_responsable VARCHAR(200),

  -- Odómetro
  odometro_entrada INT,
  odometro_salida INT,

  -- Diagnóstico final
  diagnostico_final TEXT,
  trabajos_realizados TEXT,

  -- Costos
  costo_mano_obra DECIMAL(12, 2) DEFAULT 0,
  costo_refacciones DECIMAL(12, 2) DEFAULT 0,
  costo_otros DECIMAL(12, 2) DEFAULT 0,
  costo_total DECIMAL(12, 2) DEFAULT 0,

  -- Plan relacionado
  plan_id UUID REFERENCES maintenance.planes_mantenimiento(id),

  -- Estado
  estado maintenance.estado_orden DEFAULT 'BORRADOR',

  -- Garantía
  tiene_garantia BOOLEAN DEFAULT FALSE,
  garantia_dias INT,
  garantia_km INT,

  -- Auditoría
  created_at TIMESTAMPTZ DEFAULT NOW(),
  created_by_id UUID NOT NULL,
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  updated_by_id UUID
);

CREATE INDEX idx_ot_tenant ON maintenance.ordenes_trabajo(tenant_id);
CREATE INDEX idx_ot_unidad ON maintenance.ordenes_trabajo(unidad_id);
CREATE INDEX idx_ot_estado ON maintenance.ordenes_trabajo(tenant_id, estado);
CREATE INDEX idx_ot_fecha ON maintenance.ordenes_trabajo(fecha_programada);
CREATE UNIQUE INDEX idx_ot_numero ON maintenance.ordenes_trabajo(tenant_id, numero_orden);

-- =============================================================================
-- TABLA: lineas_orden_trabajo (Refacciones usadas)
-- =============================================================================

CREATE TABLE maintenance.lineas_orden_trabajo (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES public.tenants(id),
  orden_id UUID NOT NULL REFERENCES maintenance.ordenes_trabajo(id),

  -- Tipo de línea
  tipo VARCHAR(20) NOT NULL, -- 'REFACCION', 'MANO_OBRA', 'OTRO'

  -- Refacción (si aplica)
  producto_id UUID,
  numero_parte VARCHAR(100),
  descripcion VARCHAR(500) NOT NULL,

  -- Cantidades
  cantidad DECIMAL(10, 3) NOT NULL,
  unidad_medida VARCHAR(20),

  -- Precios
  precio_unitario DECIMAL(12, 2) NOT NULL,
  descuento DECIMAL(12, 2) DEFAULT 0,
  total DECIMAL(12, 2) NOT NULL,

  -- Proveedor
  proveedor_id UUID,
  proveedor_nombre VARCHAR(200),

  -- Factura
  factura_proveedor VARCHAR(50)
);

CREATE INDEX idx_linea_ot ON maintenance.lineas_orden_trabajo(orden_id);

-- =============================================================================
-- TABLA: checklist_mantenimiento
-- =============================================================================

CREATE TABLE maintenance.checklist_items (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES public.tenants(id),
  orden_id UUID NOT NULL REFERENCES maintenance.ordenes_trabajo(id),

  -- Item
  categoria VARCHAR(100),
  descripcion VARCHAR(500) NOT NULL,
  obligatorio BOOLEAN DEFAULT FALSE,

  -- Resultado
  resultado VARCHAR(20), -- 'OK', 'REPARADO', 'PENDIENTE', 'NO_APLICA'
  observaciones TEXT,

  -- Evidencia
  foto_url TEXT,

  -- Revisado
  revisado_por VARCHAR(200),
  revisado_fecha TIMESTAMPTZ
);

CREATE INDEX idx_checklist_orden ON maintenance.checklist_items(orden_id);

-- =============================================================================
-- RLS POLICIES
-- =============================================================================

ALTER TABLE maintenance.planes_mantenimiento ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.programacion_mantenimiento ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.ordenes_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.lineas_orden_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.checklist_items ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation_planes ON maintenance.planes_mantenimiento
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY tenant_isolation_programacion ON maintenance.programacion_mantenimiento
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY tenant_isolation_ordenes ON maintenance.ordenes_trabajo
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY tenant_isolation_lineas ON maintenance.lineas_orden_trabajo
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY tenant_isolation_checklist ON maintenance.checklist_items
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

-- =============================================================================
-- COMENTARIOS
-- =============================================================================

COMMENT ON TABLE maintenance.planes_mantenimiento IS 'Planes de mantenimiento preventivo';
COMMENT ON TABLE maintenance.programacion_mantenimiento IS 'Programación de próximos mantenimientos por unidad';
COMMENT ON TABLE maintenance.ordenes_trabajo IS 'Órdenes de trabajo de mantenimiento';
COMMENT ON TABLE maintenance.lineas_orden_trabajo IS 'Líneas de detalle de órdenes de trabajo';
COMMENT ON TABLE maintenance.checklist_items IS 'Items de checklist de mantenimiento';

-- =============================================================================
-- FIN DDL MAINTENANCE
-- =============================================================================
