
import os
from pathlib import Path

from decimal import Decimal
from PyQt5.QtCore import Qt, pyqtSignal, QSize, QRect
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
    QWidget, QHBoxLayout, QScroller, QVBoxLayout, QPushButton, QGridLayout,
    QScrollArea, QFrame
)

from .custom_button import CustomButton

pkg_dir = str(Path(os.path.dirname(__file__)).parents[0])
file_back_icon = os.path.join(pkg_dir, 'share', 'back.svg')
file_close_icon = os.path.join(pkg_dir, 'share', 'close.svg')
file_menu_img = os.path.join(pkg_dir, 'share', 'menu.png')

__all__ = ['GridButtons', 'MenuDash']


def money(v):
    return '${:9,}'.format(int(v))


class MenuDash(QWidget):

    def __init__(self, parent, values, selected_method=None, title=None):
        """
            parent: parent window
            values: is to list of list/tuples values for data model
                [('a' 'b', 'c'), ('d', 'e', 'f')...]
            on_selected: method to call when triggered the selection
            title: title of window
        """
        super(MenuDash, self).__init__()
        self.setContentsMargins(0, 0, 0, 0)
        self.setObjectName('dash_menu')
        self.parent = parent
        self.values = values
        self.current_view = '0'
        self._view = 0
        self.main = QVBoxLayout()
        self.main.setSpacing(0)
        self.setLayout(self.main)
        self.ctx_widgets = {}
        self.button_size = parent.screen_size
        self.method_on_selected = getattr(self.parent, selected_method)
        self.create_categories()

        # pixmap = QPixmap(file_menu_img)
        # new_pixmap = pixmap.scaled(180, 55)
        # push_menu.setPixmap(new_pixmap)
        self.expand = False
        self.push_menu = QPushButton('MENU')
        self.push_menu.setObjectName('button_push_menu')
        self.push_menu.clicked.connect(self.expand_menu)

        self.close_menu = QPushButton()
        self.close_menu.setObjectName('button_close_menu')
        self.close_menu.setIcon(QIcon(file_close_icon))
        self.close_menu.setIconSize(QSize(40, 40))
        self.close_menu.clicked.connect(self.stretch_menu)
        self.close_menu.hide()

        widget_head = QWidget()
        widget_head.setStyleSheet("background-color: white;")
        self.layout_head = QHBoxLayout()
        widget_head.setLayout(self.layout_head)

        self.main.addWidget(widget_head, 0)
        self.pushButtonBack = QPushButton()
        self.pushButtonBack.setIcon(QIcon(file_back_icon))
        self.pushButtonBack.setIconSize(QSize(15, 15))
        self.pushButtonBack.setMaximumWidth(15)

        self.layout_head.addWidget(self.pushButtonBack, stretch=0)
        self.layout_head.addWidget(self.push_menu, stretch=1)
        self.layout_head.addWidget(self.close_menu, stretch=0)
        self.main.addWidget(self.menu_area, 0)
        self.pushButtonBack.clicked.connect(self.action_back)

        width = self.parent.screen_width
        start_width = int(width / 3)
        last_width = width - start_width - 10
        self.rect_expanded = QRect(start_width, 0, last_width, self.parent.screen_height)

    def paintEvent(self, event):
        super(MenuDash, self).paintEvent(event)
        if self.expand:
            self.expand_menu()

    def get_products(self, values, name=None):
        grid_buttons = GridButtons(
            self.parent,
            values,
            num_cols=4,
            action=self.method_on_selected
        )
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll_area.setWidget(grid_buttons)
        QScroller.grabGesture(scroll_area, QScroller.LeftMouseButtonGesture)
        return scroll_area

    def change_view(self, view_id):
        view_id = str(view_id)
        view = self.ctx_widgets[self.current_view]['items']
        view.hide()
        if not view_id:
            view_id = '0'

        new_view = self.ctx_widgets[view_id]['items']
        if not new_view:
            return

        new_view.show()
        self.main.addWidget(new_view)
        self.current_view = view_id
        self.setGeometry(self.rect_expanded)

    def create_categories(self):
        # set the list model
        self.menu_area = QScrollArea()
        self.menu_area.setWidgetResizable(True)
        QScroller.grabGesture(self.menu_area, QScroller.LeftMouseButtonGesture)

        self.menu = QWidget()
        self.menu_area.setWidget(self.menu)

        self.main_categories = QGridLayout()
        self.main_categories.setSpacing(4)
        self.menu.setLayout(self.main_categories)

        num_cat_cols = 2
        row_cat = 0
        col_cat = 0
        parent_id = '0'
        self.ctx_widgets = {
            '0': {
                'items': self.menu_area,
                'parent': None,
            },
        }
        for value in self.values:
            cat_id = str(value['id'])
            if not value:
                continue
            if col_cat > num_cat_cols - 1:
                col_cat = 0
                row_cat += 1

            button = CustomButton(
                parent=self,
                id=value['id'],
                icon=value['icon'],
                method='selected_method',
                desc_extractor='name',
                record=value,
                size=self.button_size,
                name_style='toolbar'
            )
            self.main_categories.addWidget(button, row_cat, col_cat)
            col_cat += 1

            items = value.get('items')
            childs = value.get('childs', [])
            if items:
                products = self.get_products(items)
                self.ctx_widgets[cat_id] = {
                    'items': products,
                    'parent': parent_id,
                }
            if childs:
                subrow = 0
                subcol = 0
                sub_categories = QGridLayout()
                sub_categories.setSpacing(4)
                scroll_subarea = QScrollArea()
                scroll_subarea.setWidgetResizable(True)
                scroll_subarea.setLayout(sub_categories)
                self.ctx_widgets[cat_id] = {
                    'items': scroll_subarea,
                    'parent': parent_id,
                }
                for subcat in childs:
                    sub_id = str(subcat['id'])
                    if subcol > num_cat_cols - 1:
                        subcol = 0
                        subrow += 1
                    button = CustomButton(
                        parent=self,
                        id=sub_id,
                        icon=value['icon'],
                        method='selected_method',
                        desc_extractor='name',
                        record=subcat,
                        size=self.button_size,
                        name_style='category_button'
                    )
                    sub_categories.addWidget(button, subrow, subcol)
                    subcol += 1
                    products_list = subcat.get('items')
                    products_items = None
                    if products_list:
                        products_items = self.get_products(products_list)

                    self.ctx_widgets[sub_id] = {
                        'items': products_items,
                        'parent': cat_id,
                    }
                sub_categories.setRowStretch(subrow + 1, 1)
        self.main_categories.setRowStretch(row_cat + 1, 1)

    def action_back(self):
        parent_id = self.ctx_widgets[self.current_view]['parent']
        if parent_id and parent_id != self.current_view:
            self.change_view(parent_id)

    def selected_method(self, args):
        self.change_view(args['id'])
        self.expand = True

    def setDisabled(self, bool):
        self.menu_area.setDisabled(bool)

    def stretch_menu(self):
        self.expand = False
        self.change_view('0')
        self.close_menu.hide()
        self.parent.show_right_panel(True)

    def expand_menu(self):
        self.expand = True
        self.parent.show_right_panel(False)
        self.close_menu.show()
        self.setGeometry(self.rect_expanded)


class GridButtons(QWidget):
    sigItem_selected = pyqtSignal(str)

    def __init__(self, parent, rows, num_cols, action, style='product_button'):
        """
            rows: a list of lists
            num_cols: number of columns?
        """
        QWidget.__init__(self)
        self.parent = parent
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.button_size = parent.screen_size
        self.rows = rows
        self.action = action
        self.num_cols = num_cols
        self.style = style
        self.create_list_items()
        self.layout.setSpacing(2)
        self.set_items()

    def create_list_items(self):
        self.list_items = []
        for row in self.rows:
            # if isinstance(row[3], Decimal):
            #     row[3] = money(int(row[3]))

            item_button = CustomButton(
                parent=self,
                id=row['id'],
                desc_extractor='name',
                method='action_selected',
                record=row,
                size=self.button_size,
                name_style=self.style,
            )
            self.list_items.append(item_button)

    def action_selected(self, idx):
        self.action(idx)

    def set_items(self):
        colx = 0
        rowy = 0
        for item_button in self.list_items:
            if colx >= self.num_cols:
                colx = 0
                rowy += 1
            self.layout.addWidget(item_button, rowy, colx)
            colx += 1
        self.layout.setRowStretch(rowy + 1, 1)
