#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: Bertrand256
# Created on: 2017-09
from PyQt5 import QtWidgets, QtCore

from PyQt5.QtCore import QSize, pyqtSlot
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QDialog, QLayout, QStyle
from typing import List

from ui import ui_columns_cfg_dlg
from wnd_utils import WndUtils


class ColumnsConfigDlg(QDialog, ui_columns_cfg_dlg.Ui_ColumnsConfigDlg, WndUtils):
    def __init__(self, parent, columns: List):
        QDialog.__init__(self, parent)
        ui_columns_cfg_dlg.Ui_ColumnsConfigDlg.__init__(self)
        WndUtils.__init__(self, None)
        self.columns: List = columns
        self.initialized = False
        self.setupUi()

    def setupUi(self):
        ui_columns_cfg_dlg.Ui_ColumnsConfigDlg.setupUi(self, self)
        self.setWindowTitle("Columns")
        self.setIcon(self.btnMoveBegin, "first-page@16px.png", rotate=90)
        self.setIcon(self.btnMoveEnd, "first-page@16px.png", rotate=-90)
        self.setIcon(self.btnMoveUp, "arrow-downward@16px.png", rotate=-180)
        self.setIcon(self.btnMoveDown, "arrow-downward@16px.png")
        self.tableWidget.verticalHeader().setSectionsMovable(True)

        self.tableWidget.verticalHeader().setDefaultSectionSize(
            self.tableWidget.verticalHeader().fontMetrics().height() + 8)

        self.tableWidget.verticalHeader().sectionMoved.connect(self.on_tableRowMoved)

        self.tableWidget.setRowCount(len(self.columns))
        for col_idx, col in enumerate(self.columns):
            item = QtWidgets.QTableWidgetItem()
            item.setText('  ')

            self.tableWidget.setVerticalHeaderItem(col_idx, item)

            visible = col[1]
            item = QtWidgets.QTableWidgetItem()
            item.setText(col[0])
            self.tableWidget.setItem(col_idx, 0, item)
            item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Checked if visible else QtCore.Qt.Unchecked)

        self.update_buttons_state()
        self.initialized = True

    def on_tableRowMoved(self, logicalIndex, oldVisualIndex, newVisualIndex):
        self.columns.insert(newVisualIndex, self.columns.pop(oldVisualIndex))

    @pyqtSlot(QtWidgets.QTableWidgetItem)
    def on_tableWidget_itemChanged(self, item):
        if not self.initialized:
            return
        row = self.tableWidget.row(item)
        if row >= 0:
            row = self.tableWidget.visualRow(row)
            self.columns[row][1] = item.checkState() == QtCore.Qt.Checked

    @pyqtSlot()
    def on_tableWidget_itemSelectionChanged(self):
        self.update_buttons_state()

    def update_buttons_state(self):
        up_enabled = False
        down_enabled = False

        items = sorted(self.tableWidget.selectedItems(), key=lambda x: self.tableWidget.visualRow(x.row()))
        last_row = -1
        first_selected_row = -1
        last_selected_row = len(items)
        was_gap = False
        for item in items:
            row = self.tableWidget.visualRow(item.row())
            if last_row >= 0 and last_row < row - 1:
                was_gap = True
            if first_selected_row < 0:
                first_selected_row = row
            last_selected_row = row
            last_row = row

        if first_selected_row > 0 or was_gap:
            up_enabled = True

        if last_selected_row < len(self.columns) - 1 or was_gap:
            down_enabled = True

        self.btnMoveBegin.setEnabled(up_enabled)
        self.btnMoveEnd.setEnabled(down_enabled)
        self.btnMoveUp.setEnabled(up_enabled)
        self.btnMoveDown.setEnabled(down_enabled)

    @pyqtSlot()
    def on_btnMoveUp_clicked(self):
        # sort selected item to move lower-indexed items first
        items = sorted(self.tableWidget.selectedItems(), key=lambda x: self.tableWidget.visualRow(x.row()))

        last_row_index = -1
        moved = False
        for item in items:
            row = self.tableWidget.visualRow(item.row())
            if row > 0:
                if last_row_index + 1 < row:
                    self.tableWidget.verticalHeader().moveSection(row, row-1)
                    last_row_index = row - 1
                    moved = True
                else:
                    last_row_index = row
            else:
                last_row_index = row
        if moved:
            self.update_buttons_state()
            self.tableWidget.scrollToItem(items[0])

    @pyqtSlot()
    def on_btnMoveBegin_clicked(self):
        items = sorted(self.tableWidget.selectedItems(), key=lambda x: self.tableWidget.visualRow(x.row()))
        moved = False
        for new_row_idx, item in enumerate(items):
            cur_row_idx = self.tableWidget.visualRow(item.row())
            if cur_row_idx != new_row_idx:
                self.tableWidget.verticalHeader().moveSection(cur_row_idx, new_row_idx)
                moved = True
        if moved:
            self.update_buttons_state()
            self.tableWidget.scrollToItem(items[0])

    @pyqtSlot()
    def on_btnMoveDown_clicked(self):
        # sort selected item to move higher-indexed items first
        items = sorted(self.tableWidget.selectedItems(), key=lambda x: self.tableWidget.visualRow(x.row()),
                       reverse=True)

        last_row_index = None
        moved = False
        for item in items:
            row = self.tableWidget.visualRow(item.row())
            if row < len(self.columns) - 1:
                if last_row_index is None or row + 1 < last_row_index:
                    self.tableWidget.verticalHeader().moveSection(row, row+1)
                    last_row_index = row + 1
                    moved = True
                else:
                    last_row_index = row
            else:
                last_row_index = row
        if moved:
            self.update_buttons_state()
            self.tableWidget.scrollToItem(items[0])

    @pyqtSlot()
    def on_btnMoveEnd_clicked(self):
        items = sorted(self.tableWidget.selectedItems(), key=lambda x: self.tableWidget.visualRow(x.row()),
                       reverse=True)
        moved = False
        for idx, item in enumerate(items):
            cur_row_idx = self.tableWidget.visualRow(item.row())
            new_row_idx = len(self.columns) - idx - 1
            if cur_row_idx != new_row_idx:
                self.tableWidget.verticalHeader().moveSection(cur_row_idx, new_row_idx)
                moved = True
        if moved:
            self.update_buttons_state()
            self.tableWidget.scrollToItem(items[0])