import time, sys, configparser, os

from PyQt5.QtWidgets import (QVBoxLayout, QLineEdit,QGridLayout,
 QApplication, QLabel, QMenu, QWidget, QHBoxLayout,QDialog,
 QAction, QTextEdit,QPushButton, qApp, QMessageBox, QInputDialog,
 QMainWindow, QFrame, QFileDialog, QCheckBox, QProgressBar,
 QListWidget, QCompleter, QComboBox, QTreeView,QAbstractItemView,
 QToolTip,QRadioButton,QButtonGroup)
from PyQt5.QtGui import (QIcon, QFont, QColor, QPixmap, QDrag, QPainter,
 QBrush, QPen,QStandardItem,QStandardItemModel,)
from PyQt5.QtCore import (QCoreApplication, Qt, QObject, pyqtSignal,
 QMimeData, QAbstractItemModel,QModelIndex)

from re_classify import re_class
from draw_elbow_function import draw_elbow_func
from k_means_function import k_means_func
from re_labeling_window import Re_Labeling_Window
from confirm_window import Confirm_Window

class MyModel(QAbstractItemModel):
    headers = 'ラベル', 'テキスト数'
    items = []

    def __init__(self, parent=None):
        super().__init__()

    def index(self, row, column, parent=QModelIndex()):
        return self.createIndex(row, column, None)

    def parent(self, child):
        return QModelIndex()

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)

    def columnCount(self, parent=QModelIndex()):
        return len(self.headers)

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            try:
                return self.items[index.row()][index.column()]
            except:
                return
        return

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role != Qt.DisplayRole:
            return
        if orientation == Qt.Horizontal:
            return self.headers[section]

    def addRow(self, claster):
        self.beginInsertRows(QModelIndex(), len(self.items), 1)
        #self.items.insert(0,(labe, prediction, text))
        self.items.append((claster))
        self.endInsertRows()

    def remove_all(self):
        self.items.clear()

    def all_print(self):
        return self.items

class View(QTreeView):
    def __init__(self, parent=None):
        super(View, self).__init__(parent)
        self.setItemsExpandable(False)
        self.setIndentation(0)
        self.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def drawBranches(self, painter, rect, index):
        return

