-- =============================================
-- Módulo de Diezmos — Script SQL de migración
-- Ejecutar contra la BD de desarrollo/producción
-- Idempotente: usa IF NOT EXISTS / WHERE NOT EXISTS
-- =============================================

-- ─────────────────────────────────────────────
-- Tabla: diezmo_tipos_salida
-- Catálogo de tipos de salida (Entrega al Pastor, Gastos, etc.)
-- ─────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS public.diezmo_tipos_salida
(
    id              bigint      NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    nombre          varchar(100) NOT NULL,
    descripcion     varchar(300),
    es_entrega_pastor boolean NOT NULL DEFAULT false,
    activo          boolean     NOT NULL DEFAULT true,
    eliminado       boolean     NOT NULL DEFAULT false,
    creado_en       timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
    creado_por      varchar(100),
    actualizado_en  timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT diezmo_tipos_salida_pkey PRIMARY KEY (id)
);

COMMENT ON TABLE public.diezmo_tipos_salida IS 'Catálogo de tipos de salida del módulo de diezmos';

INSERT INTO public.diezmo_tipos_salida (nombre, descripcion, es_entrega_pastor, activo)
SELECT 'Entrega al Pastor', 'Entrega oficial de diezmos al pastor', true, true
WHERE NOT EXISTS (SELECT 1 FROM public.diezmo_tipos_salida WHERE es_entrega_pastor = true);

INSERT INTO public.diezmo_tipos_salida (nombre, descripcion, es_entrega_pastor, activo)
SELECT 'Gastos Administrativos', 'Gastos operativos de la iglesia', false, true
WHERE NOT EXISTS (SELECT 1 FROM public.diezmo_tipos_salida WHERE nombre = 'Gastos Administrativos');

-- ─────────────────────────────────────────────
-- Tabla: diezmo_beneficiarios
-- Personas o entidades que reciben salidas
-- ─────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS public.diezmo_beneficiarios
(
    id              bigint      NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    nombre          varchar(150) NOT NULL,
    descripcion     varchar(300),
    activo          boolean     NOT NULL DEFAULT true,
    eliminado       boolean     NOT NULL DEFAULT false,
    creado_en       timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
    creado_por      varchar(100),
    actualizado_en  timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
    actualizado_por varchar(100),
    CONSTRAINT diezmo_beneficiarios_pkey PRIMARY KEY (id)
);

COMMENT ON TABLE public.diezmo_beneficiarios IS 'Personas o entidades beneficiarias de salidas de diezmos';

-- ─────────────────────────────────────────────
-- Tabla: diezmo_cierres
-- Agregado raíz — un cierre por fecha (UNIQUE)
-- ─────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS public.diezmo_cierres
(
    id              bigint        NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    fecha           date          NOT NULL,
    cerrado         boolean       NOT NULL DEFAULT false,
    fecha_cierre    timestamptz,
    cerrado_por     varchar(100),
    observaciones   varchar(500),
    total_recibido  numeric(12,2) NOT NULL DEFAULT 0,
    total_cambio    numeric(12,2) NOT NULL DEFAULT 0,
    total_neto      numeric(12,2) NOT NULL DEFAULT 0,
    total_salidas   numeric(12,2) NOT NULL DEFAULT 0,
    saldo_final     numeric(12,2) NOT NULL DEFAULT 0,
    creado_en       timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    creado_por      varchar(100),
    actualizado_en  timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    actualizado_por varchar(100),
    eliminado       boolean       NOT NULL DEFAULT false,
    CONSTRAINT diezmo_cierres_pkey    PRIMARY KEY (id),
    CONSTRAINT diezmo_cierres_fecha_uq UNIQUE (fecha)
);

COMMENT ON TABLE public.diezmo_cierres IS 'Cierres periódicos del módulo de diezmos (un registro por fecha)';

CREATE INDEX IF NOT EXISTS idx_diezmo_cierres_fecha    ON public.diezmo_cierres (fecha);
CREATE INDEX IF NOT EXISTS idx_diezmo_cierres_cerrado  ON public.diezmo_cierres (cerrado);
CREATE INDEX IF NOT EXISTS idx_diezmo_cierres_eliminado ON public.diezmo_cierres (eliminado);

-- ─────────────────────────────────────────────
-- Tabla: diezmo_detalles
-- Diezmo individual por miembro dentro de un cierre
-- ─────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS public.diezmo_detalles
(
    id                bigint        NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    diezmo_cierre_id  bigint        NOT NULL,
    miembro_id        bigint        NOT NULL,
    monto_entregado   numeric(12,2) NOT NULL CHECK (monto_entregado >= 0),
    cambio_entregado  numeric(12,2) NOT NULL DEFAULT 0 CHECK (cambio_entregado >= 0),
    monto_neto        numeric(12,2) NOT NULL DEFAULT 0,
    observaciones     varchar(300),
    fecha             timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    creado_por        varchar(100),
    creado_en         timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    actualizado_en    timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    actualizado_por   varchar(100),
    eliminado         boolean       NOT NULL DEFAULT false,
    CONSTRAINT diezmo_detalles_pkey PRIMARY KEY (id),
    CONSTRAINT fk_diezmo_detalles_cierre
        FOREIGN KEY (diezmo_cierre_id) REFERENCES public.diezmo_cierres (id)
        ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_diezmo_detalles_miembro
        FOREIGN KEY (miembro_id) REFERENCES public.miembros (id)
        ON UPDATE CASCADE ON DELETE RESTRICT
);

