-- ============================================================================
-- HSE Schema DDL - Seguridad, Salud Ocupacional y Medio Ambiente
-- Modulo: MAA-017 Seguridad HSE
-- Version: 1.0.0
-- Fecha: 2025-12-06
-- ============================================================================

-- Verificar prerequisitos
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'core') THEN
        RAISE EXCEPTION 'Schema core no existe. Ejecutar primero erp-core DDL.';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'construction') THEN
        RAISE EXCEPTION 'Schema construction no existe. Ejecutar primero construction-schema-ddl.sql';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'hr') THEN
        RAISE EXCEPTION 'Schema hr no existe. Ejecutar primero hr-schema-ddl.sql';
    END IF;
END $$;

-- Crear schema HSE
CREATE SCHEMA IF NOT EXISTS hse;

-- Configurar search_path
SET search_path TO hse, core, construction, hr, public;

-- ============================================================================
-- EXTENSION PostGIS para geolocalizacion
-- ============================================================================
CREATE EXTENSION IF NOT EXISTS postgis;

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

-- Tipos de incidentes
CREATE TYPE hse.tipo_incidente AS ENUM ('accidente', 'incidente', 'casi_accidente');
CREATE TYPE hse.gravedad_incidente AS ENUM ('leve', 'moderado', 'grave', 'fatal');
CREATE TYPE hse.estado_incidente AS ENUM ('abierto', 'en_investigacion', 'cerrado');
CREATE TYPE hse.rol_involucrado AS ENUM ('lesionado', 'testigo', 'responsable');
CREATE TYPE hse.factor_causa AS ENUM ('acto_inseguro', 'condicion_insegura');

-- Tipos de capacitaciones
CREATE TYPE hse.tipo_capacitacion AS ENUM ('induccion', 'especifica', 'certificacion', 'reentrenamiento');
CREATE TYPE hse.estado_sesion AS ENUM ('programada', 'en_curso', 'completada', 'cancelada');

-- Tipos de inspecciones
CREATE TYPE hse.frecuencia AS ENUM ('diaria', 'semanal', 'quincenal', 'mensual', 'eventual');
CREATE TYPE hse.estado_inspeccion AS ENUM ('programada', 'en_progreso', 'completada', 'cancelada', 'vencida');
CREATE TYPE hse.resultado_evaluacion AS ENUM ('cumple', 'no_cumple', 'no_aplica');
CREATE TYPE hse.gravedad_hallazgo AS ENUM ('critico', 'mayor', 'menor');
CREATE TYPE hse.estado_hallazgo AS ENUM ('abierto', 'en_correccion', 'verificando', 'cerrado', 'reabierto');
CREATE TYPE hse.tipo_evidencia AS ENUM ('hallazgo', 'correccion');

-- Tipos de EPP
CREATE TYPE hse.categoria_epp AS ENUM ('cabeza', 'ojos', 'auditiva', 'respiratoria', 'manos', 'pies', 'caidas', 'ropa');
CREATE TYPE hse.estado_epp AS ENUM ('activo', 'vencido', 'danado', 'perdido', 'devuelto');
CREATE TYPE hse.estado_inspeccion_epp AS ENUM ('bueno', 'regular', 'malo', 'danado');
CREATE TYPE hse.motivo_baja_epp AS ENUM ('vencimiento', 'danado', 'perdido', 'terminacion_laboral');
CREATE TYPE hse.tipo_movimiento_epp AS ENUM ('entrada', 'salida', 'transferencia', 'ajuste');

-- Tipos STPS
CREATE TYPE hse.estado_comision AS ENUM ('activa', 'vencida', 'renovada');
CREATE TYPE hse.rol_comision AS ENUM ('presidente', 'secretario', 'vocal_patronal', 'vocal_trabajador');
CREATE TYPE hse.representacion AS ENUM ('patronal', 'trabajadores');
CREATE TYPE hse.estado_recorrido AS ENUM ('programado', 'realizado', 'cancelado', 'pendiente');
CREATE TYPE hse.estado_programa AS ENUM ('borrador', 'activo', 'finalizado');
CREATE TYPE hse.tipo_actividad_programa AS ENUM ('capacitacion', 'inspeccion', 'simulacro', 'campana', 'otro');
CREATE TYPE hse.estado_actividad AS ENUM ('pendiente', 'en_progreso', 'completada', 'cancelada');
CREATE TYPE hse.tipo_documento_stps AS ENUM ('dc1', 'dc2', 'dc3', 'dc4', 'st7', 'st9');
CREATE TYPE hse.tipo_auditoria AS ENUM ('interna', 'simulada', 'stps', 'cliente', 'certificadora');
CREATE TYPE hse.resultado_auditoria AS ENUM ('aprobada', 'aprobada_observaciones', 'no_aprobada');
CREATE TYPE hse.estado_cumplimiento AS ENUM ('cumple', 'parcial', 'no_cumple', 'no_aplica');

-- Tipos ambientales
CREATE TYPE hse.categoria_residuo AS ENUM ('peligroso', 'manejo_especial', 'urbano');
CREATE TYPE hse.unidad_residuo AS ENUM ('kg', 'litros', 'm3', 'piezas');
CREATE TYPE hse.estado_residuo AS ENUM ('almacenado', 'en_transito', 'dispuesto');
CREATE TYPE hse.estado_almacen AS ENUM ('operativo', 'lleno', 'mantenimiento');
CREATE TYPE hse.tipo_proveedor_ambiental AS ENUM ('transportista', 'reciclador', 'confinamiento');
CREATE TYPE hse.estado_manifiesto AS ENUM ('emitido', 'en_transito', 'entregado', 'cerrado');
CREATE TYPE hse.tipo_impacto AS ENUM ('ruido', 'polvo', 'vibraciones', 'agua', 'emision', 'vegetacion', 'otro');
CREATE TYPE hse.severidad AS ENUM ('bajo', 'medio', 'alto');
CREATE TYPE hse.probabilidad AS ENUM ('baja', 'media', 'alta');
CREATE TYPE hse.nivel_riesgo AS ENUM ('tolerable', 'moderado', 'significativo');
CREATE TYPE hse.estado_impacto AS ENUM ('identificado', 'mitigando', 'controlado');
CREATE TYPE hse.origen_queja AS ENUM ('vecino', 'autoridad', 'interno', 'anonimo');
CREATE TYPE hse.tipo_queja AS ENUM ('ruido', 'polvo', 'olores', 'agua', 'otro');
CREATE TYPE hse.estado_queja AS ENUM ('recibida', 'atendiendo', 'cerrada');