class Cross_Category_SubWindow(QWidget):
    def __init__(self, project):
        super().__init__()

        self.project=project

        cfg=configparser.ConfigParser()
        file_path = self.project + ".ini"
        cfg.read(file_path)
        self.label_count=cfg['project']["nums_of_label"]
        self.category_count=cfg['project']["nums_of_category"]
        self.discrimination=cfg['project']["discrimination"]

        self.k_means_label_count = ""

        self.cross_category_window()

    def cross_category_window(self):
        self.w=QDialog()

        re_class_h_box=QHBoxLayout()
        re_class_label=QLabel("テキストの再分類を行う")
        re_classification=QPushButton("実行")
        re_class_h_box.addWidget(re_class_label)
        re_class_h_box.addWidget(re_classification)
        re_classification.clicked.connect(self.re_class)

        res_labeling_h_box=QHBoxLayout()
        res_label=QLabel("再分類の結果を表示")
        res_view=QPushButton("表示")
        res_labeling_h_box.addWidget(res_label)
        res_labeling_h_box.addWidget(res_view)
        res_view.clicked.connect(self.re_label_view)

        draw_elbow_pict=QHBoxLayout()
        elbow_label=QLabel("エルボー図を描く")
        elbow_button=QPushButton("実行")
        draw_elbow_pict.addWidget(elbow_label)
        draw_elbow_pict.addWidget(elbow_button)
        elbow_button.clicked.connect(self.draw_elbow)

        claster_decide_box=QHBoxLayout()
        claster_label=QLabel("クラスター数を入力")
        self.claster_count=QLineEdit()
        claster_button=QPushButton("クラスタリング")
        claster_decide_box.addWidget(claster_label)
        claster_decide_box.addWidget(self.claster_count)
        claster_decide_box.addWidget(claster_button)
        claster_button.clicked.connect(self.clastering)

        self.model=MyModel(self)
        self.view=View()
        self.view.setModel(self.model)
        self.view.setUniformRowHeights(True)
        self.view.setColumnWidth(0, 150)
        self.view.setColumnWidth(1, 200)

        claster_confirm_box=QHBoxLayout()
        claster_confirm_label=QLabel("各クラスターの内容を確認")
        claster_confirm_button=QPushButton("確認")
        claster_confirm_box.addStretch(1)
        claster_confirm_box.addWidget(claster_confirm_label)
        claster_confirm_box.addWidget(claster_confirm_button)
        claster_confirm_button.clicked.connect(self.confirm)

        close_h_box=QHBoxLayout()
        close_button=QPushButton("閉じる")
        close_h_box.addStretch(1)
        close_h_box.addWidget(close_button)
        close_button.clicked.connect(self.w.close)

        main_layout=QVBoxLayout()
        main_layout.addLayout(re_class_h_box)
        main_layout.addLayout(res_labeling_h_box)
        if os.name == "nt":
            pass
        else:
            main_layout.addLayout(draw_elbow_pict)
        main_layout.addLayout(claster_decide_box)
        main_layout.addWidget(self.view)
        main_layout.addLayout(claster_confirm_box)
        main_layout.addLayout(close_h_box)

        self.w.setGeometry(700, 300, 400, 500)
        self.w.setWindowTitle('カテゴリー横断文章分析')

        self.w.setLayout(main_layout)

    def confirm(self):
        if int(self.discrimination) != 1:
            message=QMessageBox.information(self,"お知らせ", "テキストの再分類が行われていません", QMessageBox.Ok)
            #print("テキストの再分類が行われていません")
        elif self.claster_count.text() == "":
            #print("分割するクラスター数を入力してください")
            message=QMessageBox.information(self,"お知らせ", "分割するクラスター数を入力してください", QMessageBox.Ok)
        elif self.claster_count.text().isdigit():
            subwindow = Confirm_Window(self.project, self.claster_count.text())
            subwindow.show()
        else:
            message=QMessageBox.information(self,"お知らせ", "数字を入力してください", QMessageBox.Ok)
            #print("数字を入力してください")

    def re_label_view(self):
        reply = QMessageBox.question(self, '細分類の結果を確認',
            "この処理は時間がかかります<br>再分類語のラベルとカテゴリーの一致度を確認しますか?<br>そのままお待ちください", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            if int(self.discrimination) != 1:
                #print("テキストの再分類が行われていません")
                message=QMessageBox.information(self,"お知らせ", "テキストの再分類が行われていません", QMessageBox.Ok)
            else:
                subwindow = Re_Labeling_Window(self.project)    # from re_labeling_window
                subwindow.show()
            pass

        else:
            pass

    def clastering(self):
        reply = QMessageBox.question(self, 'クラスタリングの開始',
            "この処理はたいへん時間がかかります<br>クラスタリングを開始しますか?<br>クラスタリング終了後に表中にクラスターラベルとテキスト数が表示されます", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:

            if int(self.discrimination) != 1:
                #print("テキストの再分類が行われていません")
                message=QMessageBox.information(self,"お知らせ", "テキストの再分類が行われていません", QMessageBox.Ok)
            else:
                if self.claster_count.text() == "":
                    #print("分割するクラスター数を入力してください")
                    message=QMessageBox.information(self,"お知らせ", "分割するクラスター数を入力してください", QMessageBox.Ok)
                elif self.claster_count.text().isdigit():
                    try:
                        self.model.remove_all()
                        self.k_means_label_count = k_means_func(self.project, "3", self.claster_count.text())
                        time.sleep(0.1)
                        #print(self.k_means_label_count)
                        for n in self.k_means_label_count:
                            self.model.addRow(n)
                    except Exception as e:
                        message=QMessageBox.information(self, "お知らせ","不一致カテゴリーの文章数が少ない等の理由から分析できません", QMessageBox.Ok)
                        print(e)
                else:
                    #print("数字を入力してください")
                    message=QMessageBox.information(self,"お知らせ", "数字を入力してください", QMessageBox.Ok)

        else:
            pass

    def draw_elbow(self):
        reply = QMessageBox.question(self, 'エルボー図作成開始',
            "この処理は時間がかかります<br>エルボー図の作成を開始しますか?<br>そのままお待ちください", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            if int(self.discrimination) != 1:
                #print("テキストの再分類が行われていません")
                message=QMessageBox.information(self, "お知らせ","テキストの再分類が行われていません", QMessageBox.Ok)
            else:
                try:
                    draw_elbow_func(self.project,"3") #3はdisc_code
                except Exception as e:
                    message=QMessageBox.information(self, "お知らせ","不一致カテゴリーの文章数が少ない等の理由から分析できません", QMessageBox.Ok)
                    print(e)

        else:
            pass

    def re_class(self):
        reply = QMessageBox.question(self, '再分類の開始',
            "この処理はたいへん時間がかかります<br>再分類を開始しますか?<br>そのままお待ちください", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:

            if int(self.discrimination) == 1:
                #print("すでに再分類されています")
                #message=QMessageBox.information(self,"お知らせ", "すでに再分類されています", QMessageBox.Ok)   #書き換え対象
                reply2 = QMessageBox.question(self, '再分類の開始', "このプロジェクトは再分類されています<br>もう一度、再分類を行いますか?", QMessageBox.No | QMessageBox.Yes, QMessageBox.No)
                if reply2 == QMessageBox.Yes:
                    re_class(self.project)
                    self.discrimination=1
                    #print("再分類終了")
                    message=QMessageBox.information(self, "お知らせ","再分類が終了しました", QMessageBox.Ok)
                else:
                    pass
            elif int(self.label_count) > 1 and int(self.category_count) > 1:
                re_class(self.project)
                self.discrimination=1
                #print("再分類終了")
                message=QMessageBox.information(self, "お知らせ","再分類が終了しました", QMessageBox.Ok)
            elif int(self.label_count) > 1:
                #print("カテゴリーが登録されていません")
                message=QMessageBox.information(self,"お知らせ", "カテゴリーが登録されていません", QMessageBox.Ok)
            else:
                #print("ラベル数 or カテゴリー数に問題があります")
                message=QMessageBox.information(self,"お知らせ", "ラベル数 or カテゴリー数に問題があります", QMessageBox.Ok)

        else:
            pass

    def show(self):
        self.w.exec_()

if __name__=="__main__":
    app=QApplication(sys.argv)
    project="test"
    Cross_Category_SubWindow(project).show()
    sys.exit(app.exec_())
