-- ============================================================================
-- 10-documents-schema-ddl.sql
-- Schema: documents
-- ERP Construccion - Modulo Gestion Documental (MAE-016)
-- ============================================================================
-- Descripcion: Sistema de gestion documental incluyendo:
--   - Repositorio de documentos estructurado
--   - Control de versiones
--   - Flujos de aprobacion
--   - Permisos granulares
--   - Anotaciones sobre planos
--   - Integracion con almacenamiento externo (S3)
-- ============================================================================
-- Autor: Claude-Arquitecto-Orquestador
-- Fecha: 2026-01-25
-- Version: 1.0.0
-- ============================================================================

-- Crear schema si no existe
CREATE SCHEMA IF NOT EXISTS documents;

-- ============================================================================
-- ENUMS
-- ============================================================================

-- Tipo de documento
CREATE TYPE documents.document_type AS ENUM (
    'plan',           -- Planos arquitectonicos/estructurales
    'specification',  -- Especificaciones tecnicas
    'contract',       -- Contratos
    'permit',         -- Permisos y licencias
    'report',         -- Reportes
    'photograph',     -- Fotografias
    'drawing',        -- Dibujos y croquis
    'manual',         -- Manuales
    'procedure',      -- Procedimientos
    'form',           -- Formatos
    'correspondence', -- Correspondencia
    'invoice',        -- Facturas
    'estimate',       -- Estimaciones/Presupuestos
    'other'           -- Otro
);

-- Estado del documento
CREATE TYPE documents.document_status AS ENUM (
    'draft',          -- Borrador
    'pending_review', -- Pendiente de revision
    'in_review',      -- En revision
    'approved',       -- Aprobado
    'rejected',       -- Rechazado
    'obsolete',       -- Obsoleto
    'archived'        -- Archivado
);

-- Nivel de acceso
CREATE TYPE documents.access_level AS ENUM (
    'public',       -- Publico (todos en el tenant)
    'internal',     -- Interno (empleados)
    'confidential', -- Confidencial
    'restricted'    -- Restringido (solo autorizados)
);

-- Estado de version
CREATE TYPE documents.version_status AS ENUM (
    'current',    -- Version actual
    'superseded', -- Reemplazada
    'archived'    -- Archivada
);

-- Estado de flujo de aprobacion
CREATE TYPE documents.workflow_status AS ENUM (
    'draft',       -- Borrador
    'pending',     -- Pendiente
    'in_progress', -- En progreso
    'approved',    -- Aprobado
    'rejected',    -- Rechazado
    'cancelled'    -- Cancelado
);

-- Tipo de paso de aprobacion
CREATE TYPE documents.approval_step_type AS ENUM (
    'review',    -- Revision
    'approval',  -- Aprobacion
    'signature', -- Firma
    'comment'    -- Solo comentario
);

-- Accion de aprobacion
CREATE TYPE documents.approval_action AS ENUM (
    'approve',        -- Aprobar
    'reject',         -- Rechazar
    'request_changes' -- Solicitar cambios
);

-- Tipo de anotacion
CREATE TYPE documents.annotation_type AS ENUM (
    'comment',   -- Comentario
    'markup',    -- Marcado
    'highlight', -- Resaltado
    'arrow',     -- Flecha
    'dimension', -- Dimension
    'stamp',     -- Sello
    'signature'  -- Firma
);

-- ============================================================================
-- TABLAS
-- ============================================================================

-- ----------------------------------------------------------------------------
-- 1. Categorias de Documentos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.document_categories (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Informacion basica
    code VARCHAR(50) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,

    -- Jerarquia
    parent_id UUID REFERENCES documents.document_categories(id),
    level INTEGER NOT NULL DEFAULT 1,
    path VARCHAR(500), -- Path completo separado por /

    -- Configuracion
    default_access_level documents.access_level DEFAULT 'internal',
    requires_approval BOOLEAN DEFAULT FALSE,
    retention_days INTEGER, -- Tiempo de retencion en dias
    allowed_extensions VARCHAR(255)[], -- Extensiones permitidas

    -- Icono y color
    icon VARCHAR(50),
    color VARCHAR(20),

    -- Estado
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    sort_order INTEGER DEFAULT 0,

    -- Metadatos
    metadata JSONB,

    -- Auditoria
    created_by UUID,
    updated_by UUID,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at TIMESTAMPTZ,

    CONSTRAINT uq_document_categories_tenant_code UNIQUE (tenant_id, code)
);