-- Tipos permisos de trabajo
CREATE TYPE hse.estado_permiso AS ENUM ('borrador', 'solicitado', 'aprobado_parcial', 'autorizado', 'en_ejecucion', 'suspendido', 'cerrado', 'rechazado', 'vencido');
CREATE TYPE hse.rol_permiso AS ENUM ('ejecutor', 'supervisor', 'vigia', 'operador', 'senalero');
CREATE TYPE hse.decision_autorizacion AS ENUM ('aprobado', 'rechazado');
CREATE TYPE hse.momento_checklist AS ENUM ('pre_trabajo', 'durante', 'post_trabajo');
CREATE TYPE hse.tipo_evento_permiso AS ENUM ('inicio', 'suspension', 'reanudacion', 'extension', 'anomalia', 'cierre');

-- Tipos indicadores
CREATE TYPE hse.tipo_indicador AS ENUM ('reactivo', 'proactivo', 'ambiental');
CREATE TYPE hse.frecuencia_calculo AS ENUM ('diario', 'semanal', 'mensual');
CREATE TYPE hse.periodo_tipo AS ENUM ('diario', 'semanal', 'mensual', 'anual');
CREATE TYPE hse.estado_semaforo AS ENUM ('verde', 'amarillo', 'rojo');
CREATE TYPE hse.fuente_horas AS ENUM ('asistencia', 'manual');
CREATE TYPE hse.tipo_reporte_hse AS ENUM ('semanal', 'mensual', 'trimestral', 'anual');
CREATE TYPE hse.formato_reporte AS ENUM ('pdf', 'excel', 'ambos');
CREATE TYPE hse.tipo_alerta_indicador AS ENUM ('meta_superada', 'tendencia_negativa', 'sin_datos');

-- ============================================================================
-- RF-MAA017-001: GESTION DE INCIDENTES
-- ============================================================================

-- Tabla: Incidentes
CREATE TABLE hse.incidentes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    folio VARCHAR(20) NOT NULL,
    fecha_hora TIMESTAMPTZ NOT NULL,
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    ubicacion_descripcion TEXT,
    ubicacion_geo GEOMETRY(Point, 4326),
    tipo hse.tipo_incidente NOT NULL,
    gravedad hse.gravedad_incidente NOT NULL,
    descripcion TEXT NOT NULL,
    causa_inmediata TEXT,
    causa_basica TEXT,
    estado hse.estado_incidente NOT NULL DEFAULT 'abierto',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),

    CONSTRAINT uq_incidentes_folio UNIQUE (tenant_id, folio)
);

-- Tabla: Involucrados en incidentes
CREATE TABLE hse.incidente_involucrados (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    incidente_id UUID NOT NULL REFERENCES hse.incidentes(id) ON DELETE CASCADE,
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    rol hse.rol_involucrado NOT NULL,
    descripcion_lesion TEXT,
    parte_cuerpo VARCHAR(100),
    dias_incapacidad INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Investigacion de incidentes
CREATE TABLE hse.incidente_investigacion (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    incidente_id UUID NOT NULL REFERENCES hse.incidentes(id) ON DELETE CASCADE,
    fecha_inicio DATE NOT NULL,
    fecha_cierre DATE,
    investigador_id UUID REFERENCES hr.employees(id),
    metodologia VARCHAR(100),
    factor_causa hse.factor_causa,
    analisis_causas TEXT,
    conclusiones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Acciones correctivas de incidentes
CREATE TABLE hse.incidente_acciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    incidente_id UUID NOT NULL REFERENCES hse.incidentes(id) ON DELETE CASCADE,
    descripcion TEXT NOT NULL,
    tipo VARCHAR(50) NOT NULL,
    responsable_id UUID REFERENCES hr.employees(id),
    fecha_compromiso DATE NOT NULL,
    fecha_cierre DATE,
    estado VARCHAR(20) NOT NULL DEFAULT 'pendiente',
    evidencia_url VARCHAR(500),
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Evidencias de incidentes (fotos)
CREATE TABLE hse.incidente_evidencias (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    incidente_id UUID NOT NULL REFERENCES hse.incidentes(id) ON DELETE CASCADE,
    tipo VARCHAR(50) NOT NULL DEFAULT 'foto',
    archivo_url VARCHAR(500) NOT NULL,
    descripcion VARCHAR(200),
    ubicacion_geo GEOMETRY(Point, 4326),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id)
);

-- ============================================================================
-- RF-MAA017-002: CONTROL DE CAPACITACIONES
-- ============================================================================

-- Tabla: Catalogo de capacitaciones
CREATE TABLE hse.capacitaciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    codigo VARCHAR(20) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    descripcion TEXT,
    tipo hse.tipo_capacitacion NOT NULL,
    duracion_horas DECIMAL(4,1) NOT NULL,
    validez_meses INTEGER,
    norma_referencia VARCHAR(50),
    requiere_evaluacion BOOLEAN NOT NULL DEFAULT false,
    calificacion_minima INTEGER DEFAULT 70,
    contenido_tematico TEXT,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_capacitaciones_codigo UNIQUE (tenant_id, codigo)
);

