
-- Tablas para el seguimiento de las operaciones de SIM sin importar
-- la cmpañia.
DO $$ BEGIN
  CREATE TYPE order_types AS ENUM ('activate','preactivate','cancel','pause','reactivate','unknown');
  CREATE TYPE order_status AS ENUM (
      'pending',      -- Mensaje creado/enviado a RabbitMQ
      'running',      -- Consumidor ha cogido el mensaje (opcional)
      'finished',    -- Procesado correctamente
      'failed',       -- Falló, pero podría reintentarse (Pasar a delay?)
      'dlx'           -- Falló definitivamente y está en Dead Letter Exchange
  );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

CREATE TABLE IF NOT EXISTS order_tracking (
    id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    correlation_id VARCHAR(255) NOT NULL,                    -- ID compartido con RabbitMQ (message_id)
    exchange VARCHAR(100),                                   -- Exchange al que se envia (de momento solo hay 1 principal sin contar delay y dlx)
    routing_key VARCHAR(100),                                -- Routing key del mensaje
    order_type order_types NOT NULL DEFAULT 'unknown',

    payload JSONB,                                          -- Duda si es optimo guardar la copia, es útil en caso de fallo
    
    -- Campos de reintentos?

    status order_status NOT NULL DEFAULT 'pending',
    retry_count INT DEFAULT 0,
    error_message TEXT,                                      -- Razón del fallo
    error_stacktrace TEXT,
    
    start_date        TIMESTAMP NOT NULL DEFAULT (now() at time zone 'utc'),
    update_date       TIMESTAMP NOT NULL DEFAULT (now() at time zone 'utc'),
    finish_date     TIMESTAMP
);

-- Busqueda según id de rabbit
CREATE INDEX IF NOT EXISTS idx_order_correlation 
  ON order_tracking(correlation_id);
-- Ordenenes que todavia no han finalizado
CREATE INDEX IF NOT EXISTS pending_orders
  ON order_tracking(start_date)
  WHERE order_tracking.finish_date IS NULL;

CREATE TABLE IF NOT EXISTS order_history(
    id                            BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    order_id                      BIGINT NOT NULL,
    previous_status               order_status NOT NULL, -- Siempre hay un estado anterior, para casos excepcioneale "unknown"
    new_status                    order_status NOT NULL, 
    change_reason                 TEXT, 
    change_date                   TIMESTAMP NOT NULL DEFAULT (now() at time zone 'utc'),

    CONSTRAINT fk_order_id
        FOREIGN KEY(order_id) 
        REFERENCES order_tracking(id)
        ON DELETE CASCADE
);

-- fk de order
CREATE INDEX IF NOT EXISTS idx_order_id
  ON order_history(order_id);

-- busquedas por fecha
CREATE INDEX IF NOT EXISTS idx_order_change_date 
  ON order_history(change_date);

