# coding: utf-8
import os
import typing
from tkinter import Tk
from tkinter import Button
from tkinter import YES
from tkinter import StringVar
from tkinter import OptionMenu
from tkinter import W
from tkinter import E
from tkinter import messagebox
from tkinter.ttk import Combobox
from tkinter.ttk import Treeview


import time
from synergine2.config import Config

from opencombat.gui import Gui
from opencombat.strategy.manager import TroopManager
from opencombat.strategy.team.stash import TeamStash


class SelectTroopsGui(Gui):
    def __init__(
        self,
        config: Config,
        master: Tk,
        team_stash: TeamStash,
        troop_manager: TroopManager,
        countries: typing.List[str],
        troops_dir_path: str = '.',
    ) -> None:
        super().__init__(config, master)
        self._master.title('Troops selection')
        self._countries = countries
        self._team_stash = team_stash
        self._troop_manager = troop_manager
        self._troops_dir_path = troops_dir_path
        self._countries_troops = {}  # type: typing.Dict[str, typing.List[TeamModel]]  # nopep8

        # Widgets
        self._selected_country_var = StringVar(self._master)
        self._selected_country_var.set(countries[0])
        self._selected_country_var.trace('w', self._country_changed)
        self._select_country_menu = OptionMenu(
            self._master,
            self._selected_country_var,
            *countries,
        )

        self._teams_var = StringVar(self._master)
        self._teams_list = Combobox(
            self._master,
            height=10,
            state='readonly',
            textvariable=self._teams_var,
        )

        self._add_troop_var = StringVar(self._master)
        self._add_troop_button = Button(
            self._master,
            textvariable=self._add_troop_var,
            command=self._add_troop,
        )
        self._add_troop_var.set('Add troop')

        self._remove_troop_var = StringVar(self._master)
        self._remove_troop_button = Button(
            self._master,
            textvariable=self._remove_troop_var,
            command=self._remove_troop,
        )
        self._remove_troop_var.set('Remove troop')

        self._troops_view = Treeview(
            self._master,
            columns=('Soldiers',),
            height=10,
        )
        self._troops_view.heading('#0', text='Team')
        self._troops_view.heading('#1', text='Soldiers')
        self._troops_view.column('#0', stretch=YES)
        self._troops_view.column('#1', stretch=YES)

        self._generate_troops_var = StringVar(self._master)
        self._generate_troops_button = Button(
            self._master,
            textvariable=self._generate_troops_var,
            command=self._generate_troops,
        )
        self._generate_troops_var.set('Generate troops')

        # Layout
        self._select_country_menu.grid(row=0, column=0, sticky=W)
        self._teams_list.grid(row=1, column=0, sticky=W)
        self._add_troop_button.grid(row=2, column=0, sticky=W)
        self._troops_view.grid(row=3, column=0, sticky=W)
        self._remove_troop_button.grid(row=4, column=0, sticky=W)
        self._generate_troops_button.grid(row=4, column=0, sticky=E)

        # Default behaviours
        self._selected_country_var.set(countries[0])
        self._country_changed()

    def _country_changed(self, *args, **kwargs) -> None:
        country = self._selected_country_var.get()

        self._logger.info('Change country to "{}"'.format(
            country,
        ))
        country_team_names = [
            t.name for
            t in self._team_stash.get_team_by_country(
                self._selected_country_var.get(),
            )
        ]

        self._logger.debug('Change teams for: "{}"'.format(country_team_names))
        self._teams_list['values'] = country_team_names
        self._teams_var.set(country_team_names[0])
        self._update_troops_view(country)

    def _add_troop(self, *args, **kwargs) -> None:
        if self._teams_var.get():
            country = self._selected_country_var.get()
            team_name = self._teams_var.get()

            self._logger.info('Add troop "{}" to country "{}" troops'.format(
                team_name,
                team_name,
            ))

            team_model = self._team_stash.get_team_by_name(
                team_name=team_name,
                team_country=country,
            )
            self._countries_troops.setdefault(country, []).append(
                team_model,
            )
            self._update_troops_view(country)

    def _remove_troop(self, *args, **kwargs) -> None:
        selecteds = self._troops_view.selection()

        for selected in selecteds:
            team_name = self._troops_view.item(selected)['text']
            country = self._selected_country_var.get()

            self._logger.info('Remove team "{}" from country "{}"'.format(
                team_name,
                country,
            ))

            team_model = self._team_stash.get_team_by_name(
                team_name=team_name,
                team_country=country,
            )

            self._countries_troops[country].remove(team_model)

        if selecteds:
            self._update_troops_view(country)

    def _update_troops_view(self, country: str) -> None:
        teams = self._countries_troops.get(country, [])

        self._troops_view.delete(*self._troops_view.get_children())
        for team in teams:
            self._troops_view.insert(
                '',
                'end',
                text=team.name,
                values=('o' * len(team.units,))
            )

    def _generate_troops(self, *args, **kwargs) -> None:
        # Must have team(s) in all countries
        if len(self._countries_troops.keys()) == len(self._countries) \
                and all(self._countries_troops.values()):

            troops_file_path = os.path.join(
                self._troops_dir_path,
                'troops_{}.xml'.format(str(time.time())),
            )

            self._logger.info('Generate troops into file "{}"'.format(
                troops_file_path,
            ))

            troops_xml = self._troop_manager.get_troop_dump(
                self._countries_troops,
            )
            with open(troops_file_path, 'w+') as file:
                file.write(troops_xml)

            messagebox.showinfo(
                'Troops file generated',
                'Troops file successfully generate at "{}"'.format(
                    troops_file_path,
                )
            )
        else:
            messagebox.showinfo(
                'Missing information',
                'All countries must have teams',
            )
