-- =============================================================
-- ARCHIVO: 08-plans.sql
-- DESCRIPCION: Extensiones de planes SaaS (features, limits, Stripe)
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-10
-- EPIC: SAAS-BILLING (EPIC-SAAS-002)
-- HISTORIAS: US-007, US-010, US-011, US-012
-- =============================================================

-- =====================
-- MODIFICACIONES A TABLAS EXISTENTES
-- =====================

-- Agregar columnas Stripe a tenant_subscriptions (US-007, US-008)
ALTER TABLE billing.tenant_subscriptions
ADD COLUMN IF NOT EXISTS stripe_customer_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS stripe_subscription_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS stripe_payment_method_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS stripe_price_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS trial_ends_at TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS canceled_at TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS cancel_at TIMESTAMPTZ;

-- Agregar columnas Stripe a subscription_plans
ALTER TABLE billing.subscription_plans
ADD COLUMN IF NOT EXISTS stripe_product_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS stripe_price_id_monthly VARCHAR(255),
ADD COLUMN IF NOT EXISTS stripe_price_id_annual VARCHAR(255);

-- Agregar columnas Stripe a payment_methods
ALTER TABLE billing.payment_methods
ADD COLUMN IF NOT EXISTS stripe_payment_method_id VARCHAR(255);

-- Indices para campos Stripe
CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_customer ON billing.tenant_subscriptions(stripe_customer_id) WHERE stripe_customer_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_sub ON billing.tenant_subscriptions(stripe_subscription_id) WHERE stripe_subscription_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_plans_stripe_product ON billing.subscription_plans(stripe_product_id) WHERE stripe_product_id IS NOT NULL;

-- =====================
-- TABLA: billing.plan_features
-- Features habilitadas por plan (US-010, US-011)
-- =====================
CREATE TABLE IF NOT EXISTS billing.plan_features (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    plan_id UUID NOT NULL REFERENCES billing.subscription_plans(id) ON DELETE CASCADE,

    -- Identificacion
    feature_key VARCHAR(100) NOT NULL,
    feature_name VARCHAR(255) NOT NULL,
    category VARCHAR(100),

    -- Estado
    enabled BOOLEAN DEFAULT TRUE,

    -- Configuracion
    configuration JSONB DEFAULT '{}',

    -- Metadata
    description TEXT,
    metadata JSONB DEFAULT '{}',

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(plan_id, feature_key)
);

-- Indices para plan_features
CREATE INDEX IF NOT EXISTS idx_plan_features_plan ON billing.plan_features(plan_id);
CREATE INDEX IF NOT EXISTS idx_plan_features_key ON billing.plan_features(feature_key);
CREATE INDEX IF NOT EXISTS idx_plan_features_enabled ON billing.plan_features(plan_id, enabled) WHERE enabled = TRUE;

-- =====================
-- TABLA: billing.plan_limits
-- Limites cuantificables por plan (US-010, US-012)
-- =====================
CREATE TABLE IF NOT EXISTS billing.plan_limits (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    plan_id UUID NOT NULL REFERENCES billing.subscription_plans(id) ON DELETE CASCADE,

    -- Identificacion
    limit_key VARCHAR(100) NOT NULL,
    limit_name VARCHAR(255) NOT NULL,

    -- Valor
    limit_value INTEGER NOT NULL,
    limit_type VARCHAR(50) DEFAULT 'monthly', -- monthly, daily, total, per_user

    -- Overage (si se permite exceder)
    allow_overage BOOLEAN DEFAULT FALSE,
    overage_unit_price DECIMAL(10,4) DEFAULT 0,
    overage_currency VARCHAR(3) DEFAULT 'MXN',

    -- Alertas
    alert_threshold_percent INTEGER DEFAULT 80,
    hard_limit BOOLEAN DEFAULT TRUE, -- Si true, bloquea; si false, solo alerta

    -- Metadata
    description TEXT,
    metadata JSONB DEFAULT '{}',

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(plan_id, limit_key)
);

-- Indices para plan_limits
CREATE INDEX IF NOT EXISTS idx_plan_limits_plan ON billing.plan_limits(plan_id);
CREATE INDEX IF NOT EXISTS idx_plan_limits_key ON billing.plan_limits(limit_key);