-- ----------------------------------------------------------------------------
-- 2. Documentos (Registro Principal)
-- ----------------------------------------------------------------------------
CREATE TABLE documents.documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Identificacion
    document_code VARCHAR(100) NOT NULL,
    title VARCHAR(500) NOT NULL,
    description TEXT,

    -- Clasificacion
    category_id UUID REFERENCES documents.document_categories(id),
    document_type documents.document_type NOT NULL,
    status documents.document_status NOT NULL DEFAULT 'draft',
    access_level documents.access_level NOT NULL DEFAULT 'internal',

    -- Version actual
    current_version_id UUID, -- Se actualiza con trigger
    current_version_number VARCHAR(20) DEFAULT '1.0',

    -- Proyecto/Contexto
    project_id UUID,
    project_code VARCHAR(50),
    project_name VARCHAR(255),

    -- Metadatos del documento
    author VARCHAR(255),
    keywords VARCHAR(255)[],
    tags VARCHAR(100)[],

    -- Fechas importantes
    document_date DATE,
    effective_date DATE,
    expiry_date DATE,
    review_date DATE,

    -- Origen
    source VARCHAR(100), -- internal, external, contractor
    external_reference VARCHAR(255), -- Referencia externa si aplica
    original_filename VARCHAR(500),

    -- Relaciones
    parent_document_id UUID REFERENCES documents.documents(id), -- Documento padre
    related_documents UUID[], -- Array de IDs relacionados

    -- Flujo de aprobacion
    requires_approval BOOLEAN DEFAULT FALSE,
    current_workflow_id UUID,
    approved_by_id UUID,
    approved_at TIMESTAMPTZ,

    -- Estadisticas
    view_count INTEGER DEFAULT 0,
    download_count INTEGER DEFAULT 0,
    last_accessed_at TIMESTAMPTZ,

    -- Flags
    is_template BOOLEAN DEFAULT FALSE,
    is_locked BOOLEAN DEFAULT FALSE,
    locked_by_id UUID,
    locked_at TIMESTAMPTZ,

    -- Notas y metadatos
    notes TEXT,
    custom_fields JSONB,
    metadata JSONB,

    -- Auditoria
    created_by UUID,
    updated_by UUID,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at TIMESTAMPTZ,

    CONSTRAINT uq_documents_tenant_code UNIQUE (tenant_id, document_code)
);

-- ----------------------------------------------------------------------------
-- 3. Versiones de Documentos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.document_versions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Documento padre
    document_id UUID NOT NULL REFERENCES documents.documents(id) ON DELETE CASCADE,

    -- Version
    version_number VARCHAR(20) NOT NULL,
    version_label VARCHAR(100), -- Etiqueta opcional (ej: "Final", "Para construccion")
    status documents.version_status NOT NULL DEFAULT 'current',

    -- Archivo
    file_name VARCHAR(500) NOT NULL,
    file_extension VARCHAR(20) NOT NULL,
    file_size_bytes BIGINT NOT NULL,
    mime_type VARCHAR(100),
    checksum_md5 VARCHAR(32),
    checksum_sha256 VARCHAR(64),

    -- Almacenamiento
    storage_provider VARCHAR(50) NOT NULL DEFAULT 's3', -- s3, azure, local
    storage_bucket VARCHAR(255),
    storage_key VARCHAR(1000) NOT NULL, -- Path en el storage
    storage_url VARCHAR(2000), -- URL de acceso
    thumbnail_url VARCHAR(2000),
    preview_url VARCHAR(2000),

    -- Procesamiento
    is_processed BOOLEAN DEFAULT FALSE,
    ocr_text TEXT, -- Texto extraido por OCR
    extracted_metadata JSONB,

    -- Paginas (para PDFs/planos)
    page_count INTEGER,
    page_dimensions JSONB, -- Dimensiones por pagina

    -- Cambios
    change_summary TEXT,
    change_type VARCHAR(50), -- major, minor, patch

    -- Subido por
    uploaded_by_id UUID,
    uploaded_by_name VARCHAR(255),
    upload_source VARCHAR(50), -- web, mobile, api, email

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    superseded_at TIMESTAMPTZ,
    superseded_by_version_id UUID
);

