-- Drop existing tables (cuidado, esto borrará todos los datos)
DROP TABLE IF EXISTS facturacion_servicio_interacciones;
DROP TABLE IF EXISTS facturacion_eventos_factura;
DROP TABLE IF exists facturacion_facturas;
DROP TABLE IF exists facturacion_dlq;


-- Primero, establecer la zona horaria para la sesión
SET TIME ZONE 'America/La_Paz';


-- Create the facturas table
CREATE TABLE facturacion_facturas (
      id UUID PRIMARY KEY,
      fecha_emision TIMESTAMP NOT NULL,
      estado VARCHAR(20) NOT NULL DEFAULT 'PENDIENTE',
      cuf VARCHAR(100),
      url VARCHAR(250),
      codigo_documento_sector SMALLINT CHECK (codigo_documento_sector BETWEEN 0 AND 99),
      factura TEXT,
      factura_firmada TEXT,
      mensaje_respuesta_soap Text,
      fecha_creacion TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      registro_empresa_id INTEGER NOT NULL,
      CONSTRAINT fk_cuis_registroempresa FOREIGN KEY (registro_empresa_id) REFERENCES registroEmpresa(id) ON UPDATE CASCADE ON DELETE CASCADE
);

CREATE TABLE facturacion_servicio_interacciones (
    id SERIAL PRIMARY KEY,
    factura_id UUID NOT NULL,
    tipo_servicio VARCHAR(50) NOT NULL,
    endpoint VARCHAR(255) NOT NULL,
    request_body TEXT,
    response_body TEXT,
    msg_soap TEXT,
    status_code INTEGER,
    duracion_ms BIGINT,
    exitoso BOOLEAN NOT NULL,
    fecha_creacion TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_interacciones_factura FOREIGN KEY (factura_id)
        REFERENCES facturacion_facturas(id)
        ON DELETE CASCADE
);

-- Recreate with proper cascade
CREATE TABLE facturacion_eventos_factura (
     id SERIAL PRIMARY KEY,
     factura_id UUID NOT NULL,
     estado_anterior VARCHAR(20) NOT NULL,
     estado_nuevo VARCHAR(20) NOT NULL,
     detalles TEXT,
     fecha_creacion TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
     CONSTRAINT fk_eventos_factura FOREIGN KEY (factura_id)
         REFERENCES facturacion_facturas(id)
         ON DELETE CASCADE
);

-- Create the dlq table with foreign key relationship
CREATE TABLE facturacion_dlq (
     id SERIAL PRIMARY KEY,
     transaccion_id UUID NOT NULL,
     mensaje TEXT NOT NULL,
     estado VARCHAR(20),
     fecha_creacion TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
     reprocesado BOOLEAN NOT NULL DEFAULT FALSE,
     CONSTRAINT fk_dlq_factura FOREIGN KEY (transaccion_id)
         REFERENCES facturacion_facturas(id)
         ON DELETE CASCADE
);


-- Recreate indexes
CREATE INDEX idx_eventos_factura_id ON facturacion_eventos_factura(factura_id);
CREATE INDEX idx_interacciones_factura_id ON facturacion_servicio_interacciones(factura_id);
CREATE INDEX idx_facturas_estado ON facturacion_facturas(estado);
CREATE INDEX idx_dlq_transaccion_id ON facturacion_dlq(transaccion_id);
CREATE INDEX idx_dlq_reprocesado ON facturacion_dlq(reprocesado);


-- triggers ------------------------------------------------------------------
-- Crea la función que ejecutará el trigger
CREATE OR REPLACE FUNCTION actualizar_estado_factura()
RETURNS TRIGGER AS $$
BEGIN
    -- Actualiza el estado de la factura con el valor del estado en la tabla DLQ
    -- Si el estado es NULL, usa 'ERROR' como valor predeterminado
UPDATE facturacion_facturas
SET estado = COALESCE(NEW.estado, 'ERROR')
WHERE id = NEW.transaccion_id;

RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Crea el trigger que llama a esta función después de cada inserción en la tabla DLQ
CREATE TRIGGER trigger_actualizar_estado_factura
    AFTER INSERT ON facturacion_dlq
    FOR EACH ROW
    EXECUTE FUNCTION actualizar_estado_factura();
--------------------------------------------------------------------------------


-- Primero creamos la función que se ejecutará con el trigger------------------------------------
CREATE OR REPLACE FUNCTION actualizar_mensaje_respuesta_soap()
RETURNS TRIGGER AS $$
BEGIN
    -- Actualizamos el campo mensaje_respuesta_soap en la tabla facturacion_facturas
    -- cuando se inserta un nuevo registro en facturacion_servicio_interacciones
    -- y el campo msg_soap no es nulo
    IF NEW.msg_soap IS NOT NULL THEN
UPDATE facturacion_facturas
SET mensaje_respuesta_soap = NEW.msg_soap
WHERE id = NEW.factura_id;
END IF;

RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Ahora creamos el trigger que ejecutará la función
CREATE TRIGGER trigger_actualizar_mensaje_respuesta
    AFTER INSERT ON facturacion_servicio_interacciones
    FOR EACH ROW
    EXECUTE FUNCTION actualizar_mensaje_respuesta_soap();
-- triggers ------------------------------------------------------------------

SHOW timezone;
-- Verificar que las fechas se estén guardando correctamente
SELECT current_timestamp, current_timestamp AT TIME ZONE 'America/La_Paz';


-- Create the dlq table
-- CREATE TABLE facturacion_dlq (
--      id SERIAL PRIMARY KEY,
--      transaccion_id UUID NOT NULL,
--      mensaje TEXT NOT NULL,
--      estado VARCHAR(20),
--      fecha_creacion TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
--      reprocesado BOOLEAN NOT NULL DEFAULT FALSE
-- );