-- =============================================================================
-- MICHANGARRITO - 18 WEBHOOKS (MCH-029: Infraestructura SaaS)
-- =============================================================================
-- Sistema de webhooks salientes para integraciones externas
-- Permite a los tenants recibir notificaciones de eventos en sus sistemas
-- =============================================================================

-- Tipos de evento webhook
CREATE TYPE webhook_event_type AS ENUM (
    -- Ventas
    'sale.created',
    'sale.completed',
    'sale.cancelled',
    'sale.refunded',

    -- Productos
    'product.created',
    'product.updated',
    'product.deleted',
    'product.low_stock',

    -- Clientes
    'customer.created',
    'customer.updated',

    -- Fiados
    'credit.created',
    'credit.payment',
    'credit.overdue',

    -- Pedidos
    'order.created',
    'order.confirmed',
    'order.delivered',
    'order.cancelled',

    -- Suscripciones
    'subscription.created',
    'subscription.renewed',
    'subscription.cancelled',
    'subscription.expired'
);

-- Endpoints de webhook
CREATE TABLE IF NOT EXISTS webhooks.endpoints (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,

    -- Configuracion
    name VARCHAR(100) NOT NULL,
    url VARCHAR(500) NOT NULL,
    secret VARCHAR(255) NOT NULL,  -- Para firma HMAC-SHA256

    -- Eventos suscritos
    events webhook_event_type[] NOT NULL,

    -- Estado
    is_active BOOLEAN DEFAULT true,

    -- Rate limiting
    rate_limit INTEGER DEFAULT 100,  -- requests por minuto

    -- Estadisticas
    total_deliveries INTEGER DEFAULT 0,
    failed_deliveries INTEGER DEFAULT 0,
    last_delivery_at TIMESTAMPTZ,
    last_failure_at TIMESTAMPTZ,

    -- Timestamps
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_webhooks_endpoints_tenant ON webhooks.endpoints(tenant_id);
CREATE INDEX idx_webhooks_endpoints_active ON webhooks.endpoints(tenant_id, is_active) WHERE is_active = true;

CREATE TRIGGER update_webhooks_endpoints_updated_at
    BEFORE UPDATE ON webhooks.endpoints
    FOR EACH ROW EXECUTE FUNCTION update_updated_at();

COMMENT ON TABLE webhooks.endpoints IS 'Endpoints de webhook configurados por tenant';
COMMENT ON COLUMN webhooks.endpoints.secret IS 'Secret para firma HMAC-SHA256 del payload';
COMMENT ON COLUMN webhooks.endpoints.events IS 'Array de tipos de evento suscritos';

-- Estado de entrega
CREATE TYPE webhook_delivery_status AS ENUM (
    'pending',
    'success',
    'failed',
    'retrying'
);

-- Entregas de webhook (log)
CREATE TABLE IF NOT EXISTS webhooks.deliveries (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    endpoint_id UUID NOT NULL REFERENCES webhooks.endpoints(id) ON DELETE CASCADE,

    -- Evento
    event_type webhook_event_type NOT NULL,
    event_id VARCHAR(100),  -- ID del evento original (sale_id, order_id, etc.)
    payload JSONB NOT NULL,

    -- Estado de entrega
    status webhook_delivery_status DEFAULT 'pending',

    -- Respuesta
    response_code INTEGER,
    response_body TEXT,
    response_time_ms INTEGER,

    -- Reintentos
    attempts INTEGER DEFAULT 0,
    max_attempts INTEGER DEFAULT 5,
    next_retry_at TIMESTAMPTZ,

    -- Timestamps
    created_at TIMESTAMPTZ DEFAULT NOW(),
    delivered_at TIMESTAMPTZ
);

CREATE INDEX idx_webhooks_deliveries_endpoint ON webhooks.deliveries(endpoint_id);
CREATE INDEX idx_webhooks_deliveries_status ON webhooks.deliveries(status) WHERE status IN ('pending', 'retrying');
CREATE INDEX idx_webhooks_deliveries_retry ON webhooks.deliveries(next_retry_at) WHERE status = 'retrying';
CREATE INDEX idx_webhooks_deliveries_created ON webhooks.deliveries(created_at DESC);

COMMENT ON TABLE webhooks.deliveries IS 'Log de entregas de webhooks';
COMMENT ON COLUMN webhooks.deliveries.attempts IS 'Numero de intentos realizados';
COMMENT ON COLUMN webhooks.deliveries.next_retry_at IS 'Timestamp del proximo reintento (backoff exponencial)';

-- =============================================================================
-- FUNCION: Calcular siguiente retry con backoff exponencial
-- =============================================================================

CREATE OR REPLACE FUNCTION webhooks.calculate_next_retry(attempts INTEGER)
RETURNS TIMESTAMPTZ AS $$
BEGIN
    -- Backoff exponencial: 1min, 5min, 15min, 1hr, 4hr
    RETURN NOW() + (POWER(2, LEAST(attempts, 5)) * INTERVAL '1 minute');
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION webhooks.calculate_next_retry IS 'Calcula el timestamp del siguiente reintento con backoff exponencial';
