use crate::ui::{Chat, Goban, PlayerCard};
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
use kifu_core::{
    ui::{
        ChatElement, GobanElement, PlayerCardElement, PlayingFieldView, StoneElement,
        TextFieldElement,
    },
    Color, Size,
};
use std::{cell::RefCell, rc::Rc};

/*
#[derive(Clone, Debug)]
pub struct PlayingFieldView {
    pub board: types::GobanElement,
    pub player_card_black: types::PlayerCardElement,
    pub player_card_white: types::PlayerCardElement,
    pub chat: types::ChatElement,
    pub message: types::TextFieldElement,
    pub current_player: Color,
}
*/

pub struct PlayingFieldPrivate {
    goban: Goban,
    player_card_white: Rc<RefCell<Option<PlayerCard>>>,
    player_card_black: Rc<RefCell<Option<PlayerCard>>>,
    chat: Rc<RefCell<Option<Chat>>>,
}

impl Default for PlayingFieldPrivate {
    fn default() -> Self {
        Self {
            goban: Goban::new(),
            player_card_white: Rc::new(RefCell::new(None)),
            player_card_black: Rc::new(RefCell::new(None)),
            chat: Rc::new(RefCell::new(None)),
        }
    }
}

#[glib::object_subclass]
impl ObjectSubclass for PlayingFieldPrivate {
    const NAME: &'static str = "PlayingField";
    type Type = PlayingField;
    type ParentType = gtk::Grid;

    fn new() -> Self {
        Self {
            goban: Goban::new(),
            player_card_white: Rc::new(RefCell::new(None)),
            player_card_black: Rc::new(RefCell::new(None)),
            chat: Rc::new(RefCell::new(None)),
        }
    }
}

impl ObjectImpl for PlayingFieldPrivate {}
impl WidgetImpl for PlayingFieldPrivate {}
impl GridImpl for PlayingFieldPrivate {}

glib::wrapper! {
    pub struct PlayingField(ObjectSubclass<PlayingFieldPrivate>) @extends gtk::Grid, gtk::Widget;
}

impl PlayingField {
    pub fn new(view: PlayingFieldView) -> PlayingField {
        let s: Self = Object::builder().build();

        let player_card_white = PlayerCard::new(view.player_card_white);
        let player_card_black = PlayerCard::new(view.player_card_black);
        let chat = Chat::new(view.chat);

        s.imp().goban.set_board(view.board);

        s.attach(&s.imp().goban, 1, 1, 1, 2);
        s.attach(&player_card_black, 2, 1, 1, 1);
        s.attach(&player_card_white, 3, 1, 1, 1);
        s.attach(&chat, 2, 2, 2, 1);

        *s.imp().player_card_white.borrow_mut() = Some(player_card_white);
        *s.imp().player_card_black.borrow_mut() = Some(player_card_black);
        *s.imp().chat.borrow_mut() = Some(chat);

        s
    }
}

#[cfg(feature = "screenplay")]
pub fn playing_field_view() -> PlayingFieldView {
    let mut board = GobanElement::default();
    *board.stone_mut(4, 4) = Some(StoneElement::new(Color::White));
    *board.stone_mut(15, 15) = Some(StoneElement::new(Color::Black));
    let player_card_black = PlayerCardElement {
        color: Color::Black,
        name: "Savanni".to_owned(),
        rank: "10k".to_owned(),
        clock: "24:53".to_owned(),
    };

    let player_card_white = PlayerCardElement {
        color: Color::White,
        name: "Opal".to_owned(),
        rank: "10k".to_owned(),
        clock: "25:00".to_owned(),
    };

    let chat = ChatElement {
        messages: vec![
            "[22:05] Savanni: oops".to_owned(),
            "[22:06] Opal: you know I'll take advantage of that, right?".to_owned(),
        ],
    };
    let message = TextFieldElement {};

    PlayingFieldView {
        board,
        player_card_black,
        player_card_white,
        chat,
        message,
        current_player: Color::White,
    }
}