COMMENT ON TABLE public.diezmo_detalles IS 'Diezmos individuales aportados por miembro en cada cierre';

CREATE INDEX IF NOT EXISTS idx_diezmo_detalles_cierre_id  ON public.diezmo_detalles (diezmo_cierre_id);
CREATE INDEX IF NOT EXISTS idx_diezmo_detalles_miembro_id ON public.diezmo_detalles (miembro_id);
CREATE INDEX IF NOT EXISTS idx_diezmo_detalles_eliminado  ON public.diezmo_detalles (eliminado);

-- ─────────────────────────────────────────────
-- Tabla: diezmo_salidas
-- Salida de fondos registrada contra un cierre
-- ─────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS public.diezmo_salidas
(
    id                bigint        NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    diezmo_cierre_id  bigint        NOT NULL,
    tipo_salida_id    bigint        NOT NULL,
    beneficiario_id   bigint,
    monto             numeric(12,2) NOT NULL CHECK (monto > 0),
    concepto          varchar(300)  NOT NULL,
    numero_recibo     varchar(30),
    fecha             timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    creado_por        varchar(100),
    creado_en         timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    actualizado_en    timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    eliminado         boolean       NOT NULL DEFAULT false,
    CONSTRAINT diezmo_salidas_pkey PRIMARY KEY (id),
    CONSTRAINT fk_diezmo_salidas_cierre
        FOREIGN KEY (diezmo_cierre_id) REFERENCES public.diezmo_cierres (id)
        ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_diezmo_salidas_tipo
        FOREIGN KEY (tipo_salida_id) REFERENCES public.diezmo_tipos_salida (id)
        ON UPDATE CASCADE ON DELETE RESTRICT,
    CONSTRAINT fk_diezmo_salidas_beneficiario
        FOREIGN KEY (beneficiario_id) REFERENCES public.diezmo_beneficiarios (id)
        ON UPDATE CASCADE ON DELETE RESTRICT
);

COMMENT ON TABLE public.diezmo_salidas IS 'Salidas de fondos (entregas, gastos) registradas en un cierre de diezmos';

CREATE INDEX IF NOT EXISTS idx_diezmo_salidas_cierre_id ON public.diezmo_salidas (diezmo_cierre_id);
CREATE INDEX IF NOT EXISTS idx_diezmo_salidas_eliminado ON public.diezmo_salidas (eliminado);

-- =============================================
-- Bitácora de operaciones críticas del módulo
-- =============================================
CREATE TABLE IF NOT EXISTS public.diezmo_bitacora
(
    id              bigint        NOT NULL GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 CACHE 1),
    diezmo_cierre_id bigint,
    accion          varchar(50)   NOT NULL,  -- 'CIERRE', 'REAPERTURA', 'ELIMINAR_DETALLE', 'ELIMINAR_SALIDA'
    detalle         varchar(500),
    realizado_por   varchar(100)  NOT NULL,
    realizado_en    timestamptz   NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT diezmo_bitacora_pkey PRIMARY KEY (id)
);

CREATE INDEX IF NOT EXISTS idx_diezmo_bitacora_cierre_id ON public.diezmo_bitacora (diezmo_cierre_id);

-- =============================================
-- Permisos para el módulo
-- =============================================

-- Crear módulo si no existe
INSERT INTO public.modulos (nombre, descripcion, icono, orden, activo)
SELECT 'Diezmos', 'Módulo de gestión de diezmos', 'bi bi-cash-coin', 50, true
WHERE NOT EXISTS (SELECT 1 FROM public.modulos WHERE nombre = 'Diezmos');

-- Permiso: ver listado de cierres
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.Index', 'Ver Diezmos', 'Permite ver el listado de cierres de diezmos',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.Index');

-- Permiso: crear cierre
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.Create', 'Crear Cierre', 'Permite crear un nuevo cierre de diezmos',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.Create');

-- Permiso: registrar detalle (diezmo por miembro)
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.AddDetalle', 'Registrar Detalle', 'Permite agregar/eliminar diezmos de miembros en un cierre',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.AddDetalle');

-- Permiso: registrar salida
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.AddSalida', 'Registrar Salida', 'Permite registrar salidas/entregas en un cierre',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.AddSalida');

-- Permiso: cerrar cierre
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.Close', 'Cerrar Cierre', 'Permite cerrar un cierre de diezmos (bloquea edición)',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.Close');

-- Permiso: reabrir cierre (solo Administrador)
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.Reopen', 'Reabrir Cierre', 'Permite reabrir un cierre cerrado (solo Administrador)',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.Reopen');

-- Permiso: reportes y consultas
INSERT INTO public.permisos (codigo, nombre, descripcion, modulo_id, activo)
SELECT 'Diezmo.Reportes', 'Reportes Diezmos', 'Permite ver reportes y estado de cuenta del módulo de diezmos',
       (SELECT id FROM public.modulos WHERE nombre = 'Diezmos'), true
WHERE NOT EXISTS (SELECT 1 FROM public.permisos WHERE codigo = 'Diezmo.Reportes');
