#
# Copyright (c) Daniel Sheffield 2022 - 2023
#
# All rights reserved
#
# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
from collections import OrderedDict

from urwid import (
    connect_signal,
    AttrMap,
    Button,
    Divider,
    ListBox,
    LineBox,
    Overlay,
    Padding,
    Pile,
    SimpleListWalker,
    Text,
    WidgetPlaceholder,
    Widget,
)
from . import ActivityManager
from ..data.QueryManager import NON_IDENTIFIER_COLUMNS, QueryManager, get_insert_product_statement
from ..widgets import AutoCompleteEdit, AutoCompletePopUp

class NewProduct(WidgetPlaceholder):

    def __init__(self,
        activity_manager: ActivityManager,
        query_manager: QueryManager,
        under: Widget,
    ):
        self.under = under
        self.activity_manager = activity_manager
        self.query_manager = query_manager

        title = Text('Enter Product Info', align='center')
        self.fields = OrderedDict()
        self.autocomplete_cb = lambda widget, options: len(options) and widget._emit('open', options)
        for f in ('product', 'category', 'group', 'unit'):
            w = AutoCompleteEdit(('bg', f))
            self.fields[f] = w
            w.set_edit_text(under.data[f])
            if f == 'unit':
                continue
            connect_signal(w, 'change', lambda w, v: under.apply_changes(w.name, v))
            connect_signal(w, 'apply', lambda _, name: self.autocomplete_cb(
                _, query_manager.unique_suggestions(name, **self.data)
            ))

        ok = Button('Done', on_press=lambda _: self.insert_new_product())

        body = AttrMap(ListBox(SimpleListWalker([
            Padding(
                Pile([
                    AttrMap(title, 'banner'),
                    *[AttrMap(LineBox(AttrMap(
                        AutoCompletePopUp(
                            v,
                            self.apply_choice,
                            lambda: activity_manager.show(self.update())
                        ),'streak'), title=k.title(), title_align='left'), 'bg'
                    ) for k,v in self.fields.items()],
                    Divider(),
                    AttrMap(ok, 'bg'),
                ], focus_item=2),
                align='center', left=1, right=1,
            )
        ])), 'banner')
        super().__init__(under)
        self.original_widget = Overlay(
            AttrMap(body, 'bg'),
            self.original_widget,
            align='center', width=('relative', 40),
            valign='middle', height=16,
            min_width=20)

    @property
    def data(self):
        return { k:v.get_edit_text() for k,v in self.fields.items() }

    @data.setter
    def data(self, _data):
        for k,v in _data.items():
            self.fields[k].set_edit_text(v)

    def insert_new_product(self):
        product, category, group, unit = [ self.fields[k].get_edit_text() for k in (
            'product', 'category', 'group', 'unit'
        )]
        self.activity_manager.app.log.write(
            f'{get_insert_product_statement(product, category, group, unit)};\n'
        )
        self.query_manager.insert_new_product(product, category, group, unit)
        self.activity_manager.show(self.under.update())

    def apply_choice(self, name, value):
        self.data = {
            name: value
        }
        for k,v in self.data.items():
            if k == name or v:
                continue
            options = self.query_manager.unique_suggestions(
                k, exclude=['product', *NON_IDENTIFIER_COLUMNS], **self.data)
            if len(options) == 1 and k != 'ts':
                self.data = { k: list(options)[0] }

    def update(self):
        for k, v in self.data.items():
            self.fields[k].set_edit_text(v)
        return self

    def keypress(self, size, key):
        if key == 'esc':
            self.activity_manager.show(self.under.update())
            return None

        if key == 'tab':
            return self.original_widget.keypress(size, 'down')
        if key == 'shift tab':
            return self.original_widget.keypress(size, 'up')


        return self.original_widget.keypress(size, key)

