//! Polymarket liquidity rewards support.
//!
//! Fetches reward-eligible markets from the CLOB sampling endpoint
//! and exposes reward configuration types to Python.

use pyo3::prelude::*;

const SAMPLING_URL: &str = "https://clob.polymarket.com/sampling-simplified-markets";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

/// Reward rate configuration for a single market.
#[pyclass]
#[derive(Debug, Clone)]
pub struct RewardConfig {
    /// Maximum allowed spread to qualify for rewards.
    #[pyo3(get)]
    pub max_spread: f64,
    /// Minimum order size to qualify for rewards.
    #[pyo3(get)]
    pub min_size: f64,
    /// Raw JSON string of rate tiers from the API.
    #[pyo3(get)]
    pub rates: String,
}

#[pymethods]
impl RewardConfig {
    fn __repr__(&self) -> String {
        format!(
            "RewardConfig(max_spread={:.4}, min_size={:.1})",
            self.max_spread, self.min_size
        )
    }
}

/// A market that is eligible for liquidity rewards.
#[pyclass]
#[derive(Debug, Clone)]
pub struct RewardMarket {
    #[pyo3(get)]
    pub market_id: String,
    #[pyo3(get)]
    pub condition_id: String,
    #[pyo3(get)]
    pub question: String,
    #[pyo3(get)]
    pub rewards: Option<RewardConfig>,
}

#[pymethods]
impl RewardMarket {
    fn __repr__(&self) -> String {
        format!(
            "RewardMarket(market_id='{}', question='{}')",
            self.market_id,
            if self.question.len() > 60 {
                format!("{}...", &self.question[..57])
            } else {
                self.question.clone()
            }
        )
    }
}

// ---------------------------------------------------------------------------
// Fetching
// ---------------------------------------------------------------------------

async fn fetch_reward_markets_async() -> Result<Vec<RewardMarket>, String> {
    let client = crate::data_fetcher::http_client()?;
    let resp = client
        .get(SAMPLING_URL)
        .header("Accept", "application/json")
        .send()
        .await
        .map_err(|e| format!("request failed: {}", e))?;

    if !resp.status().is_success() {
        return Err(format!("HTTP {} for sampling-simplified-markets", resp.status()));
    }

    let body: serde_json::Value = resp
        .json()
        .await
        .map_err(|e| format!("JSON parse failed: {}", e))?;

    let markets = body
        .as_array()
        .ok_or_else(|| "expected array response".to_string())?;

    let mut result = Vec::with_capacity(markets.len());
    for m in markets {
        let market_id = m
            .get("condition_id")
            .and_then(|v| v.as_str())
            .unwrap_or("")
            .to_string();
        let condition_id = m
            .get("condition_id")
            .and_then(|v| v.as_str())
            .unwrap_or("")
            .to_string();
        let question = m
            .get("question")
            .and_then(|v| v.as_str())
            .unwrap_or("")
            .to_string();

        let rewards = m.get("rewards").and_then(|r| {
            if r.is_null() {
                return None;
            }
            let max_spread = r
                .get("max_spread")
                .and_then(|v| v.as_f64().or_else(|| v.as_str().and_then(|s| s.parse().ok())))
                .unwrap_or(0.0);
            let min_size = r
                .get("min_size")
                .and_then(|v| v.as_f64().or_else(|| v.as_str().and_then(|s| s.parse().ok())))
                .unwrap_or(0.0);
            let rates = r
                .get("rates")
                .map(|v| v.to_string())
                .unwrap_or_default();
            Some(RewardConfig {
                max_spread,
                min_size,
                rates,
            })
        });

        result.push(RewardMarket {
            market_id,
            condition_id,
            question,
            rewards,
        });
    }

    Ok(result)
}

/// Fetch Polymarket reward-eligible markets.
///
/// GET https://clob.polymarket.com/sampling-simplified-markets (unauthenticated)
#[pyfunction]
fn fetch_reward_markets() -> PyResult<Vec<RewardMarket>> {
    let rt = crate::data_fetcher::oneshot_runtime()?;
    rt.block_on(fetch_reward_markets_async())
        .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e))
}

/// Register rewards types and functions in the Python module.
pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_class::<RewardConfig>()?;
    m.add_class::<RewardMarket>()?;
    m.add_function(wrap_pyfunction!(fetch_reward_markets, m)?)?;
    Ok(())
}