-- ----------------------------------------------------------------------------
-- 4. Permisos de Documentos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.document_permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Objeto
    document_id UUID REFERENCES documents.documents(id) ON DELETE CASCADE,
    category_id UUID REFERENCES documents.document_categories(id) ON DELETE CASCADE,

    -- Sujeto (quien tiene el permiso)
    user_id UUID,
    role_id UUID,
    team_id UUID,

    -- Permisos
    can_view BOOLEAN DEFAULT FALSE,
    can_download BOOLEAN DEFAULT FALSE,
    can_edit BOOLEAN DEFAULT FALSE,
    can_delete BOOLEAN DEFAULT FALSE,
    can_share BOOLEAN DEFAULT FALSE,
    can_approve BOOLEAN DEFAULT FALSE,
    can_annotate BOOLEAN DEFAULT FALSE,

    -- Vigencia
    valid_from TIMESTAMPTZ,
    valid_until TIMESTAMPTZ,

    -- Otorgado por
    granted_by_id UUID,
    granted_at TIMESTAMPTZ DEFAULT NOW(),

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT chk_permission_target CHECK (
        (document_id IS NOT NULL AND category_id IS NULL) OR
        (document_id IS NULL AND category_id IS NOT NULL)
    ),
    CONSTRAINT chk_permission_subject CHECK (
        (user_id IS NOT NULL AND role_id IS NULL AND team_id IS NULL) OR
        (user_id IS NULL AND role_id IS NOT NULL AND team_id IS NULL) OR
        (user_id IS NULL AND role_id IS NULL AND team_id IS NOT NULL)
    )
);

-- ----------------------------------------------------------------------------
-- 5. Flujos de Aprobacion (Definicion)
-- ----------------------------------------------------------------------------
CREATE TABLE documents.approval_workflows (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Identificacion
    workflow_code VARCHAR(50) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,

    -- Aplica a
    category_id UUID REFERENCES documents.document_categories(id),
    document_type documents.document_type,

    -- Pasos (JSON array con la definicion)
    steps JSONB NOT NULL, -- [{step_number, name, type, approvers[], required_count}]

    -- Configuracion
    allow_parallel BOOLEAN DEFAULT FALSE, -- Pasos pueden ser paralelos
    allow_skip BOOLEAN DEFAULT FALSE, -- Permitir saltar pasos
    auto_archive_on_approval BOOLEAN DEFAULT FALSE,

    -- Estado
    is_active BOOLEAN NOT NULL DEFAULT TRUE,

    -- Metadatos
    metadata JSONB,

    -- Auditoria
    created_by UUID,
    updated_by UUID,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at TIMESTAMPTZ,

    CONSTRAINT uq_approval_workflows_tenant_code UNIQUE (tenant_id, workflow_code)
);