-- =====================
-- TABLA: billing.coupons
-- Cupones de descuento
-- =====================
CREATE TABLE IF NOT EXISTS billing.coupons (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Identificacion
    code VARCHAR(50) NOT NULL UNIQUE,
    name VARCHAR(255) NOT NULL,
    description TEXT,

    -- Descuento
    discount_type VARCHAR(20) NOT NULL CHECK (discount_type IN ('percentage', 'fixed')),
    discount_value DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'MXN',

    -- Aplicabilidad
    applicable_plans UUID[] DEFAULT '{}',  -- Vacio = todos
    min_amount DECIMAL(10,2) DEFAULT 0,

    -- Limites
    max_redemptions INTEGER,
    times_redeemed INTEGER DEFAULT 0,
    max_redemptions_per_customer INTEGER DEFAULT 1,

    -- Vigencia
    valid_from TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    valid_until TIMESTAMPTZ,

    -- Duracion del descuento
    duration VARCHAR(20) DEFAULT 'once', -- once, forever, repeating
    duration_months INTEGER, -- Si duration = repeating

    -- Stripe
    stripe_coupon_id VARCHAR(255),

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Indices para coupons
CREATE INDEX IF NOT EXISTS idx_coupons_code ON billing.coupons(code);
CREATE INDEX IF NOT EXISTS idx_coupons_active ON billing.coupons(is_active, valid_until);

-- =====================
-- TABLA: billing.coupon_redemptions
-- Uso de cupones
-- =====================
CREATE TABLE IF NOT EXISTS billing.coupon_redemptions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    coupon_id UUID NOT NULL REFERENCES billing.coupons(id),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
    subscription_id UUID REFERENCES billing.tenant_subscriptions(id),

    -- Descuento aplicado
    discount_amount DECIMAL(10,2) NOT NULL,

    -- Timestamps
    redeemed_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    expires_at TIMESTAMPTZ,

    UNIQUE(coupon_id, tenant_id)
);

-- Indices para coupon_redemptions
CREATE INDEX IF NOT EXISTS idx_coupon_redemptions_coupon ON billing.coupon_redemptions(coupon_id);
CREATE INDEX IF NOT EXISTS idx_coupon_redemptions_tenant ON billing.coupon_redemptions(tenant_id);

-- =====================
-- TABLA: billing.stripe_events
-- Log de eventos de Stripe (US-008)
-- =====================
CREATE TABLE IF NOT EXISTS billing.stripe_events (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Evento de Stripe
    stripe_event_id VARCHAR(255) NOT NULL UNIQUE,
    event_type VARCHAR(100) NOT NULL,
    api_version VARCHAR(20),

    -- Datos
    data JSONB NOT NULL,

    -- Procesamiento
    processed BOOLEAN DEFAULT FALSE,
    processed_at TIMESTAMPTZ,
    error_message TEXT,
    retry_count INTEGER DEFAULT 0,

    -- Tenant relacionado (si aplica)
    tenant_id UUID REFERENCES auth.tenants(id),

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Indices para stripe_events
CREATE INDEX IF NOT EXISTS idx_stripe_events_type ON billing.stripe_events(event_type);
CREATE INDEX IF NOT EXISTS idx_stripe_events_processed ON billing.stripe_events(processed) WHERE processed = FALSE;
CREATE INDEX IF NOT EXISTS idx_stripe_events_tenant ON billing.stripe_events(tenant_id);

-- =====================
-- RLS POLICIES
-- =====================
ALTER TABLE billing.plan_features ENABLE ROW LEVEL SECURITY;
-- Plan features son globales, no requieren isolation
CREATE POLICY public_read_plan_features ON billing.plan_features
    FOR SELECT USING (true);

ALTER TABLE billing.plan_limits ENABLE ROW LEVEL SECURITY;
-- Plan limits son globales, no requieren isolation
CREATE POLICY public_read_plan_limits ON billing.plan_limits
    FOR SELECT USING (true);

ALTER TABLE billing.coupons ENABLE ROW LEVEL SECURITY;
-- Cupones son globales pero solo admins pueden modificar
CREATE POLICY public_read_coupons ON billing.coupons
    FOR SELECT USING (is_active = TRUE);

ALTER TABLE billing.coupon_redemptions ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_coupon_redemptions ON billing.coupon_redemptions
    USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

ALTER TABLE billing.stripe_events ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_stripe_events ON billing.stripe_events
    USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid OR tenant_id IS NULL);

