-- ================================================================================================
-- Migration 044 DOWN: Rollback Advanced Performance Metrics
-- Removes Sortino, Calmar, VaR, CVaR calculations
-- ================================================================================================

-- Revoke permissions
REVOKE EXECUTE ON FUNCTION get_comprehensive_performance_metrics FROM foxhunt;
REVOKE EXECUTE ON FUNCTION calculate_cvar_95 FROM foxhunt;
REVOKE EXECUTE ON FUNCTION calculate_var_95 FROM foxhunt;
REVOKE EXECUTE ON FUNCTION calculate_calmar_ratio FROM foxhunt;
REVOKE EXECUTE ON FUNCTION calculate_max_drawdown FROM foxhunt;
REVOKE EXECUTE ON FUNCTION calculate_sortino_ratio FROM foxhunt;

-- Drop trigger
DROP TRIGGER IF EXISTS trg_update_model_performance ON ensemble_predictions;

-- Drop updated function
DROP FUNCTION IF EXISTS update_model_performance_metrics();

-- Drop comprehensive metrics function
DROP FUNCTION IF EXISTS get_comprehensive_performance_metrics(VARCHAR, INTEGER);

-- Drop advanced metric calculation functions
DROP FUNCTION IF EXISTS calculate_cvar_95(VARCHAR, VARCHAR, INTEGER);
DROP FUNCTION IF EXISTS calculate_var_95(VARCHAR, VARCHAR, INTEGER);
DROP FUNCTION IF EXISTS calculate_calmar_ratio(VARCHAR, VARCHAR, INTEGER);
DROP FUNCTION IF EXISTS calculate_max_drawdown(VARCHAR, VARCHAR, INTEGER);
DROP FUNCTION IF EXISTS calculate_sortino_ratio(VARCHAR, VARCHAR, INTEGER, DOUBLE PRECISION);

-- Remove new columns from model_performance_attribution
ALTER TABLE model_performance_attribution
DROP COLUMN IF EXISTS calmar_ratio,
DROP COLUMN IF EXISTS cvar_95,
DROP COLUMN IF EXISTS var_95;

-- Recreate original update_model_performance_metrics function (from migration 043)
CREATE OR REPLACE FUNCTION update_model_performance_metrics()
RETURNS TRIGGER AS $$
DECLARE
    v_model_ids VARCHAR[] := ARRAY['DQN', 'PPO', 'MAMBA2', 'TFT'];
    v_model_id VARCHAR(50);
    v_window_hours INTEGER[] := ARRAY[1, 24, 168]; -- 1h, 24h, 1 week
    v_window INTEGER;
    v_total_predictions INTEGER;
    v_correct_predictions INTEGER;
    v_total_pnl BIGINT;
    v_total_trades INTEGER;
    v_winning_trades INTEGER;
    v_avg_pnl DOUBLE PRECISION;
    v_stddev_pnl DOUBLE PRECISION;
    v_sharpe_ratio DOUBLE PRECISION;
    v_win_rate DOUBLE PRECISION;
BEGIN
    -- Only recalculate if outcome was just recorded
    IF (TG_OP = 'UPDATE' AND NEW.actual_outcome IS NOT NULL AND OLD.actual_outcome IS NULL) THEN

        -- Loop through each model
        FOREACH v_model_id IN ARRAY v_model_ids
        LOOP
            -- Loop through each window
            FOREACH v_window IN ARRAY v_window_hours
            LOOP
                -- Calculate metrics for this model and window
                SELECT
                    COUNT(*) AS total_predictions,
                    COUNT(CASE WHEN actual_outcome = 'WIN' THEN 1 END) AS correct_predictions,
                    COALESCE(SUM(pnl), 0) AS total_pnl,
                    COUNT(CASE WHEN actual_outcome IN ('WIN', 'LOSS', 'BREAKEVEN') THEN 1 END) AS total_trades,
                    COUNT(CASE WHEN actual_outcome = 'WIN' THEN 1 END) AS winning_trades,
                    AVG(pnl) AS avg_pnl,
                    STDDEV(pnl) AS stddev_pnl
                INTO
                    v_total_predictions, v_correct_predictions, v_total_pnl,
                    v_total_trades, v_winning_trades, v_avg_pnl, v_stddev_pnl
                FROM ensemble_predictions
                WHERE
                    prediction_timestamp >= NOW() - (v_window || ' hours')::INTERVAL
                    AND symbol = NEW.symbol
                    AND actual_outcome IS NOT NULL
                    AND (
                        (v_model_id = 'DQN' AND dqn_vote IS NOT NULL) OR
                        (v_model_id = 'PPO' AND ppo_vote IS NOT NULL) OR
                        (v_model_id = 'MAMBA2' AND mamba2_vote IS NOT NULL) OR
                        (v_model_id = 'TFT' AND tft_vote IS NOT NULL)
                    );

                -- Calculate Sharpe ratio (annualized)
                IF v_stddev_pnl IS NOT NULL AND v_stddev_pnl > 0 THEN
                    v_sharpe_ratio := (v_avg_pnl / v_stddev_pnl) * SQRT(252);
                ELSE
                    v_sharpe_ratio := NULL;
                END IF;

                -- Calculate win rate
                IF v_total_trades > 0 THEN
                    v_win_rate := v_winning_trades::DOUBLE PRECISION / v_total_trades;
                ELSE
                    v_win_rate := 0.0;
                END IF;

                -- Upsert into model_performance_attribution
                INSERT INTO model_performance_attribution (
                    model_id, symbol, window_hours,
                    total_predictions, correct_predictions, accuracy,
                    total_pnl, total_trades, winning_trades,
                    sharpe_ratio, win_rate,
                    prediction_timestamp
                )
                VALUES (
                    v_model_id, NEW.symbol, v_window,
                    v_total_predictions, v_correct_predictions,
                    CASE WHEN v_total_predictions > 0 THEN v_correct_predictions::DOUBLE PRECISION / v_total_predictions ELSE 0.0 END,
                    v_total_pnl, v_total_trades, v_winning_trades,
                    v_sharpe_ratio, v_win_rate,
                    NOW()
                )
                ON CONFLICT (id, prediction_timestamp) DO NOTHING;

            END LOOP;
        END LOOP;

    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Recreate trigger
CREATE TRIGGER trg_update_model_performance
    AFTER UPDATE ON ensemble_predictions
    FOR EACH ROW
    WHEN (NEW.actual_outcome IS NOT NULL AND OLD.actual_outcome IS NULL)
    EXECUTE FUNCTION update_model_performance_metrics();

-- Grant permissions for restored function
GRANT EXECUTE ON FUNCTION update_model_performance_metrics TO foxhunt;

-- ================================================================================================
-- END MIGRATION 044 DOWN
-- ================================================================================================