-- ----------------------------------------------------------------------------
-- 6. Instancias de Flujo de Aprobacion
-- ----------------------------------------------------------------------------
CREATE TABLE documents.approval_instances (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Flujo y documento
    workflow_id UUID NOT NULL REFERENCES documents.approval_workflows(id),
    document_id UUID NOT NULL REFERENCES documents.documents(id),
    version_id UUID REFERENCES documents.document_versions(id),

    -- Estado
    status documents.workflow_status NOT NULL DEFAULT 'draft',
    current_step INTEGER DEFAULT 1,
    total_steps INTEGER NOT NULL,

    -- Fechas
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    due_date TIMESTAMPTZ,

    -- Iniciador
    initiated_by_id UUID,
    initiated_by_name VARCHAR(255),

    -- Resultado final
    final_action documents.approval_action,
    final_comments TEXT,
    final_approver_id UUID,

    -- Notas
    notes TEXT,
    metadata JSONB,

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ----------------------------------------------------------------------------
-- 7. Pasos de Aprobacion (Instancias)
-- ----------------------------------------------------------------------------
CREATE TABLE documents.approval_steps (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Instancia
    instance_id UUID NOT NULL REFERENCES documents.approval_instances(id) ON DELETE CASCADE,

    -- Paso
    step_number INTEGER NOT NULL,
    step_name VARCHAR(255) NOT NULL,
    step_type documents.approval_step_type NOT NULL,

    -- Aprobadores requeridos
    required_approvers UUID[], -- IDs de usuarios requeridos
    required_count INTEGER DEFAULT 1, -- Cuantas aprobaciones se necesitan

    -- Estado
    status documents.workflow_status NOT NULL DEFAULT 'pending',

    -- Fechas
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    due_date TIMESTAMPTZ,

    -- Resultado
    action_taken documents.approval_action,
    approved_by UUID[],
    rejected_by UUID[],

    -- Notas
    notes TEXT,

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ----------------------------------------------------------------------------
-- 8. Acciones de Aprobacion
-- ----------------------------------------------------------------------------
CREATE TABLE documents.approval_actions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Paso
    step_id UUID NOT NULL REFERENCES documents.approval_steps(id) ON DELETE CASCADE,
    instance_id UUID NOT NULL REFERENCES documents.approval_instances(id),

    -- Accion
    action documents.approval_action NOT NULL,
    comments TEXT,

    -- Usuario que toma la accion
    user_id UUID NOT NULL,
    user_name VARCHAR(255),

    -- Firma digital (si aplica)
    signature_data TEXT,
    signature_timestamp TIMESTAMPTZ,
    signature_ip VARCHAR(45),

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ----------------------------------------------------------------------------
-- 9. Anotaciones sobre Documentos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.annotations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Documento y version
    document_id UUID NOT NULL REFERENCES documents.documents(id) ON DELETE CASCADE,
    version_id UUID REFERENCES documents.document_versions(id),

    -- Tipo
    annotation_type documents.annotation_type NOT NULL,

    -- Ubicacion en el documento
    page_number INTEGER,
    x_position DECIMAL(10,4),
    y_position DECIMAL(10,4),
    width DECIMAL(10,4),
    height DECIMAL(10,4),
    rotation DECIMAL(5,2),

    -- Contenido
    content TEXT, -- Texto del comentario o SVG del dibujo
    style JSONB, -- Estilos (color, grosor, fuente, etc.)

    -- Respuesta a otra anotacion
    parent_annotation_id UUID REFERENCES documents.annotations(id),

    -- Estado
    is_resolved BOOLEAN DEFAULT FALSE,
    resolved_by_id UUID,
    resolved_at TIMESTAMPTZ,

    -- Visibilidad
    is_private BOOLEAN DEFAULT FALSE,
    visible_to UUID[], -- Array de user_ids si es privado

    -- Autor
    author_id UUID NOT NULL,
    author_name VARCHAR(255),

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at TIMESTAMPTZ
);

-- ----------------------------------------------------------------------------
-- 10. Historial de Acceso a Documentos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.access_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Documento
    document_id UUID NOT NULL REFERENCES documents.documents(id),
    version_id UUID REFERENCES documents.document_versions(id),

    -- Accion
    action VARCHAR(50) NOT NULL, -- view, download, print, share, edit
    action_details JSONB,

    -- Usuario
    user_id UUID NOT NULL,
    user_name VARCHAR(255),
    user_ip VARCHAR(45),
    user_agent TEXT,

    -- Contexto
    session_id VARCHAR(100),
    request_source VARCHAR(50), -- web, mobile, api

    -- Timestamp
    accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ----------------------------------------------------------------------------
-- 11. Compartidos Externos
-- ----------------------------------------------------------------------------
CREATE TABLE documents.document_shares (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Documento
    document_id UUID NOT NULL REFERENCES documents.documents(id) ON DELETE CASCADE,
    version_id UUID REFERENCES documents.document_versions(id),

    -- Link compartido
    share_token VARCHAR(100) NOT NULL UNIQUE,
    share_url VARCHAR(2000),

    -- Destinatario
    shared_with_email VARCHAR(255),
    shared_with_name VARCHAR(255),

    -- Permisos
    can_download BOOLEAN DEFAULT FALSE,
    can_comment BOOLEAN DEFAULT FALSE,

    -- Seguridad
    password_hash VARCHAR(255), -- Si requiere password
    max_downloads INTEGER,
    download_count INTEGER DEFAULT 0,

    -- Vigencia
    expires_at TIMESTAMPTZ,
    is_revoked BOOLEAN DEFAULT FALSE,
    revoked_at TIMESTAMPTZ,
    revoked_by_id UUID,

    -- Compartido por
    shared_by_id UUID NOT NULL,
    shared_by_name VARCHAR(255),

    -- Notificacion
    notification_sent BOOLEAN DEFAULT FALSE,
    notification_sent_at TIMESTAMPTZ,

    -- Auditoria
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_accessed_at TIMESTAMPTZ
);

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

-- Document Categories
CREATE INDEX idx_document_categories_tenant ON documents.document_categories(tenant_id);
CREATE INDEX idx_document_categories_parent ON documents.document_categories(parent_id);

-- Documents
CREATE INDEX idx_documents_tenant ON documents.documents(tenant_id);
CREATE INDEX idx_documents_tenant_category ON documents.documents(tenant_id, category_id);
CREATE INDEX idx_documents_tenant_type ON documents.documents(tenant_id, document_type);
CREATE INDEX idx_documents_tenant_status ON documents.documents(tenant_id, status);
CREATE INDEX idx_documents_tenant_project ON documents.documents(tenant_id, project_id);
CREATE INDEX idx_documents_keywords ON documents.documents USING gin(keywords);
CREATE INDEX idx_documents_tags ON documents.documents USING gin(tags);
CREATE INDEX idx_documents_fulltext ON documents.documents USING gin(
    to_tsvector('spanish', coalesce(title, '') || ' ' || coalesce(description, ''))
);

-- Document Versions
CREATE INDEX idx_document_versions_tenant ON documents.document_versions(tenant_id);
CREATE INDEX idx_document_versions_document ON documents.document_versions(document_id);
CREATE INDEX idx_document_versions_status ON documents.document_versions(status);

-- Document Permissions
CREATE INDEX idx_document_permissions_document ON documents.document_permissions(document_id);
CREATE INDEX idx_document_permissions_category ON documents.document_permissions(category_id);
CREATE INDEX idx_document_permissions_user ON documents.document_permissions(user_id);
CREATE INDEX idx_document_permissions_role ON documents.document_permissions(role_id);

-- Approval Workflows
CREATE INDEX idx_approval_workflows_tenant ON documents.approval_workflows(tenant_id);
CREATE INDEX idx_approval_workflows_category ON documents.approval_workflows(category_id);

-- Approval Instances
CREATE INDEX idx_approval_instances_tenant ON documents.approval_instances(tenant_id);
CREATE INDEX idx_approval_instances_document ON documents.approval_instances(document_id);
CREATE INDEX idx_approval_instances_status ON documents.approval_instances(status);

-- Approval Steps
CREATE INDEX idx_approval_steps_instance ON documents.approval_steps(instance_id);
CREATE INDEX idx_approval_steps_status ON documents.approval_steps(status);

-- Approval Actions
CREATE INDEX idx_approval_actions_step ON documents.approval_actions(step_id);
CREATE INDEX idx_approval_actions_user ON documents.approval_actions(user_id);

-- Annotations
CREATE INDEX idx_annotations_tenant ON documents.annotations(tenant_id);
CREATE INDEX idx_annotations_document ON documents.annotations(document_id);
CREATE INDEX idx_annotations_version ON documents.annotations(version_id);
CREATE INDEX idx_annotations_author ON documents.annotations(author_id);

-- Access Logs
CREATE INDEX idx_access_logs_tenant ON documents.access_logs(tenant_id);
CREATE INDEX idx_access_logs_document ON documents.access_logs(document_id);
CREATE INDEX idx_access_logs_user ON documents.access_logs(user_id);
CREATE INDEX idx_access_logs_accessed ON documents.access_logs(accessed_at);

-- Document Shares
CREATE INDEX idx_document_shares_tenant ON documents.document_shares(tenant_id);
CREATE INDEX idx_document_shares_document ON documents.document_shares(document_id);
CREATE INDEX idx_document_shares_token ON documents.document_shares(share_token);

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

ALTER TABLE documents.document_categories ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.documents ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.document_versions ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.document_permissions ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.approval_workflows ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.approval_instances ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.approval_steps ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.approval_actions ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.annotations ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.access_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE documents.document_shares ENABLE ROW LEVEL SECURITY;

-- ============================================================================
-- TRIGGERS DE AUDITORIA
-- ============================================================================

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

CREATE TRIGGER trg_document_categories_updated_at
    BEFORE UPDATE ON documents.document_categories
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_documents_updated_at
    BEFORE UPDATE ON documents.documents
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_document_permissions_updated_at
    BEFORE UPDATE ON documents.document_permissions
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_approval_workflows_updated_at
    BEFORE UPDATE ON documents.approval_workflows
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_approval_instances_updated_at
    BEFORE UPDATE ON documents.approval_instances
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_approval_steps_updated_at
    BEFORE UPDATE ON documents.approval_steps
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

CREATE TRIGGER trg_annotations_updated_at
    BEFORE UPDATE ON documents.annotations
    FOR EACH ROW EXECUTE FUNCTION documents.set_updated_at();

-- ============================================================================
-- FUNCIONES AUXILIARES
-- ============================================================================

-- Actualizar version actual del documento
CREATE OR REPLACE FUNCTION documents.update_current_version()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.status = 'current' THEN
        -- Marcar versiones anteriores como superseded
        UPDATE documents.document_versions
        SET status = 'superseded',
            superseded_at = NOW(),
            superseded_by_version_id = NEW.id
        WHERE document_id = NEW.document_id
          AND id != NEW.id
          AND status = 'current';

        -- Actualizar documento con version actual
        UPDATE documents.documents
        SET current_version_id = NEW.id,
            current_version_number = NEW.version_number,
            updated_at = NOW()
        WHERE id = NEW.document_id;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_update_current_version
    AFTER INSERT OR UPDATE ON documents.document_versions
    FOR EACH ROW EXECUTE FUNCTION documents.update_current_version();

-- Incrementar contador de vistas
CREATE OR REPLACE FUNCTION documents.increment_view_count()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.action = 'view' THEN
        UPDATE documents.documents
        SET view_count = view_count + 1,
            last_accessed_at = NOW()
        WHERE id = NEW.document_id;
    ELSIF NEW.action = 'download' THEN
        UPDATE documents.documents
        SET download_count = download_count + 1,
            last_accessed_at = NOW()
        WHERE id = NEW.document_id;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_increment_view_count
    AFTER INSERT ON documents.access_logs
    FOR EACH ROW EXECUTE FUNCTION documents.increment_view_count();

-- Actualizar path de categoria
CREATE OR REPLACE FUNCTION documents.update_category_path()
RETURNS TRIGGER AS $$
DECLARE
    v_parent_path VARCHAR(500);
BEGIN
    IF NEW.parent_id IS NULL THEN
        NEW.path := '/' || NEW.code;
        NEW.level := 1;
    ELSE
        SELECT path, level + 1 INTO v_parent_path, NEW.level
        FROM documents.document_categories
        WHERE id = NEW.parent_id;

        NEW.path := v_parent_path || '/' || NEW.code;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_update_category_path
    BEFORE INSERT OR UPDATE ON documents.document_categories
    FOR EACH ROW EXECUTE FUNCTION documents.update_category_path();

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

COMMENT ON SCHEMA documents IS 'Modulo de Gestion Documental (MAE-016) - ERP Construccion';

COMMENT ON TABLE documents.document_categories IS 'Categorias jerarquicas para clasificar documentos';
COMMENT ON TABLE documents.documents IS 'Registro principal de documentos';
COMMENT ON TABLE documents.document_versions IS 'Versiones de documentos con archivos';
COMMENT ON TABLE documents.document_permissions IS 'Permisos granulares por documento o categoria';
COMMENT ON TABLE documents.approval_workflows IS 'Definicion de flujos de aprobacion';
COMMENT ON TABLE documents.approval_instances IS 'Instancias de flujos de aprobacion activos';
COMMENT ON TABLE documents.approval_steps IS 'Pasos de aprobacion por instancia';
COMMENT ON TABLE documents.approval_actions IS 'Acciones tomadas en pasos de aprobacion';
COMMENT ON TABLE documents.annotations IS 'Anotaciones y comentarios sobre documentos';
COMMENT ON TABLE documents.access_logs IS 'Historial de acceso a documentos';
COMMENT ON TABLE documents.document_shares IS 'Links de compartido externo';

-- ============================================================================
-- FK CONSTRAINTS ADICIONALES
-- NOTA: Fortalecer referencias internas y externas del schema documents.
-- ============================================================================

-- FK: documents.parent_document_id → documents.documents (auto-referencia)
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'fk_documents_parent'
    ) THEN
        ALTER TABLE documents.documents
        ADD CONSTRAINT fk_documents_parent
        FOREIGN KEY (parent_document_id) REFERENCES documents.documents(id)
        ON DELETE SET NULL;
        RAISE NOTICE 'FK creada: documents.parent_document_id → documents.documents';
    END IF;