-- =====================
-- FUNCIONES
-- =====================

-- Funcion para verificar si un tenant tiene una feature habilitada
CREATE OR REPLACE FUNCTION billing.has_feature(
    p_tenant_id UUID,
    p_feature_key VARCHAR(100)
)
RETURNS BOOLEAN AS $$
DECLARE
    v_enabled BOOLEAN;
BEGIN
    SELECT pf.enabled INTO v_enabled
    FROM billing.tenant_subscriptions ts
    JOIN billing.plan_features pf ON pf.plan_id = ts.plan_id
    WHERE ts.tenant_id = p_tenant_id
    AND ts.status = 'active'
    AND pf.feature_key = p_feature_key;

    RETURN COALESCE(v_enabled, FALSE);
END;
$$ LANGUAGE plpgsql STABLE;

-- Funcion para obtener limite de un tenant
CREATE OR REPLACE FUNCTION billing.get_limit(
    p_tenant_id UUID,
    p_limit_key VARCHAR(100)
)
RETURNS INTEGER AS $$
DECLARE
    v_limit INTEGER;
BEGIN
    SELECT pl.limit_value INTO v_limit
    FROM billing.tenant_subscriptions ts
    JOIN billing.plan_limits pl ON pl.plan_id = ts.plan_id
    WHERE ts.tenant_id = p_tenant_id
    AND ts.status = 'active'
    AND pl.limit_key = p_limit_key;

    RETURN COALESCE(v_limit, 0);
END;
$$ LANGUAGE plpgsql STABLE;

