-- ============================================================================
-- TRADING SCHEMA - Funcion: initialize_paper_balance
-- ============================================================================
-- Inicializa el balance de paper trading para un usuario
-- ============================================================================

CREATE OR REPLACE FUNCTION trading.initialize_paper_balance(
    p_user_id UUID,
    p_initial_amount DECIMAL(20, 8) DEFAULT 10000.00,
    p_asset VARCHAR(10) DEFAULT 'USDT'
)
RETURNS UUID AS $$
DECLARE
    v_balance_id UUID;
BEGIN
    INSERT INTO trading.paper_balances (
        user_id,
        asset,
        total,
        available,
        locked,
        initial_balance
    )
    VALUES (
        p_user_id,
        p_asset,
        p_initial_amount,
        p_initial_amount,
        0,
        p_initial_amount
    )
    ON CONFLICT (user_id, asset) DO NOTHING
    RETURNING id INTO v_balance_id;

    -- Si ya existia, obtener el ID
    IF v_balance_id IS NULL THEN
        SELECT id INTO v_balance_id
        FROM trading.paper_balances
        WHERE user_id = p_user_id AND asset = p_asset;
    END IF;

    RETURN v_balance_id;
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION trading.initialize_paper_balance IS 'Inicializa balance de paper trading para un usuario (default $10,000 USDT)';

-- ============================================================================
-- Funcion: reset_paper_balance
-- ============================================================================
-- Resetea el balance de paper trading a su valor inicial
-- ============================================================================

CREATE OR REPLACE FUNCTION trading.reset_paper_balance(
    p_user_id UUID,
    p_asset VARCHAR(10) DEFAULT 'USDT',
    p_new_amount DECIMAL(20, 8) DEFAULT NULL
)
RETURNS BOOLEAN AS $$
DECLARE
    v_initial DECIMAL(20, 8);
BEGIN
    -- Obtener balance inicial original o usar el nuevo monto
    IF p_new_amount IS NOT NULL THEN
        v_initial := p_new_amount;
    ELSE
        SELECT initial_balance INTO v_initial
        FROM trading.paper_balances
        WHERE user_id = p_user_id AND asset = p_asset;
    END IF;

    -- Resetear balance
    UPDATE trading.paper_balances
    SET
        total = v_initial,
        available = v_initial,
        locked = 0,
        initial_balance = v_initial,
        total_deposits = 0,
        total_withdrawals = 0,
        total_pnl = 0,
        last_reset_at = NOW(),
        reset_count = reset_count + 1,
        updated_at = NOW()
    WHERE user_id = p_user_id AND asset = p_asset;

    RETURN FOUND;
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION trading.reset_paper_balance IS 'Resetea el balance de paper trading al valor inicial';

-- ============================================================================
-- Funcion: update_paper_balance
-- ============================================================================
-- Actualiza el balance de paper trading (lock/unlock/pnl)
-- ============================================================================

CREATE OR REPLACE FUNCTION trading.update_paper_balance(
    p_user_id UUID,
    p_asset VARCHAR(10),
    p_amount DECIMAL(20, 8),
    p_operation VARCHAR(20) -- 'lock', 'unlock', 'pnl', 'deposit', 'withdrawal'
)
RETURNS BOOLEAN AS $$
BEGIN
    CASE p_operation
        WHEN 'lock' THEN
            UPDATE trading.paper_balances
            SET
                available = available - p_amount,
                locked = locked + p_amount,
                updated_at = NOW()
            WHERE user_id = p_user_id
              AND asset = p_asset
              AND available >= p_amount;

        WHEN 'unlock' THEN
            UPDATE trading.paper_balances
            SET
                available = available + p_amount,
                locked = locked - p_amount,
                updated_at = NOW()
            WHERE user_id = p_user_id
              AND asset = p_asset
              AND locked >= p_amount;

        WHEN 'pnl' THEN
            UPDATE trading.paper_balances
            SET
                total = total + p_amount,
                available = available + p_amount,
                total_pnl = total_pnl + p_amount,
                updated_at = NOW()
            WHERE user_id = p_user_id AND asset = p_asset;

        WHEN 'deposit' THEN
            UPDATE trading.paper_balances
            SET
                total = total + p_amount,
                available = available + p_amount,
                total_deposits = total_deposits + p_amount,
                updated_at = NOW()
            WHERE user_id = p_user_id AND asset = p_asset;

        WHEN 'withdrawal' THEN
            UPDATE trading.paper_balances
            SET
                total = total - p_amount,
                available = available - p_amount,
                total_withdrawals = total_withdrawals + p_amount,
                updated_at = NOW()
            WHERE user_id = p_user_id
              AND asset = p_asset
              AND available >= p_amount;

        ELSE
            RETURN FALSE;
    END CASE;

    RETURN FOUND;
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION trading.update_paper_balance IS 'Actualiza balance de paper trading (lock/unlock/pnl/deposit/withdrawal)';
