BEGIN;

CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE IF NOT EXISTS crm.cliente_objetivo_respuestas (
    respuesta_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    business_id VARCHAR(100) NOT NULL,
    sucursal_id INTEGER NOT NULL,
    id_cliente INTEGER NOT NULL REFERENCES crm.clientes(id_cliente) ON UPDATE CASCADE ON DELETE CASCADE,
    empleado_digital_id INTEGER NOT NULL DEFAULT 0,
    assistant_endpoint_id TEXT,
    objective_hash CHAR(64) NOT NULL,
    objective_item_fingerprint CHAR(64) NOT NULL,
    info_id INTEGER NOT NULL,
    info_texto TEXT NOT NULL,
    info_texto_normalized TEXT NOT NULL DEFAULT '',
    respuesta TEXT NOT NULL,
    confidence NUMERIC(5,4) NOT NULL DEFAULT 1.0000,
    source VARCHAR(80) NOT NULL,
    status VARCHAR(40) NOT NULL DEFAULT 'active',
    is_temporal BOOLEAN NOT NULL DEFAULT false,
    expires_at TIMESTAMPTZ,
    conversation_id TEXT,
    evidence JSONB NOT NULL DEFAULT '{}'::jsonb,
    objective_snapshot JSONB NOT NULL DEFAULT '{}'::jsonb,
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT chk_cliente_objetivo_respuestas_scope CHECK (
        business_id <> ''
        AND sucursal_id > 0
        AND id_cliente > 0
        AND empleado_digital_id >= 0
    ),
    CONSTRAINT chk_cliente_objetivo_respuestas_info CHECK (
        info_id > 0
        AND info_texto <> ''
        AND respuesta <> ''
    ),
    CONSTRAINT chk_cliente_objetivo_respuestas_confidence CHECK (
        confidence >= 0
        AND confidence <= 1
    ),
    CONSTRAINT chk_cliente_objetivo_respuestas_status CHECK (
        status IN ('active', 'ignored', 'rejected', 'expired', 'superseded')
    ),
    CONSTRAINT chk_cliente_objetivo_respuestas_json CHECK (
        jsonb_typeof(evidence) = 'object'
        AND jsonb_typeof(objective_snapshot) = 'object'
        AND jsonb_typeof(metadata) = 'object'
    )
);

CREATE UNIQUE INDEX IF NOT EXISTS cliente_objetivo_respuestas_active_uq
    ON crm.cliente_objetivo_respuestas (
        business_id,
        sucursal_id,
        id_cliente,
        empleado_digital_id,
        objective_hash,
        info_id
    )
    WHERE status = 'active';

CREATE INDEX IF NOT EXISTS cliente_objetivo_respuestas_cliente_idx
    ON crm.cliente_objetivo_respuestas (
        business_id,
        sucursal_id,
        id_cliente,
        empleado_digital_id,
        updated_at DESC
    );

CREATE INDEX IF NOT EXISTS cliente_objetivo_respuestas_fingerprint_idx
    ON crm.cliente_objetivo_respuestas (
        business_id,
        sucursal_id,
        id_cliente,
        empleado_digital_id,
        objective_item_fingerprint
    )
    WHERE status = 'active';

CREATE INDEX IF NOT EXISTS cliente_objetivo_respuestas_expiry_idx
    ON crm.cliente_objetivo_respuestas (expires_at)
    WHERE expires_at IS NOT NULL AND status = 'active';

COMMENT ON TABLE crm.cliente_objetivo_respuestas IS
    'Memoria canonica estructurada de respuestas aceptadas para objetivos del empleado digital por cliente.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.objective_hash IS
    'Hash canonico del objetivo vigente al momento de guardar la respuesta.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.objective_item_fingerprint IS
    'Fingerprint estable del punto de informacion para reconciliar cambios de objetivo.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.info_id IS
    'ID del punto de informacion relevante configurado para el objetivo.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.info_texto_normalized IS
    'Texto normalizado usado para matching deterministico entre versiones de objetivo.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.evidence IS
    'Evidencia no sensible de aceptacion: fuente, conversacion, fragmento y motivo.';
COMMENT ON COLUMN crm.cliente_objetivo_respuestas.objective_snapshot IS
    'Snapshot minimo del objetivo/item usado para auditar cambios de configuracion.';

COMMIT;