-- Funcion para verificar si se puede usar una feature (con limite)
CREATE OR REPLACE FUNCTION billing.can_use_feature(
    p_tenant_id UUID,
    p_limit_key VARCHAR(100),
    p_current_usage INTEGER DEFAULT 0
)
RETURNS TABLE (
    allowed BOOLEAN,
    limit_value INTEGER,
    current_usage INTEGER,
    remaining INTEGER,
    allow_overage BOOLEAN,
    overage_price DECIMAL
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        CASE
            WHEN pl.hard_limit THEN p_current_usage < pl.limit_value
            ELSE TRUE
        END as allowed,
        pl.limit_value,
        p_current_usage as current_usage,
        GREATEST(0, pl.limit_value - p_current_usage) as remaining,
        pl.allow_overage,
        pl.overage_unit_price
    FROM billing.tenant_subscriptions ts
    JOIN billing.plan_limits pl ON pl.plan_id = ts.plan_id
    WHERE ts.tenant_id = p_tenant_id
    AND ts.status = 'active'
    AND pl.limit_key = p_limit_key;
END;
$$ LANGUAGE plpgsql STABLE;

-- Funcion para obtener todas las features de un tenant
CREATE OR REPLACE FUNCTION billing.get_tenant_features(p_tenant_id UUID)
RETURNS TABLE (
    feature_key VARCHAR(100),
    feature_name VARCHAR(255),
    enabled BOOLEAN,
    configuration JSONB
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        pf.feature_key,
        pf.feature_name,
        pf.enabled,
        pf.configuration
    FROM billing.tenant_subscriptions ts
    JOIN billing.plan_features pf ON pf.plan_id = ts.plan_id
    WHERE ts.tenant_id = p_tenant_id
    AND ts.status IN ('active', 'trial');
END;
$$ LANGUAGE plpgsql STABLE;

-- Funcion para obtener todos los limites de un tenant
CREATE OR REPLACE FUNCTION billing.get_tenant_limits(p_tenant_id UUID)
RETURNS TABLE (
    limit_key VARCHAR(100),
    limit_name VARCHAR(255),
    limit_value INTEGER,
    limit_type VARCHAR(50),
    allow_overage BOOLEAN,
    overage_unit_price DECIMAL
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        pl.limit_key,
        pl.limit_name,
        pl.limit_value,
        pl.limit_type,
        pl.allow_overage,
        pl.overage_unit_price
    FROM billing.tenant_subscriptions ts
    JOIN billing.plan_limits pl ON pl.plan_id = ts.plan_id
    WHERE ts.tenant_id = p_tenant_id
    AND ts.status IN ('active', 'trial');
END;
$$ LANGUAGE plpgsql STABLE;

-- Funcion para aplicar cupon
CREATE OR REPLACE FUNCTION billing.apply_coupon(
    p_tenant_id UUID,
    p_coupon_code VARCHAR(50)
)
RETURNS TABLE (
    success BOOLEAN,
    message TEXT,
    discount_amount DECIMAL
) AS $$
DECLARE
    v_coupon RECORD;
    v_subscription RECORD;
    v_discount DECIMAL;
BEGIN
    -- Obtener cupon
    SELECT * INTO v_coupon
    FROM billing.coupons
    WHERE code = p_coupon_code
    AND is_active = TRUE
    AND (valid_until IS NULL OR valid_until > CURRENT_TIMESTAMP);

    IF NOT FOUND THEN
        RETURN QUERY SELECT FALSE, 'Cupon no valido o expirado'::TEXT, 0::DECIMAL;
        RETURN;
    END IF;

    -- Verificar max redemptions
    IF v_coupon.max_redemptions IS NOT NULL AND v_coupon.times_redeemed >= v_coupon.max_redemptions THEN
        RETURN QUERY SELECT FALSE, 'Cupon agotado'::TEXT, 0::DECIMAL;
        RETURN;
    END IF;

    -- Verificar si ya fue usado por este tenant
    IF EXISTS (SELECT 1 FROM billing.coupon_redemptions WHERE coupon_id = v_coupon.id AND tenant_id = p_tenant_id) THEN
        RETURN QUERY SELECT FALSE, 'Cupon ya utilizado'::TEXT, 0::DECIMAL;
        RETURN;
    END IF;

    -- Obtener suscripcion
    SELECT * INTO v_subscription
    FROM billing.tenant_subscriptions
    WHERE tenant_id = p_tenant_id
    AND status = 'active';

    IF NOT FOUND THEN
        RETURN QUERY SELECT FALSE, 'No hay suscripcion activa'::TEXT, 0::DECIMAL;
        RETURN;
    END IF;

    -- Calcular descuento
    IF v_coupon.discount_type = 'percentage' THEN
        v_discount := v_subscription.current_price * (v_coupon.discount_value / 100);
    ELSE
        v_discount := v_coupon.discount_value;
    END IF;

    -- Registrar uso
    INSERT INTO billing.coupon_redemptions (coupon_id, tenant_id, subscription_id, discount_amount)
    VALUES (v_coupon.id, p_tenant_id, v_subscription.id, v_discount);

    -- Actualizar contador
    UPDATE billing.coupons SET times_redeemed = times_redeemed + 1 WHERE id = v_coupon.id;

    RETURN QUERY SELECT TRUE, 'Cupon aplicado correctamente'::TEXT, v_discount;
END;
$$ LANGUAGE plpgsql;

-- =====================
-- TRIGGERS
-- =====================

-- Trigger para updated_at en plan_features
CREATE OR REPLACE FUNCTION billing.update_plan_features_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_plan_features_updated_at
    BEFORE UPDATE ON billing.plan_features
    FOR EACH ROW
    EXECUTE FUNCTION billing.update_plan_features_timestamp();

CREATE TRIGGER trg_plan_limits_updated_at
    BEFORE UPDATE ON billing.plan_limits
    FOR EACH ROW
    EXECUTE FUNCTION billing.update_plan_features_timestamp();

-- =====================
-- SEED DATA: Features por Plan
-- =====================

-- Features para plan Starter
INSERT INTO billing.plan_features (plan_id, feature_key, feature_name, category, enabled) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'pos', 'Punto de Venta', 'sales', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'inventory_basic', 'Inventario Basico', 'inventory', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'reports_basic', 'Reportes Basicos', 'reports', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'email_support', 'Soporte por Email', 'support', TRUE)
ON CONFLICT DO NOTHING;

-- Features para plan Professional
INSERT INTO billing.plan_features (plan_id, feature_key, feature_name, category, enabled) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'pos', 'Punto de Venta', 'sales', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'mobile_app', 'App Movil', 'platform', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'inventory_advanced', 'Inventario Avanzado', 'inventory', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'reports_advanced', 'Reportes Avanzados', 'reports', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'multi_branch', 'Multi-Sucursal', 'core', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'api_access', 'Acceso a API', 'integration', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'chat_support', 'Soporte por Chat', 'support', TRUE)
ON CONFLICT DO NOTHING;

-- Features para plan Business
INSERT INTO billing.plan_features (plan_id, feature_key, feature_name, category, enabled) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'pos', 'Punto de Venta', 'sales', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'mobile_app', 'App Movil', 'platform', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'desktop_app', 'App Desktop', 'platform', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'inventory_advanced', 'Inventario Avanzado', 'inventory', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'manufacturing', 'Manufactura', 'production', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'hr_module', 'Modulo RRHH', 'hr', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'accounting', 'Contabilidad', 'financial', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'ai_assistant', 'Asistente IA', 'ai', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'webhooks', 'Webhooks', 'integration', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'priority_support', 'Soporte Prioritario', 'support', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'sla_99', 'SLA 99.9%', 'support', TRUE)
ON CONFLICT DO NOTHING;

