use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct CloudEval {
    pub depth: i32,
    pub fen: String,
    pub knodes: i32,
    pub pvs: Vec<Pv>,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Pv {
    NonMate {
        /// Evaluation in centi-pawns, from White's point of view
        cp: i32,
        /// Variation in UCI notation (King to rook for Chess960-compatible castling notation)
        moves: String,
    },
    Mate {
        /// Evaluation in moves to mate, from White's point of view
        mate: i32,
        /// Variation in UCI notation (King to rook for Chess960-compatible castling notation)
        moves: String,
    },
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json;

    #[test]
    fn test_cloud_eval_deserialization() {
        let json = include_str!("../test_data/analysis/cloud_eval.json");

        let eval: CloudEval = serde_json::from_str(json).expect("Failed to deserialize CloudEval");

        assert_eq!(eval.depth, 29);
        assert_eq!(
            eval.fen,
            "r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R"
        );
        assert_eq!(eval.knodes, 106325);
        assert_eq!(eval.pvs.len(), 3);

        // Check first PV (NonMate variant)
        if let Pv::NonMate { cp, moves } = &eval.pvs[0] {
            assert_eq!(*cp, 41);
            assert_eq!(moves, "d1e2 d8e7 a2a4 a7a6 b5c4 d7d6 d2d3 g8f6 c1e3 c6a5");
        } else {
            panic!("Expected NonMate variant");
        }

        // Similarly for others if needed, but this covers the structure
    }
}
