import os

import duckdb
import pytest

from src.fmatch.saas.intelligence.policy_store import PolicyStore
from src.fmatch.saas.intelligence.bandit_repo import BanditRepo
from src.fmatch.saas.intelligence.decision_logger import DecisionLogger
from src.fmatch.saas.services.learning_pipeline import LearningPipeline


@pytest.mark.asyncio
async def test_learning_pipeline_updates_policy(async_client):
    # Create a temporary DuckDB for this test
    db_path = 'temp/learning_test.duckdb'
    os.makedirs('temp', exist_ok=True)
    try:
        logger = DecisionLogger(duckdb_path=db_path, redis_conn=None)

        # Seed decision + feedback for account A, segment default
        with duckdb.connect(db_path) as conn:
            # Two decisions under same arm
            conn.execute("""
                INSERT INTO decision_log (job_id, tenant_id, segment, mode, threshold_policy, config_hash, sample_size, runtime_ms)
                VALUES
                ('job1','acctA','default','match','high_precision','h1',1000,100),
                ('job2','acctA','default','match','high_precision','h1',1000,100)
            """)
            # Feedback: one accepted, one reverted
            conn.execute("""
                INSERT INTO feedback_events (job_id, match_id, outcome, user_id)
                VALUES
                ('job1','m1','accepted','u'),
                ('job2','m2','reverted','u')
            """)

        bandits = BanditRepo(duckdb_path=db_path)

        # Use the app's DB session fixture
        from src.fmatch.saas.main import get_session
        async for db in get_session():
            store = PolicyStore(db)
            # Set baseline policy
            await store.set_policy('acctA', 'default', {'suggest': 0.70, 'min_gap': 0.10, 'auto_link': 0.80, 'version': 1})
            pipeline = LearningPipeline(logger, bandits, store)
            out = await pipeline.update_from_feedback(account_id='acctA', segment='default', lookback_days=30)
            assert out['feedback']['total'] == 2
            # Expect a small nudge within bounds
            after = out['policy_after']
            assert 0.50 <= after['suggest'] <= 0.85
            assert 0.05 <= after['min_gap'] <= 0.20
            assert after['auto_link'] >= after['suggest'] + after['min_gap'] - 1e-6
            break
    finally:
        if os.path.exists(db_path):
            os.remove(db_path)