-- =====================
-- SEED DATA: Limits por Plan
-- =====================

-- Limits para plan Starter
INSERT INTO billing.plan_limits (plan_id, limit_key, limit_name, limit_value, limit_type, allow_overage) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'users', 'Usuarios', 3, 'total', FALSE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'branches', 'Sucursales', 1, 'total', FALSE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'storage_mb', 'Storage (MB)', 5120, 'total', TRUE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'api_calls', 'API Calls', 5000, 'monthly', FALSE),
((SELECT id FROM billing.subscription_plans WHERE code = 'starter'), 'invoices', 'Facturas', 100, 'monthly', TRUE)
ON CONFLICT DO NOTHING;

-- Limits para plan Professional
INSERT INTO billing.plan_limits (plan_id, limit_key, limit_name, limit_value, limit_type, allow_overage, overage_unit_price) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'users', 'Usuarios', 10, 'total', TRUE, 99),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'branches', 'Sucursales', 3, 'total', TRUE, 199),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'storage_mb', 'Storage (MB)', 20480, 'total', TRUE, 0.10),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'api_calls', 'API Calls', 25000, 'monthly', TRUE, 0.001),
((SELECT id FROM billing.subscription_plans WHERE code = 'professional'), 'invoices', 'Facturas', 500, 'monthly', TRUE, 2)
ON CONFLICT DO NOTHING;

-- Limits para plan Business
INSERT INTO billing.plan_limits (plan_id, limit_key, limit_name, limit_value, limit_type, allow_overage, overage_unit_price) VALUES
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'users', 'Usuarios', 25, 'total', TRUE, 79),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'branches', 'Sucursales', 10, 'total', TRUE, 149),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'storage_mb', 'Storage (MB)', 102400, 'total', TRUE, 0.05),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'api_calls', 'API Calls', 100000, 'monthly', TRUE, 0.0005),
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'invoices', 'Facturas', 0, 'monthly', FALSE, 0),  -- Ilimitadas
((SELECT id FROM billing.subscription_plans WHERE code = 'business'), 'ai_tokens', 'Tokens IA', 100000, 'monthly', TRUE, 0.0001)
ON CONFLICT DO NOTHING;

-- =====================
-- COMENTARIOS
-- =====================
COMMENT ON TABLE billing.plan_features IS 'Features habilitadas por plan de suscripcion';
COMMENT ON TABLE billing.plan_limits IS 'Limites cuantificables por plan';
COMMENT ON TABLE billing.coupons IS 'Cupones de descuento';
COMMENT ON TABLE billing.coupon_redemptions IS 'Registro de uso de cupones';
COMMENT ON TABLE billing.stripe_events IS 'Log de eventos recibidos de Stripe';

COMMENT ON FUNCTION billing.has_feature IS 'Verifica si un tenant tiene una feature habilitada';
COMMENT ON FUNCTION billing.get_limit IS 'Obtiene el valor de un limite para un tenant';
COMMENT ON FUNCTION billing.can_use_feature IS 'Verifica si un tenant puede usar una feature con limite';
COMMENT ON FUNCTION billing.get_tenant_features IS 'Obtiene todas las features habilitadas para un tenant';
COMMENT ON FUNCTION billing.get_tenant_limits IS 'Obtiene todos los limites de un tenant';
COMMENT ON FUNCTION billing.apply_coupon IS 'Aplica un cupon de descuento a un tenant';
