use crate::{
    api::GameId,
    ui::{Action, GamePreviewElement},
};
use serde::{Deserialize, Serialize};
use sgf::go::Game;
use typeshare::typeshare;

fn rank_strings() -> Vec<String> {
    vec![
        "", "30 kyu", "29 kyu", "28 kyu", "27 kyu", "26 kyu", "25 kyu", "24 kyu", "23 kyu",
        "22 kyu", "21 kyu", "20 kyu", "19 kyu", "18 kyu", "17 kyu", "16 kyu", "15 kyu", "14 kyu",
        "13 kyu", "12 kyu", "11 kyu", "10 kyu", "9 kyu", "8 kyu", "7 kyu", "6 kyu", "5 kyu",
        "4 kyu", "3 kyu", "2 kyu", "1 kyu", "1 dan", "2 dan", "3 dan", "4 dan", "5 dan", "6 dan",
        "7 dan", "8 dan", "9 dan", "1 pro", "2 pro", "3 pro", "4 pro", "5 pro", "6 pro", "7 pro",
        "8 pro", "9 pro",
    ]
    .into_iter()
    .map(|s| s.to_owned())
    .collect()
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[typeshare]
pub enum PlayerElement {
    Hotseat(HotseatPlayerElement),
    // Remote(RemotePlayerElement),
    // Bot(BotPlayerElement),
}

impl Default for PlayerElement {
    fn default() -> PlayerElement {
        PlayerElement::Hotseat(HotseatPlayerElement::default())
    }
}

#[derive(Clone, Debug, Serialize, Deserialize, Default)]
#[typeshare]
pub struct HotseatPlayerElement {
    pub placeholder: Option<String>,
    pub default_rank: Option<String>,
    pub ranks: Vec<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[typeshare]
pub struct RemotePlayerElement {}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[typeshare]
pub struct BotPlayerElement {}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[typeshare]
pub struct HomeView {
    pub black_player: PlayerElement,
    pub white_player: PlayerElement,
    pub games: Vec<GamePreviewElement>,
    pub start_game: Action<()>,
}

pub fn home<'a>(games: impl Iterator<Item = (&'a GameId, &'a Game)>) -> HomeView {
    let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
        placeholder: Some("black player".to_owned()),
        default_rank: None,
        ranks: rank_strings(),
    });
    let white_player = PlayerElement::Hotseat(HotseatPlayerElement {
        placeholder: Some("white player".to_owned()),
        default_rank: None,
        ranks: rank_strings(),
    });
    HomeView {
        black_player,
        white_player,
        games: games
            .map(|(id, game)| GamePreviewElement::new(id, game))
            .collect(),
        start_game: Action {
            id: "start-game-action".to_owned(),
            label: "New Game".to_owned(),
            action: (),
        },
    }
}