-- Tabla: Matriz de capacitacion por puesto
CREATE TABLE hse.capacitacion_matriz (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    puesto_id UUID NOT NULL,
    capacitacion_id UUID NOT NULL REFERENCES hse.capacitaciones(id),
    es_obligatoria BOOLEAN NOT NULL DEFAULT true,
    plazo_dias INTEGER DEFAULT 30,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Instructores
CREATE TABLE hse.instructores (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    nombre VARCHAR(200) NOT NULL,
    registro_stps VARCHAR(50),
    especialidades TEXT,
    es_interno BOOLEAN NOT NULL DEFAULT false,
    employee_id UUID REFERENCES hr.employees(id),
    contacto_telefono VARCHAR(20),
    contacto_email VARCHAR(100),
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Sesiones de capacitacion
CREATE TABLE hse.capacitacion_sesiones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    capacitacion_id UUID NOT NULL REFERENCES hse.capacitaciones(id),
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    instructor_id UUID REFERENCES hse.instructores(id),
    fecha_programada DATE NOT NULL,
    hora_inicio TIME NOT NULL,
    hora_fin TIME NOT NULL,
    lugar VARCHAR(200),
    cupo_maximo INTEGER,
    estado hse.estado_sesion NOT NULL DEFAULT 'programada',
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Asistencia a capacitaciones
CREATE TABLE hse.capacitacion_asistentes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    sesion_id UUID NOT NULL REFERENCES hse.capacitacion_sesiones(id) ON DELETE CASCADE,
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    asistio BOOLEAN DEFAULT false,
    hora_entrada TIME,
    hora_salida TIME,
    calificacion INTEGER,
    aprobado BOOLEAN,
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Constancias DC-3
CREATE TABLE hse.constancias_dc3 (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    folio VARCHAR(30) NOT NULL,
    asistente_id UUID NOT NULL REFERENCES hse.capacitacion_asistentes(id),
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    capacitacion_id UUID NOT NULL REFERENCES hse.capacitaciones(id),
    fecha_emision DATE NOT NULL,
    fecha_vencimiento DATE,
    documento_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_constancias_dc3_folio UNIQUE (tenant_id, folio)
);

-- ============================================================================
-- RF-MAA017-003: INSPECCIONES DE SEGURIDAD
-- ============================================================================

-- Tabla: Tipos de inspeccion
CREATE TABLE hse.tipos_inspeccion (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    codigo VARCHAR(20) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    descripcion TEXT,
    frecuencia hse.frecuencia NOT NULL,
    norma_referencia VARCHAR(50),
    duracion_estimada_min INTEGER,
    requiere_firma BOOLEAN NOT NULL DEFAULT true,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_tipos_inspeccion_codigo UNIQUE (tenant_id, codigo)
);

-- Tabla: Items de checklist
CREATE TABLE hse.checklist_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tipo_inspeccion_id UUID NOT NULL REFERENCES hse.tipos_inspeccion(id) ON DELETE CASCADE,
    numero_orden INTEGER NOT NULL,
    categoria VARCHAR(100),
    descripcion TEXT NOT NULL,
    criterio_cumplimiento TEXT,
    es_critico BOOLEAN NOT NULL DEFAULT false,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Programa de inspecciones
CREATE TABLE hse.programa_inspecciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    tipo_inspeccion_id UUID NOT NULL REFERENCES hse.tipos_inspeccion(id),
    inspector_id UUID REFERENCES hr.employees(id),
    fecha_programada DATE NOT NULL,
    hora_programada TIME,
    zona_area VARCHAR(200),
    estado hse.estado_inspeccion NOT NULL DEFAULT 'programada',
    motivo_cancelacion TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Inspecciones ejecutadas
CREATE TABLE hse.inspecciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    programa_id UUID REFERENCES hse.programa_inspecciones(id),
    tipo_inspeccion_id UUID NOT NULL REFERENCES hse.tipos_inspeccion(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    inspector_id UUID NOT NULL REFERENCES hr.employees(id),
    fecha_inicio TIMESTAMPTZ NOT NULL,
    fecha_fin TIMESTAMPTZ,
    ubicacion_geo GEOMETRY(Point, 4326),
    items_evaluados INTEGER DEFAULT 0,
    items_cumple INTEGER DEFAULT 0,
    items_no_cumple INTEGER DEFAULT 0,
    items_no_aplica INTEGER DEFAULT 0,
    porcentaje_cumplimiento DECIMAL(5,2),
    observaciones_generales TEXT,
    firma_inspector TEXT,
    estado VARCHAR(20) NOT NULL DEFAULT 'borrador',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Evaluaciones de inspeccion
CREATE TABLE hse.inspeccion_evaluaciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    inspeccion_id UUID NOT NULL REFERENCES hse.inspecciones(id) ON DELETE CASCADE,
    checklist_item_id UUID NOT NULL REFERENCES hse.checklist_items(id),
    resultado hse.resultado_evaluacion NOT NULL,
    observacion TEXT,
    genera_hallazgo BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Hallazgos de inspeccion
CREATE TABLE hse.hallazgos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    inspeccion_id UUID NOT NULL REFERENCES hse.inspecciones(id),
    evaluacion_id UUID REFERENCES hse.inspeccion_evaluaciones(id),
    folio VARCHAR(20) NOT NULL,
    gravedad hse.gravedad_hallazgo NOT NULL,
    tipo hse.factor_causa NOT NULL,
    descripcion TEXT NOT NULL,
    ubicacion_descripcion VARCHAR(500),
    ubicacion_geo GEOMETRY(Point, 4326),
    responsable_correccion_id UUID REFERENCES hr.employees(id),
    fecha_limite DATE NOT NULL,
    estado hse.estado_hallazgo NOT NULL DEFAULT 'abierto',
    fecha_correccion TIMESTAMPTZ,
    descripcion_correccion TEXT,
    verificador_id UUID REFERENCES hr.employees(id),
    fecha_verificacion TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_hallazgos_folio UNIQUE (tenant_id, folio)
);

-- Tabla: Evidencias de hallazgos
CREATE TABLE hse.hallazgo_evidencias (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hallazgo_id UUID NOT NULL REFERENCES hse.hallazgos(id) ON DELETE CASCADE,
    tipo hse.tipo_evidencia NOT NULL,
    archivo_url VARCHAR(500) NOT NULL,
    descripcion VARCHAR(200),
    ubicacion_geo GEOMETRY(Point, 4326),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id)
);

-- ============================================================================
-- RF-MAA017-004: CONTROL DE EPP
-- ============================================================================

-- Tabla: Catalogo de EPP
CREATE TABLE hse.epp_catalogo (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    codigo VARCHAR(20) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    categoria hse.categoria_epp NOT NULL,
    descripcion TEXT,
    especificaciones TEXT,
    vida_util_dias INTEGER NOT NULL,
    norma_referencia VARCHAR(50),
    requiere_certificacion BOOLEAN NOT NULL DEFAULT false,
    requiere_inspeccion_periodica BOOLEAN NOT NULL DEFAULT false,
    frecuencia_inspeccion_dias INTEGER,
    alerta_dias_antes INTEGER DEFAULT 15,
    imagen_url VARCHAR(500),
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_epp_catalogo_codigo UNIQUE (tenant_id, codigo)
);

-- Tabla: Matriz EPP por puesto
CREATE TABLE hse.epp_matriz_puesto (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    puesto_id UUID NOT NULL,
    epp_id UUID NOT NULL REFERENCES hse.epp_catalogo(id),
    es_obligatorio BOOLEAN NOT NULL DEFAULT true,
    actividad_especifica VARCHAR(200),
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Asignaciones de EPP
CREATE TABLE hse.epp_asignaciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    epp_id UUID NOT NULL REFERENCES hse.epp_catalogo(id),
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    fecha_entrega DATE NOT NULL,
    fecha_vencimiento DATE NOT NULL,
    numero_serie VARCHAR(100),
    numero_lote VARCHAR(100),
    firma_trabajador TEXT,
    foto_entrega_url VARCHAR(500),
    capacitacion_uso BOOLEAN NOT NULL DEFAULT false,
    estado hse.estado_epp NOT NULL DEFAULT 'activo',
    costo_unitario DECIMAL(10,2),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id)
);

