-- eliminar los drop para prod
drop domain if exists imei_type cascade;
CREATE DOMAIN imei_type as varchar(15);
drop domain if exists iccid_type cascade;
CREATE DOMAIN iccid_type as varchar(22);
drop domain if exists imsi_type cascade;
CREATE DOMAIN imsi_type as varchar(15);


CREATE table if not exists sim_cards (
    id          BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    imei        imei_type,
    iccid       iccid_type,
    imsi        imsi_type,
    user_id      BIGINT,
    subscription_id BIGINT,
    created_at    TIMESTAMP,
    last_update   TIMESTAMP,
    deleted_at    TIMESTAMP
);


CREATE TABLE if not exists sim_envio (
    id              BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    codigo_origen    TEXT,
    codigo_distrito  TEXT,
    pedido_id       BIGINT,
    sim_id          BIGINT,

    fecha_envio     TIMESTAMP,
    fecha_email     TIMESTAMP,
    is_preactivado  BOOLEAN,
    fecha_devolucion TIMESTAMP,
    created_at      TIMESTAMP,

    CONSTRAINT fk_sim_id
        FOREIGN KEY(sim_id) REFERENCES sim_cards(id)
);

-- Mock, No es parte de SIMs
CREATE TABLE if not exists sf_subscription (
    id              BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
);

-- No habria que meterle las propiedades del tipo de subscripcion
CREATE TABLE if not exists sim_subscription_types (
    id              INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    subscription    TEXT NOT NULL,
    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    deleted_at      TIMESTAMP
);

CREATE TABLE if not exists sim_company (
    id              INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    name    TEXT,
    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    deleted_at      TIMESTAMP
);

CREATE TABLE sim_subscription (
    id              BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    company_id      INT,
    subscription_type_id INT,
    sim_id          BIGINT,
    order_id        BIGINT,

    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    deleted_at      TIMESTAMP,

    CONSTRAINT fk_sim_id
        FOREIGN KEY(sim_id) REFERENCES sim_cards(id),

    CONSTRAINT fk_company_id
        FOREIGN KEY(company_id) REFERENCES sim_company(id),

    CONSTRAINT fk_subscription_type_id
        FOREIGN KEY(subscription_type_id) REFERENCES sim_subscription_types(id)
);

CREATE TABLE if not exists sim_subscription_operations (
    id          BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    sim_id       BIGINT,
    operation_type TEXT NOT NULL,
    happened_at  TIMESTAMP,
    
    CONSTRAINT valid_operations CHECK (
      operation_type in ('free','preactivate','activate','pause','cancel')
    ),
    
    CONSTRAINT fk_subscription_id
        FOREIGN KEY(sim_id)
        REFERENCES sim_subscription(id)
);

-- Se supone que indica un cambio
CREATE TABLE sim_subscription_historic (
    id              BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    subscription_id BIGINT,
    iccid   iccid_type,
    company_id INT
);

CREATE TYPE status_enum AS ENUM ('noRequestID','noMassID','running','finished','error','other');

-- Tabla para gestionar las peticiones de cambio de objenious.
-- Para una o mas lineas se pueden lanzar operacione que no sabemos
-- con certeza cuando van a terminar.
CREATE TABLE if not exists objenious_operation (
    id          BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    retry_count INT DEFAULT 0,
    max_retry    INT DEFAULT 5,
    max_date_retry TIMESTAMP DEFAULT NULL,
    iccids      TEXT,
    request_id  TEXT,
    mass_action_id  TEXT,
    operation TEXT NOT NULL,
    start_date  TIMESTAMP NOT NULL DEFAULT now(),
    last_change_date TIMESTAMP NOT NULL DEFAULT now(),
    end_date    TIMESTAMP,
    error       TEXT,
    status      status_enum
);

-- operaciones pendientes para revisar
CREATE INDEX IF NOT EXISTS pending_operations
  ON objenious_operation(start_date)
  WHERE end_date IS NULL;

CREATE TABLE if not exists objenious_operation_change (
    id          BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    operation_id  BIGINT,
    creation_date TIMESTAMP NOT NULL DEFAULT now(),
    error         TEXT,
    new_status    status_enum,
    new_request_id  TEXT,
    new_mass_action_id TEXT,
    CONSTRAINT fk_operation_id
        FOREIGN KEY(operation_id) REFERENCES objenious_operation(id)
);

CREATE INDEX operation_change
  ON objenious_operation_change(operation_id);