EXCEPTION WHEN OTHERS THEN
    RAISE NOTICE 'FK documents.parent_document_id no creada: %', SQLERRM;
END $$;

-- FK: access_logs.document_id → documents.documents (para mantener logs aunque doc se elimine)
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'fk_access_logs_document'
    ) THEN
        ALTER TABLE documents.access_logs
        ADD CONSTRAINT fk_access_logs_document
        FOREIGN KEY (document_id) REFERENCES documents.documents(id)
        ON DELETE CASCADE;
        RAISE NOTICE 'FK creada: access_logs.document_id → documents.documents';
    END IF;
EXCEPTION WHEN OTHERS THEN
    RAISE NOTICE 'FK access_logs.document_id no creada: %', SQLERRM;
END $$;

-- FK: access_logs.user_id → auth.users
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'users') THEN
        IF NOT EXISTS (
            SELECT 1 FROM pg_constraint WHERE conname = 'fk_access_logs_user'
        ) THEN
            ALTER TABLE documents.access_logs
            ADD CONSTRAINT fk_access_logs_user
            FOREIGN KEY (user_id) REFERENCES auth.users(id)
            ON DELETE SET NULL;
            RAISE NOTICE 'FK creada: access_logs.user_id → auth.users';
        END IF;
    END IF;
EXCEPTION WHEN OTHERS THEN
    RAISE NOTICE 'FK access_logs.user_id no creada: %', SQLERRM;
END $$;

-- FK: document_shares.shared_by_id → auth.users
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'users') THEN
        IF NOT EXISTS (
            SELECT 1 FROM pg_constraint WHERE conname = 'fk_document_shares_shared_by'
        ) THEN
            ALTER TABLE documents.document_shares
            ADD CONSTRAINT fk_document_shares_shared_by
            FOREIGN KEY (shared_by_id) REFERENCES auth.users(id)
            ON DELETE SET NULL;
            RAISE NOTICE 'FK creada: document_shares.shared_by_id → auth.users';
        END IF;
    END IF;
EXCEPTION WHEN OTHERS THEN
    RAISE NOTICE 'FK document_shares.shared_by_id no creada: %', SQLERRM;
END $$;

-- Índices adicionales para campos sin índice
CREATE INDEX IF NOT EXISTS idx_documents_parent ON documents.documents(parent_document_id);
CREATE INDEX IF NOT EXISTS idx_document_shares_shared_by ON documents.document_shares(shared_by_id);

-- ============================================================================
-- FIN DEL SCRIPT
-- FK constraints adicionales: 4
-- ============================================================================