-- Tabla: Inspecciones de EPP
CREATE TABLE hse.epp_inspecciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    asignacion_id UUID NOT NULL REFERENCES hse.epp_asignaciones(id) ON DELETE CASCADE,
    inspector_id UUID NOT NULL REFERENCES hr.employees(id),
    fecha_inspeccion DATE NOT NULL,
    estado_epp hse.estado_inspeccion_epp NOT NULL,
    observaciones TEXT,
    requiere_reemplazo BOOLEAN NOT NULL DEFAULT false,
    foto_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Bajas de EPP
CREATE TABLE hse.epp_bajas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    asignacion_id UUID NOT NULL REFERENCES hse.epp_asignaciones(id),
    fecha_baja DATE NOT NULL,
    motivo hse.motivo_baja_epp NOT NULL,
    descripcion TEXT,
    descuento_aplicado BOOLEAN NOT NULL DEFAULT false,
    monto_descuento DECIMAL(10,2),
    autorizado_por UUID REFERENCES hr.employees(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Inventario de EPP
CREATE TABLE hse.epp_inventario (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    epp_id UUID NOT NULL REFERENCES hse.epp_catalogo(id),
    almacen_id UUID,
    cantidad_disponible INTEGER NOT NULL DEFAULT 0,
    cantidad_minima INTEGER DEFAULT 0,
    cantidad_maxima INTEGER,
    costo_promedio DECIMAL(10,2),
    ultima_entrada DATE,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Movimientos de EPP
CREATE TABLE hse.epp_movimientos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    epp_id UUID NOT NULL REFERENCES hse.epp_catalogo(id),
    almacen_origen_id UUID,
    almacen_destino_id UUID,
    tipo hse.tipo_movimiento_epp NOT NULL,
    cantidad INTEGER NOT NULL,
    referencia VARCHAR(100),
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id)
);

-- ============================================================================
-- RF-MAA017-005: CUMPLIMIENTO STPS
-- ============================================================================

