#  SPDX-License-Identifier: MPL-2.0
#    Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
#  This Source Code Form is subject to the terms of the Mozilla Public
#  License, v. 2.0. If a copy of the MPL was not distributed with this
#  file, You can obtain one at https://mozilla.org/MPL/2.0/.

import unittest
from typing import List
from pydantic import conint, confloat
from tkinter import Tk, ttk
from enum import IntEnum
import toml

from dcs.config.store import Store, ConfigObject, ConfigControlFrame
from dcs.config.ui import ui_create


class ExampleSubFrame(ConfigControlFrame):
    wdg_id: ttk.Spinbox


@ui_create
class ExampleSub(ConfigObject):
    id: conint(ge=0, lt=10000) = 1
    title: str = 'test'

    def make_config_widget(self, parent: ttk.Widget) -> ConfigControlFrame:
        frm = ExampleSubFrame(parent)
        frm.pack()
        ttk.Label(frm, text="Id:").grid(row=0, column=0)
        frm.wdg_id = self.ui_create_id(frm)
        frm.wdg_id.grid(row=0, column=1)
        return frm



class ExampleIntEnum(IntEnum):
    Option1 = 1
    Option2 = 2


@ui_create
class ExampleConfig(ConfigObject):
    _KEY = 'example'
    id: conint(ge=0, lt=10) = 1
    name: str = 'Hello'
    sub: List[ExampleSub] = [
        ExampleSub(id=1, title='item 1'),
        ExampleSub(id=2, title='item 2'),
    ]
    int_option: ExampleIntEnum = ExampleIntEnum.Option2
    flt: confloat(ge=0.0, lt=10.0, multiple_of=0.01) = 0.12


class UITest(unittest.TestCase):
    def test_deserialize(self):
        in_data = {
            'example': {
                'id': 0,
                'name': 'Test1',
                'sub': [
                    {
                        'id': 0,
                        'title': 'Title1',
                    },
                    {
                        'id': 1,
                        'title': 'Title2',
                    },
                ]
            }
        }

        loaded_store = Store.load_obj(in_data, 'default')

        store = Store.get_instance('default')
        self.assertEqual(id(loaded_store), id(store))

        cfg: ExampleConfig = store.get_config(ExampleConfig)
        self.assertIn('ui_create_id', dir(cfg))


class UIInteractiveTest(unittest.TestCase):
    def setUp(self) -> None:
        self.root = Tk()
        self.frm = ttk.Frame(self.root, padding=10)
        self.frm.pack()

        self.store = Store.new('default')

    def _print_cfg(self) -> None:
        print(repr(self.store.get_config(ExampleConfig)))
        print(toml.dumps(self.store.dump_obj()))
        #print(self.store.get_config(ExampleConfig).json())

    def _run_ui(self) -> bool:
        self.res = False

        def act(ok: bool) -> None:
            self.root.destroy()
            self.res = ok

        self.ok_btn = ttk.Button(self.root, text='Test OK', command=lambda: act(True))
        self.ok_btn.pack()
        self.ok_fail = ttk.Button(self.root, text='Test Fail', command=lambda: act(False))
        self.ok_fail.pack()

        self.root.mainloop()

        return self.res

    def test_int_widget(self):
        cfg = self.store.get_config(ExampleConfig)
        wdg = cfg.ui_create_id(self.frm)
        wdg.pack()
        wdg.listen_change(lambda x, y, z: self._print_cfg())

        self.assertTrue(self._run_ui())

    def test_float_widget(self):
        cfg = self.store.get_config(ExampleConfig)
        wdg = cfg.ui_create_flt(self.frm)
        wdg.pack()
        wdg.listen_change(lambda x, y, z: self._print_cfg())

        self.assertTrue(self._run_ui())
