-- V011__create_medio_seccion.sql
-- ADM-001 (Fase 1 CRITICAL PATH): Medios y Secciones — catálogo fundacional.
--
-- Cambios:
--   1. dbo.Medio (Codigo UQ global, TipoMedio enum 1..4, PlataformaEmpresaId NULL, SYSTEM_VERSIONING ON).
--   2. dbo.Seccion (FK MedioId, Codigo UQ por Medio, Tipo CHECK, SYSTEM_VERSIONING ON).
--   3. Permiso 'administracion:secciones:gestionar' + asignación a rol 'admin'.
--      El permiso 'administracion:medios:gestionar' ya existía desde V005.
--
-- Patrón: V007 (permisos MERGE) + V010 (Temporal Tables con retention 10 años + PAGE compression en history).
-- Idempotente: seguro para re-ejecutar.
-- Reversa: V011_ROLLBACK.sql.
-- Run on: SIGCM2 (dev) y SIGCM2_Test (integration tests).
--
-- Source of truth: Obsidian/02-ARQUITECTURA-y-TECH-STACK/2.10 📋 UDTs Módulo Administración.md (ADM-001)
-- Entidades: Obsidian/03-MODELO-de-DATOS/3.2 Entidades Core/3.2.1 🏢 Medio.md
-- Auditoría: Obsidian/02-ARQUITECTURA-y-TECH-STACK/2.5 📋 Auditoría.md

SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;
SET NOCOUNT ON;
GO

-- ═══════════════════════════════════════════════════════════════════════
-- 1. dbo.Medio
-- ═══════════════════════════════════════════════════════════════════════

IF OBJECT_ID(N'dbo.Medio', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.Medio (
        Id                   INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_Medio PRIMARY KEY,
        Codigo               VARCHAR(30)       NOT NULL,
        Nombre               NVARCHAR(100)     NOT NULL,
        Tipo                 TINYINT           NOT NULL,           -- TipoMedio: 1=Diario, 2=Radio, 3=Web, 4=Poster
        PlataformaEmpresaId  INT               NULL,               -- FK futura a INT-003 (IMAC mapping)
        Activo               BIT               NOT NULL CONSTRAINT DF_Medio_Activo            DEFAULT(1),
        FechaCreacion        DATETIME2(3)      NOT NULL CONSTRAINT DF_Medio_FechaCreacion     DEFAULT(SYSUTCDATETIME()),
        FechaModificacion    DATETIME2(3)      NULL,
        CONSTRAINT UQ_Medio_Codigo UNIQUE (Codigo),
        CONSTRAINT CK_Medio_Tipo   CHECK (Tipo BETWEEN 1 AND 4)
    );
    PRINT 'Table dbo.Medio created.';
END
ELSE
    PRINT 'Table dbo.Medio already exists — skip.';
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Medio_Activo_Tipo' AND object_id = OBJECT_ID('dbo.Medio'))
BEGIN
    CREATE INDEX IX_Medio_Activo_Tipo
        ON dbo.Medio(Activo, Tipo)
        INCLUDE (Codigo, Nombre, PlataformaEmpresaId);
    PRINT 'Index IX_Medio_Activo_Tipo created.';
END
GO

-- ═══════════════════════════════════════════════════════════════════════
-- 2. dbo.Seccion
-- ═══════════════════════════════════════════════════════════════════════

IF OBJECT_ID(N'dbo.Seccion', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.Seccion (
        Id                INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_Seccion PRIMARY KEY,
        MedioId           INT               NOT NULL,
        Codigo            VARCHAR(30)       NOT NULL,
        Nombre            NVARCHAR(100)     NOT NULL,
        Tipo              VARCHAR(20)       NOT NULL,     -- 'clasificados' | 'notables' | 'suplementos'
        Activo            BIT               NOT NULL CONSTRAINT DF_Seccion_Activo         DEFAULT(1),
        FechaCreacion     DATETIME2(3)      NOT NULL CONSTRAINT DF_Seccion_FechaCreacion  DEFAULT(SYSUTCDATETIME()),
        FechaModificacion DATETIME2(3)      NULL,
        CONSTRAINT FK_Seccion_Medio FOREIGN KEY (MedioId) REFERENCES dbo.Medio(Id) ON DELETE NO ACTION,
        CONSTRAINT UQ_Seccion_MedioId_Codigo UNIQUE (MedioId, Codigo),
        CONSTRAINT CK_Seccion_Tipo CHECK (Tipo IN ('clasificados','notables','suplementos'))
    );
    PRINT 'Table dbo.Seccion created.';
END
ELSE
    PRINT 'Table dbo.Seccion already exists — skip.';
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Seccion_MedioId_Activo' AND object_id = OBJECT_ID('dbo.Seccion'))
BEGIN
    CREATE INDEX IX_Seccion_MedioId_Activo
        ON dbo.Seccion(MedioId, Activo)
        INCLUDE (Codigo, Nombre, Tipo);
    PRINT 'Index IX_Seccion_MedioId_Activo created.';
END
GO

-- ═══════════════════════════════════════════════════════════════════════
-- 3. SYSTEM_VERSIONING — Medio
-- ═══════════════════════════════════════════════════════════════════════

IF COL_LENGTH('dbo.Medio', 'ValidFrom') IS NULL
BEGIN
    ALTER TABLE dbo.Medio
    ADD
        ValidFrom DATETIME2(3) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
            CONSTRAINT DF_Medio_ValidFrom DEFAULT(SYSUTCDATETIME()),
        ValidTo   DATETIME2(3) GENERATED ALWAYS AS ROW END   HIDDEN NOT NULL
            CONSTRAINT DF_Medio_ValidTo   DEFAULT(CONVERT(DATETIME2(3), '9999-12-31 23:59:59.999')),
        PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
    PRINT 'Medio: PERIOD FOR SYSTEM_TIME added.';
END
GO

IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('dbo.Medio') AND temporal_type = 2)
BEGIN
    ALTER TABLE dbo.Medio
    SET (SYSTEM_VERSIONING = ON (
        HISTORY_TABLE = dbo.Medio_History,
        HISTORY_RETENTION_PERIOD = 10 YEARS
    ));
    PRINT 'Medio: SYSTEM_VERSIONING = ON (history: dbo.Medio_History, retention: 10 years).';
END
ELSE
    PRINT 'Medio: SYSTEM_VERSIONING already ON — skip.';
GO

IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Medio_History' AND schema_id = SCHEMA_ID('dbo'))
   AND NOT EXISTS (
       SELECT 1 FROM sys.partitions p
       JOIN sys.tables t ON t.object_id = p.object_id
       WHERE t.name = 'Medio_History' AND p.data_compression = 2
   )
BEGIN
    ALTER TABLE dbo.Medio_History REBUILD WITH (DATA_COMPRESSION = PAGE);
    PRINT 'Medio_History: rebuilt with PAGE compression.';
END
GO

-- ═══════════════════════════════════════════════════════════════════════
-- 4. SYSTEM_VERSIONING — Seccion
-- ═══════════════════════════════════════════════════════════════════════

IF COL_LENGTH('dbo.Seccion', 'ValidFrom') IS NULL
BEGIN
    ALTER TABLE dbo.Seccion
    ADD
        ValidFrom DATETIME2(3) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
            CONSTRAINT DF_Seccion_ValidFrom DEFAULT(SYSUTCDATETIME()),
        ValidTo   DATETIME2(3) GENERATED ALWAYS AS ROW END   HIDDEN NOT NULL
            CONSTRAINT DF_Seccion_ValidTo   DEFAULT(CONVERT(DATETIME2(3), '9999-12-31 23:59:59.999')),
        PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
    PRINT 'Seccion: PERIOD FOR SYSTEM_TIME added.';
END
GO

IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('dbo.Seccion') AND temporal_type = 2)
BEGIN
    ALTER TABLE dbo.Seccion
    SET (SYSTEM_VERSIONING = ON (
        HISTORY_TABLE = dbo.Seccion_History,
        HISTORY_RETENTION_PERIOD = 10 YEARS
    ));
    PRINT 'Seccion: SYSTEM_VERSIONING = ON.';