-- Tabla: Catalogo de normas STPS
CREATE TABLE hse.normas_stps (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    codigo VARCHAR(30) NOT NULL UNIQUE,
    nombre VARCHAR(300) NOT NULL,
    descripcion TEXT,
    fecha_publicacion DATE,
    ultima_actualizacion DATE,
    aplica_construccion BOOLEAN NOT NULL DEFAULT true,
    documento_url VARCHAR(500),
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Requisitos por norma
CREATE TABLE hse.norma_requisitos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    norma_id UUID NOT NULL REFERENCES hse.normas_stps(id) ON DELETE CASCADE,
    numero VARCHAR(20) NOT NULL,
    descripcion TEXT NOT NULL,
    tipo_evidencia VARCHAR(200),
    es_critico BOOLEAN NOT NULL DEFAULT false,
    aplica_a VARCHAR(100),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Cumplimiento por obra
CREATE TABLE hse.cumplimiento_obra (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    norma_id UUID NOT NULL REFERENCES hse.normas_stps(id),
    requisito_id UUID REFERENCES hse.norma_requisitos(id),
    estado hse.estado_cumplimiento NOT NULL DEFAULT 'no_cumple',
    evidencia_url VARCHAR(500),
    observaciones TEXT,
    fecha_evaluacion DATE NOT NULL,
    evaluador_id UUID REFERENCES hr.employees(id),
    fecha_compromiso DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Comisiones de seguridad e higiene
CREATE TABLE hse.comision_seguridad (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    fecha_constitucion DATE NOT NULL,
    numero_acta VARCHAR(50),
    vigencia_inicio DATE NOT NULL,
    vigencia_fin DATE NOT NULL,
    estado hse.estado_comision NOT NULL DEFAULT 'activa',
    documento_acta_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Integrantes de comision
CREATE TABLE hse.comision_integrantes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    comision_id UUID NOT NULL REFERENCES hse.comision_seguridad(id) ON DELETE CASCADE,
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    rol hse.rol_comision NOT NULL,
    representacion hse.representacion NOT NULL,
    fecha_nombramiento DATE NOT NULL,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Recorridos de comision
CREATE TABLE hse.comision_recorridos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    comision_id UUID NOT NULL REFERENCES hse.comision_seguridad(id) ON DELETE CASCADE,
    fecha_programada DATE NOT NULL,
    fecha_realizada DATE,
    numero_acta VARCHAR(50),
    areas_recorridas TEXT,
    hallazgos TEXT,
    recomendaciones TEXT,
    estado hse.estado_recorrido NOT NULL DEFAULT 'programado',
    documento_acta_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Programa de seguridad anual
CREATE TABLE hse.programa_seguridad (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    anio INTEGER NOT NULL,
    objetivo_general TEXT,
    metas JSONB,
    presupuesto DECIMAL(12,2),
    estado hse.estado_programa NOT NULL DEFAULT 'borrador',
    aprobado_por UUID REFERENCES hr.employees(id),
    fecha_aprobacion DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Actividades del programa
CREATE TABLE hse.programa_actividades (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    programa_id UUID NOT NULL REFERENCES hse.programa_seguridad(id) ON DELETE CASCADE,
    actividad VARCHAR(300) NOT NULL,
    tipo hse.tipo_actividad_programa NOT NULL,
    fecha_programada DATE NOT NULL,
    fecha_realizada DATE,
    responsable_id UUID REFERENCES hr.employees(id),
    recursos TEXT,
    estado hse.estado_actividad NOT NULL DEFAULT 'pendiente',
    evidencia_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Documentos STPS emitidos
CREATE TABLE hse.documentos_stps (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    tipo hse.tipo_documento_stps NOT NULL,
    folio VARCHAR(30) NOT NULL,
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    employee_id UUID REFERENCES hr.employees(id),
    fecha_emision DATE NOT NULL,
    fecha_vencimiento DATE,
    datos_documento JSONB,
    documento_url VARCHAR(500),
    firmado BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),

    CONSTRAINT uq_documentos_stps_folio UNIQUE (tenant_id, tipo, folio)
);

-- Tabla: Auditorias
CREATE TABLE hse.auditorias (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    tipo hse.tipo_auditoria NOT NULL,
    fecha_programada DATE NOT NULL,
    fecha_realizada DATE,
    auditor VARCHAR(200),
    resultado hse.resultado_auditoria,
    no_conformidades INTEGER DEFAULT 0,
    observaciones TEXT,
    informe_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================================
-- RF-MAA017-006: GESTION AMBIENTAL
-- ============================================================================

-- Tabla: Catalogo de residuos
CREATE TABLE hse.residuos_catalogo (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    codigo VARCHAR(20) NOT NULL UNIQUE,
    nombre VARCHAR(200) NOT NULL,
    categoria hse.categoria_residuo NOT NULL,
    caracteristicas_cretib VARCHAR(6),
    norma_referencia VARCHAR(50),
    manejo_requerido TEXT,
    tiempo_max_almacen_dias INTEGER,
    requiere_manifiesto BOOLEAN NOT NULL DEFAULT false,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Generacion de residuos
CREATE TABLE hse.residuos_generacion (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    residuo_id UUID NOT NULL REFERENCES hse.residuos_catalogo(id),
    fecha_generacion DATE NOT NULL,
    cantidad DECIMAL(10,2) NOT NULL,
    unidad hse.unidad_residuo NOT NULL,
    area_generacion VARCHAR(200),
    fuente VARCHAR(200),
    contenedor_id VARCHAR(50),
    foto_url VARCHAR(500),
    ubicacion_geo GEOMETRY(Point, 4326),
    estado hse.estado_residuo NOT NULL DEFAULT 'almacenado',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id)
);

-- Tabla: Almacenes temporales
CREATE TABLE hse.almacen_temporal (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    nombre VARCHAR(100) NOT NULL,
    ubicacion VARCHAR(200),
    capacidad_m3 DECIMAL(8,2),
    tiene_contencion BOOLEAN NOT NULL DEFAULT true,
    tiene_techo BOOLEAN NOT NULL DEFAULT true,
    senalizacion_ok BOOLEAN NOT NULL DEFAULT true,
    estado hse.estado_almacen NOT NULL DEFAULT 'operativo',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Proveedores ambientales
CREATE TABLE hse.proveedores_ambientales (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    razon_social VARCHAR(300) NOT NULL,
    rfc VARCHAR(13),
    tipo hse.tipo_proveedor_ambiental NOT NULL,
    numero_autorizacion VARCHAR(50),
    entidad_autorizadora VARCHAR(100),
    fecha_autorizacion DATE,
    fecha_vencimiento DATE,
    servicios TEXT,
    contacto_nombre VARCHAR(200),
    contacto_telefono VARCHAR(20),
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Manifiestos de residuos
CREATE TABLE hse.manifiestos_residuos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    folio VARCHAR(30) NOT NULL,
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    transportista_id UUID NOT NULL REFERENCES hse.proveedores_ambientales(id),
    destino_id UUID NOT NULL REFERENCES hse.proveedores_ambientales(id),
    fecha_recoleccion DATE NOT NULL,
    fecha_entrega DATE,
    estado hse.estado_manifiesto NOT NULL DEFAULT 'emitido',
    observaciones TEXT,
    documento_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_manifiestos_residuos_folio UNIQUE (tenant_id, folio)
);

-- Tabla: Detalle de manifiestos
CREATE TABLE hse.manifiesto_detalle (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    manifiesto_id UUID NOT NULL REFERENCES hse.manifiestos_residuos(id) ON DELETE CASCADE,
    residuo_id UUID NOT NULL REFERENCES hse.residuos_catalogo(id),
    generacion_ids UUID[],
    cantidad DECIMAL(10,2) NOT NULL,
    unidad hse.unidad_residuo NOT NULL,
    descripcion TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Impacto ambiental
CREATE TABLE hse.impacto_ambiental (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    aspecto VARCHAR(200) NOT NULL,
    tipo_impacto hse.tipo_impacto NOT NULL,
    severidad hse.severidad NOT NULL,
    probabilidad hse.probabilidad NOT NULL,
    nivel_riesgo hse.nivel_riesgo NOT NULL,
    medidas_mitigacion TEXT,
    responsable_id UUID REFERENCES hr.employees(id),
    estado hse.estado_impacto NOT NULL DEFAULT 'identificado',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Quejas ambientales
CREATE TABLE hse.quejas_ambientales (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    fecha_queja TIMESTAMPTZ NOT NULL,
    origen hse.origen_queja NOT NULL,
    tipo hse.tipo_queja NOT NULL,
    descripcion TEXT NOT NULL,
    nombre_quejoso VARCHAR(200),
    contacto_quejoso VARCHAR(100),
    acciones_tomadas TEXT,
    estado hse.estado_queja NOT NULL DEFAULT 'recibida',
    fecha_cierre DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================================
-- RF-MAA017-007: PERMISOS DE TRABAJO
-- ============================================================================

-- Tabla: Tipos de permiso de trabajo
CREATE TABLE hse.tipos_permiso_trabajo (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    codigo VARCHAR(20) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    descripcion TEXT,
    norma_referencia VARCHAR(50),
    vigencia_max_horas INTEGER NOT NULL,
    requiere_autorizacion_nivel INTEGER NOT NULL DEFAULT 2,
    documentos_requeridos JSONB,
    requisitos_personal JSONB,
    equipos_requeridos JSONB,
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_tipos_permiso_trabajo_codigo UNIQUE (tenant_id, codigo)
);

-- Tabla: Permisos de trabajo
CREATE TABLE hse.permisos_trabajo (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    folio VARCHAR(30) NOT NULL,
    tipo_permiso_id UUID NOT NULL REFERENCES hse.tipos_permiso_trabajo(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    solicitante_id UUID NOT NULL REFERENCES hr.employees(id),
    descripcion_trabajo TEXT NOT NULL,
    ubicacion VARCHAR(300) NOT NULL,
    ubicacion_geo GEOMETRY(Point, 4326),
    fecha_inicio_programada TIMESTAMPTZ NOT NULL,
    fecha_fin_programada TIMESTAMPTZ NOT NULL,
    fecha_inicio_real TIMESTAMPTZ,
    fecha_fin_real TIMESTAMPTZ,
    estado hse.estado_permiso NOT NULL DEFAULT 'borrador',
    motivo_rechazo TEXT,
    motivo_suspension TEXT,
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_permisos_trabajo_folio UNIQUE (tenant_id, folio)
);

-- Tabla: Personal del permiso
CREATE TABLE hse.permiso_personal (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    employee_id UUID NOT NULL REFERENCES hr.employees(id),
    rol hse.rol_permiso NOT NULL,
    verificacion_capacitacion BOOLEAN NOT NULL DEFAULT false,
    verificacion_epp BOOLEAN NOT NULL DEFAULT false,
    verificacion_aptitud BOOLEAN NOT NULL DEFAULT false,
    observaciones TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Autorizaciones de permiso
CREATE TABLE hse.permiso_autorizaciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    nivel INTEGER NOT NULL,
    autorizador_id UUID NOT NULL REFERENCES hr.employees(id),
    rol_autorizador VARCHAR(100),
    decision hse.decision_autorizacion NOT NULL,
    observaciones TEXT,
    firma_digital TEXT,
    fecha_decision TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Checklist del permiso
CREATE TABLE hse.permiso_checklist (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    momento hse.momento_checklist NOT NULL,
    item_verificacion VARCHAR(300) NOT NULL,
    cumple BOOLEAN,
    observacion TEXT,
    verificador_id UUID REFERENCES hr.employees(id),
    fecha_verificacion TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Monitoreos durante permiso
CREATE TABLE hse.permiso_monitoreos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    fecha_hora TIMESTAMPTZ NOT NULL,
    tipo VARCHAR(100) NOT NULL,
    valor_medicion VARCHAR(50),
    unidad VARCHAR(20),
    dentro_rango BOOLEAN NOT NULL DEFAULT true,
    observaciones TEXT,
    responsable_id UUID NOT NULL REFERENCES hr.employees(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Eventos del permiso
CREATE TABLE hse.permiso_eventos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    fecha_hora TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    tipo_evento hse.tipo_evento_permiso NOT NULL,
    descripcion TEXT,
    accion_tomada TEXT,
    responsable_id UUID NOT NULL REFERENCES hr.employees(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Documentos del permiso
CREATE TABLE hse.permiso_documentos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    permiso_id UUID NOT NULL REFERENCES hse.permisos_trabajo(id) ON DELETE CASCADE,
    tipo_documento VARCHAR(100) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    archivo_url VARCHAR(500) NOT NULL,
    fecha_subida TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    subido_por UUID REFERENCES auth.users(id)
);

-- ============================================================================
-- RF-MAA017-008: INDICADORES HSE
-- ============================================================================

-- Tabla: Configuracion de indicadores
CREATE TABLE hse.indicadores_config (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    codigo VARCHAR(20) NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    descripcion TEXT,
    formula TEXT,
    unidad VARCHAR(50),
    tipo hse.tipo_indicador NOT NULL,
    meta_global DECIMAL(10,4),
    umbral_verde DECIMAL(10,4),
    umbral_amarillo DECIMAL(10,4),
    umbral_rojo DECIMAL(10,4),
    frecuencia_calculo hse.frecuencia_calculo NOT NULL DEFAULT 'mensual',
    activo BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_indicadores_config_codigo UNIQUE (tenant_id, codigo)
);

-- Tabla: Metas por obra
CREATE TABLE hse.indicadores_meta_obra (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    indicador_id UUID NOT NULL REFERENCES hse.indicadores_config(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    anio INTEGER NOT NULL,
    meta DECIMAL(10,4) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Valores calculados de indicadores
CREATE TABLE hse.indicadores_valores (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    indicador_id UUID NOT NULL REFERENCES hse.indicadores_config(id),
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    periodo_tipo hse.periodo_tipo NOT NULL,
    periodo_fecha DATE NOT NULL,
    valor DECIMAL(15,4),
    numerador DECIMAL(15,4),
    denominador DECIMAL(15,4),
    estado hse.estado_semaforo,
    calculado_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Horas trabajadas
CREATE TABLE hse.horas_trabajadas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    fecha DATE NOT NULL,
    horas_totales DECIMAL(12,2) NOT NULL,
    trabajadores_promedio INTEGER NOT NULL,
    fuente hse.fuente_horas NOT NULL DEFAULT 'manual',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_horas_trabajadas UNIQUE (tenant_id, fraccionamiento_id, fecha)
);

-- Tabla: Dias sin accidente
CREATE TABLE hse.dias_sin_accidente (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    fecha_inicio_conteo DATE NOT NULL,
    dias_acumulados INTEGER NOT NULL DEFAULT 0,
    record_historico INTEGER NOT NULL DEFAULT 0,
    ultimo_incidente_id UUID REFERENCES hse.incidentes(id),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT uq_dias_sin_accidente UNIQUE (tenant_id, fraccionamiento_id)
);

-- Tabla: Reportes programados
CREATE TABLE hse.reportes_programados (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    nombre VARCHAR(200) NOT NULL,
    tipo_reporte hse.tipo_reporte_hse NOT NULL,
    indicadores UUID[],
    fraccionamientos UUID[],
    destinatarios VARCHAR[],
    dia_envio INTEGER,
    hora_envio TIME,
    formato hse.formato_reporte NOT NULL DEFAULT 'pdf',
    activo BOOLEAN NOT NULL DEFAULT true,
    ultimo_envio TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Tabla: Alertas de indicadores
CREATE TABLE hse.alertas_indicadores (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    indicador_id UUID NOT NULL REFERENCES hse.indicadores_config(id),
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    tipo_alerta hse.tipo_alerta_indicador NOT NULL,
    mensaje TEXT NOT NULL,
    valor_actual DECIMAL(10,4),
    valor_meta DECIMAL(10,4),
    leida BOOLEAN NOT NULL DEFAULT false,
    fecha_alerta TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================================
-- INDICES
-- ============================================================================

-- Incidentes
CREATE INDEX idx_incidentes_tenant ON hse.incidentes(tenant_id);
CREATE INDEX idx_incidentes_fraccionamiento ON hse.incidentes(fraccionamiento_id);
CREATE INDEX idx_incidentes_fecha ON hse.incidentes(fecha_hora);
CREATE INDEX idx_incidentes_estado ON hse.incidentes(estado);
CREATE INDEX idx_incidentes_tipo ON hse.incidentes(tipo);
CREATE INDEX idx_incidentes_gravedad ON hse.incidentes(gravedad);
CREATE INDEX idx_incidente_involucrados_employee ON hse.incidente_involucrados(employee_id);

-- Capacitaciones
CREATE INDEX idx_capacitaciones_tenant ON hse.capacitaciones(tenant_id);
CREATE INDEX idx_capacitacion_sesiones_fecha ON hse.capacitacion_sesiones(fecha_programada);
CREATE INDEX idx_capacitacion_asistentes_employee ON hse.capacitacion_asistentes(employee_id);
CREATE INDEX idx_constancias_dc3_employee ON hse.constancias_dc3(employee_id);
CREATE INDEX idx_constancias_dc3_vencimiento ON hse.constancias_dc3(fecha_vencimiento);

-- Inspecciones
CREATE INDEX idx_inspecciones_tenant ON hse.inspecciones(tenant_id);
CREATE INDEX idx_inspecciones_fraccionamiento ON hse.inspecciones(fraccionamiento_id);
CREATE INDEX idx_inspecciones_fecha ON hse.inspecciones(fecha_inicio);
CREATE INDEX idx_programa_inspecciones_fecha ON hse.programa_inspecciones(fecha_programada);
CREATE INDEX idx_hallazgos_estado ON hse.hallazgos(estado);
CREATE INDEX idx_hallazgos_fecha_limite ON hse.hallazgos(fecha_limite);

-- EPP
CREATE INDEX idx_epp_asignaciones_employee ON hse.epp_asignaciones(employee_id);
CREATE INDEX idx_epp_asignaciones_vencimiento ON hse.epp_asignaciones(fecha_vencimiento);
CREATE INDEX idx_epp_asignaciones_estado ON hse.epp_asignaciones(estado);

-- STPS
CREATE INDEX idx_comision_seguridad_vigencia ON hse.comision_seguridad(vigencia_fin);
CREATE INDEX idx_documentos_stps_vencimiento ON hse.documentos_stps(fecha_vencimiento);

-- Ambiental
CREATE INDEX idx_residuos_generacion_fecha ON hse.residuos_generacion(fecha_generacion);
CREATE INDEX idx_manifiestos_estado ON hse.manifiestos_residuos(estado);

-- Permisos
CREATE INDEX idx_permisos_trabajo_estado ON hse.permisos_trabajo(estado);
CREATE INDEX idx_permisos_trabajo_fecha ON hse.permisos_trabajo(fecha_inicio_programada);

-- Indicadores
CREATE INDEX idx_indicadores_valores_fecha ON hse.indicadores_valores(periodo_fecha);
CREATE INDEX idx_horas_trabajadas_fecha ON hse.horas_trabajadas(fecha);

-- ============================================================================
-- ROW LEVEL SECURITY (RLS)
-- ============================================================================

-- Habilitar RLS en todas las tablas con tenant_id
ALTER TABLE hse.incidentes ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.capacitaciones ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.capacitacion_sesiones ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.instructores ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.constancias_dc3 ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.tipos_inspeccion ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.programa_inspecciones ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.inspecciones ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.hallazgos ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.epp_catalogo ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.epp_asignaciones ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.epp_inventario ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.epp_movimientos ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.cumplimiento_obra ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.comision_seguridad ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.programa_seguridad ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.documentos_stps ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.auditorias ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.residuos_generacion ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.almacen_temporal ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.proveedores_ambientales ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.manifiestos_residuos ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.impacto_ambiental ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.quejas_ambientales ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.tipos_permiso_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.permisos_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.indicadores_config ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.indicadores_valores ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.horas_trabajadas ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.dias_sin_accidente ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.reportes_programados ENABLE ROW LEVEL SECURITY;
ALTER TABLE hse.alertas_indicadores ENABLE ROW LEVEL SECURITY;

-- Politicas RLS (ejemplo para incidentes, replicar para las demas)
CREATE POLICY tenant_isolation_incidentes ON hse.incidentes
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_capacitaciones ON hse.capacitaciones
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_inspecciones ON hse.inspecciones
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_hallazgos ON hse.hallazgos
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_epp_asignaciones ON hse.epp_asignaciones
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_permisos_trabajo ON hse.permisos_trabajo
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY tenant_isolation_indicadores_valores ON hse.indicadores_valores
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

-- ============================================================================
-- TRIGGERS PARA UPDATED_AT
-- ============================================================================

CREATE OR REPLACE FUNCTION hse.update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Aplicar trigger a tablas con updated_at
CREATE TRIGGER trg_incidentes_updated_at
    BEFORE UPDATE ON hse.incidentes
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

CREATE TRIGGER trg_capacitaciones_updated_at
    BEFORE UPDATE ON hse.capacitaciones
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

CREATE TRIGGER trg_inspecciones_updated_at
    BEFORE UPDATE ON hse.inspecciones
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

CREATE TRIGGER trg_hallazgos_updated_at
    BEFORE UPDATE ON hse.hallazgos
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

CREATE TRIGGER trg_epp_asignaciones_updated_at
    BEFORE UPDATE ON hse.epp_asignaciones
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

CREATE TRIGGER trg_permisos_trabajo_updated_at
    BEFORE UPDATE ON hse.permisos_trabajo
    FOR EACH ROW EXECUTE FUNCTION hse.update_updated_at();

-- ============================================================================
-- DATOS INICIALES - CATALOGO DE NORMAS STPS
-- ============================================================================

INSERT INTO hse.normas_stps (codigo, nombre, descripcion, aplica_construccion) VALUES
('NOM-001-STPS-2008', 'Edificios, locales e instalaciones', 'Condiciones de seguridad', true),
('NOM-002-STPS-2010', 'Prevencion y proteccion contra incendios', 'Prevencion y proteccion contra incendios en centros de trabajo', true),
('NOM-004-STPS-1999', 'Sistemas de proteccion y dispositivos de seguridad en maquinaria', 'Sistemas de proteccion en maquinaria y equipo', true),
('NOM-005-STPS-1998', 'Manejo de sustancias quimicas peligrosas', 'Relativa a condiciones de seguridad e higiene', true),
('NOM-006-STPS-2014', 'Manejo y almacenamiento de materiales', 'Condiciones de seguridad y salud en el trabajo', true),
('NOM-009-STPS-2011', 'Trabajos en altura', 'Condiciones de seguridad para realizar trabajos en altura', true),
('NOM-011-STPS-2001', 'Ruido', 'Condiciones de seguridad e higiene donde se genere ruido', true),
('NOM-017-STPS-2008', 'Equipo de proteccion personal', 'Seleccion, uso y manejo en centros de trabajo', true),
('NOM-019-STPS-2011', 'Comisiones de seguridad e higiene', 'Constitucion, integracion, organizacion y funcionamiento', true),
('NOM-026-STPS-2008', 'Senales de seguridad', 'Colores y senales de seguridad e higiene', true),
('NOM-029-STPS-2011', 'Mantenimiento de instalaciones electricas', 'Condiciones de seguridad para realizar actividades', true),
('NOM-030-STPS-2009', 'Servicios preventivos de seguridad y salud', 'Funciones y actividades', true),
('NOM-031-STPS-2011', 'Construccion', 'Condiciones de seguridad y salud en el trabajo', true);

-- ============================================================================
-- DATOS INICIALES - CATALOGO DE RESIDUOS COMUNES EN CONSTRUCCION
-- ============================================================================

INSERT INTO hse.residuos_catalogo (codigo, nombre, categoria, caracteristicas_cretib, norma_referencia, tiempo_max_almacen_dias, requiere_manifiesto) VALUES
('RP-001', 'Aceites usados', 'peligroso', 'IT', 'NOM-052-SEMARNAT', 180, true),
('RP-002', 'Solventes usados', 'peligroso', 'IT', 'NOM-052-SEMARNAT', 180, true),
('RP-003', 'Pinturas y barnices', 'peligroso', 'IT', 'NOM-052-SEMARNAT', 180, true),
('RP-004', 'Baterias y acumuladores', 'peligroso', 'CT', 'NOM-052-SEMARNAT', 180, true),
('RP-005', 'Envases contaminados', 'peligroso', 'T', 'NOM-052-SEMARNAT', 180, true),
('RP-006', 'Trapos y estopas impregnados', 'peligroso', 'I', 'NOM-052-SEMARNAT', 180, true),
('RME-001', 'Escombro y cascajo', 'manejo_especial', NULL, 'LGPGIR', 365, false),
('RME-002', 'Tierra excavada', 'manejo_especial', NULL, 'LGPGIR', 365, false),
('RME-003', 'Material de demolicion', 'manejo_especial', NULL, 'LGPGIR', 365, false),
('RSU-001', 'Carton y papel', 'urbano', NULL, NULL, NULL, false),
('RSU-002', 'Plasticos', 'urbano', NULL, NULL, NULL, false),
('RSU-003', 'Residuos organicos', 'urbano', NULL, NULL, NULL, false);

-- ============================================================================
-- COMENTARIOS DE DOCUMENTACION
-- ============================================================================

COMMENT ON SCHEMA hse IS 'Schema para gestion de Seguridad, Salud Ocupacional y Medio Ambiente (HSE) - MAA-017';
COMMENT ON TABLE hse.incidentes IS 'Registro de incidentes y accidentes de trabajo';
COMMENT ON TABLE hse.capacitaciones IS 'Catalogo de capacitaciones de seguridad';
COMMENT ON TABLE hse.inspecciones IS 'Registro de inspecciones de seguridad ejecutadas';
COMMENT ON TABLE hse.hallazgos IS 'Hallazgos detectados en inspecciones';
COMMENT ON TABLE hse.epp_asignaciones IS 'Asignacion de EPP a trabajadores';
COMMENT ON TABLE hse.permisos_trabajo IS 'Permisos para trabajos de alto riesgo';
COMMENT ON TABLE hse.indicadores_valores IS 'Valores calculados de indicadores HSE';

-- ============================================================================
-- FIN DEL DDL
-- ============================================================================
