use serde::{Deserialize, Serialize};
use sgf::{Game, GameResult, Win};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GamePreviewElement {
    pub date: String,
    pub name: String,
    pub black_player: String,
    pub white_player: String,
    pub result: String,
}

impl GamePreviewElement {
    pub fn new(game: &Game) -> GamePreviewElement {
        let black_player = match game.info.black_player {
            Some(ref black_player) => black_player.clone(),
            None => "unknown".to_owned(),
        };
        let white_player = match game.info.white_player {
            Some(ref white_player) => white_player.clone(),
            None => "unknown".to_owned(),
        };

        let black_player = match &game.info.black_rank {
            Some(rank) => format!("{} ({})", black_player, rank),
            None => black_player,
        };

        let white_player = match &game.info.white_rank {
            Some(rank) => format!("{} ({})", white_player, rank),
            None => white_player,
        };

        let name = match game.info.game_name {
            Some(ref name) => name.clone(),
            None => format!("{} vs. {}", black_player, white_player),
        };

        let format_win = |win: &Win| match win {
            Win::Resignation => "Resignation".to_owned(),
            Win::Time => "Timeout".to_owned(),
            Win::Forfeit => "Forfeit".to_owned(),
            Win::Score(score) => format!("{:.1}", score),
            Win::Unknown => "Unknown".to_owned(),
        };

        let result = match game.info.result {
            Some(GameResult::Void) => "Annulled".to_owned(),
            Some(GameResult::Draw) => "Draw".to_owned(),
            Some(GameResult::Black(ref win)) => format!("Black by {}", format_win(win)),
            Some(GameResult::White(ref win)) => format!("White by {}", format_win(win)),
            Some(GameResult::Unknown(ref text)) => format!("Unknown: {}", text),
            None => "".to_owned(),
        };

        GamePreviewElement {
            date: game
                .info
                .date
                .first()
                .map(|dt| dt.to_string())
                .unwrap_or("".to_owned()),
            name,
            black_player,
            white_player,
            result,
        }
    }
}