END
ELSE
    PRINT 'Seccion: SYSTEM_VERSIONING already ON — skip.';
GO

IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Seccion_History' AND schema_id = SCHEMA_ID('dbo'))
   AND NOT EXISTS (
       SELECT 1 FROM sys.partitions p
       JOIN sys.tables t ON t.object_id = p.object_id
       WHERE t.name = 'Seccion_History' AND p.data_compression = 2
   )
BEGIN
    ALTER TABLE dbo.Seccion_History REBUILD WITH (DATA_COMPRESSION = PAGE);
    PRINT 'Seccion_History: rebuilt with PAGE compression.';
END
GO

-- ═══════════════════════════════════════════════════════════════════════
-- 5. Permiso nuevo: administracion:secciones:gestionar
--    ('administracion:medios:gestionar' ya fue sembrado en V005 — no se toca).
-- ═══════════════════════════════════════════════════════════════════════

MERGE dbo.Permiso AS t
USING (VALUES
    ('administracion:secciones:gestionar', N'Gestionar secciones por medio', N'Crear, editar y desactivar secciones de un medio', 'administracion')
) AS s (Codigo, Nombre, Descripcion, Modulo)
ON t.Codigo = s.Codigo
WHEN NOT MATCHED BY TARGET THEN
    INSERT (Codigo, Nombre, Descripcion, Modulo)
    VALUES (s.Codigo, s.Nombre, s.Descripcion, s.Modulo);
GO

MERGE dbo.RolPermiso AS t
USING (
    SELECT r.Id AS RolId, p.Id AS PermisoId
    FROM (VALUES
        ('admin', 'administracion:secciones:gestionar')
    ) AS x (RolCodigo, PermisoCodigo)
    JOIN dbo.Rol     r ON r.Codigo = x.RolCodigo
    JOIN dbo.Permiso p ON p.Codigo = x.PermisoCodigo
) AS s ON t.RolId = s.RolId AND t.PermisoId = s.PermisoId
WHEN NOT MATCHED BY TARGET THEN
    INSERT (RolId, PermisoId) VALUES (s.RolId, s.PermisoId);
GO

PRINT '';
PRINT 'V011 applied successfully — dbo.Medio + dbo.Seccion (temporal, retention 10y) + permiso secciones.';
PRINT 'Next: V012__seed_medios.sql (seed ELDIA, ELPLATA).';
GO
