import MySQLdb, sys, configparser, time, subprocess, 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 mysql_sampling import mysql_sampling
from write_project_ini import write_pro_ini
from main_config import main_Config

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, labe, count):
        self.beginInsertRows(QModelIndex(), len(self.items), 1)
        self.items.insert(0,(labe, count))
        self.endInsertRows()

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

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 sampling_SubWindow(QWidget):
    def __init__(self, project):
        super().__init__()
        self.project=project

        self.sampling_subwindow()

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

        sample_h_box=QHBoxLayout()
        label=QLabel("サンプル数")
        self.num_of_sample=QLineEdit()
        sample_h_box.addWidget(label)
        sample_h_box.addWidget(self.num_of_sample)

        self.limit_of_samples=QLabel()
        self.limit_of_samples.setAlignment(Qt.AlignRight)


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

        warning_label = QLabel("すでに学習済みのデータがある場合、すべて削除されます<br>サンプリング後に再度分散表現の取得を行ってください<br><br>解除ボタンを押すとサンプリングを解除することができます<br>すでに学習済みのデータがある場合、すべて削除されます<br>解除後に再度分散表現の取得を行ってください")


        button_h_box=QHBoxLayout()
        de_sampling=QPushButton("解除")
        de_sampling.setFocusPolicy(Qt.NoFocus)
        de_sampling.clicked.connect(self.de_sample)
        process_button=QPushButton("実行")
        process_button.clicked.connect(self.process)
        cancelB=QPushButton("閉じる")
        cancelB.clicked.connect(self.close_window)
        button_h_box.addWidget(de_sampling)
        button_h_box.addStretch(2)
        button_h_box.addWidget(process_button)
        button_h_box.addWidget(cancelB)

        main_v_layout=QVBoxLayout()
        main_v_layout.addLayout(sample_h_box)
        main_v_layout.addWidget(self.limit_of_samples)
        main_v_layout.addWidget(self.view)
        main_v_layout.addWidget(warning_label)
        main_v_layout.addLayout(button_h_box)

        self.w.setGeometry(300, 300, 400, 400)
        self.w.setWindowTitle('サンプリング')
        self.w.setLayout(main_v_layout)

        self.count_label(self.project)

    def close_window(self):
        self.model.remove_all()
        #time.sleep(0.1)
        self.w.close()

    def de_sample(self):
        try:
            mysql_id, mysql_pass, projects, root_path, using_os = main_Config()
            project=self.project
            conn=MySQLdb.connect(db=project, user=mysql_id, passwd=mysql_pass, charset="utf8mb4")
            cursor=conn.cursor()

            sql="update text_table set sampling = 0"
            cursor.execute(sql)
            time.sleep(0.1)

            sql="update text_table set disc_code = null"
            cursor.execute(sql)
            time.sleep(0.1)

            sql="update text_table set sentence_vector = null"
            cursor.execute(sql)
            time.sleep(0.1)

            sql="update text_table set train_test_data = null"
            cursor.execute(sql)
            time.sleep(0.1)

            sql="update text_table set k_means_label = null"
            cursor.execute(sql)
            time.sleep(0.1)

            conn.commit()
            cursor.close()
            conn.close()

            time.sleep(0.1)

            write_pro_ini(project).main(
            sample="0",
            train_test="",
            discrimination="0",
            dimensions="",
            count_texts_analysis=""
            )   #iniファイルにプロジェクトを登録
            time.sleep(0.1)

        except Exception as e:
            print(e)

    def process(self):
        count = self.num_of_sample.text()
        a=int(self.counts)
        b=int(count)

        if a < b:
            #print("全ラベルの最小テキスト数以下の値にしてください")
            message=QMessageBox.information(self,"お知らせ",  "全ラベルの最小テキスト数以下の値にしてください", QMessageBox.Ok)
        else:
            reply = QMessageBox.question(self, '前処理の開始',
                "この処理は時間がかかります<br>処理を開始しますか?<br>終了後は自動的にメインウィンドウに戻ります", QMessageBox.No |
                QMessageBox.Yes, QMessageBox.No)

            if reply == QMessageBox.Yes:
                mysql_sampling(self.project, self.label_set, b)
                time.sleep(0.1)

                count_texts_analysis=self.count_sampling(self.project)
                write_pro_ini(self.project).main(count_texts_analysis = count_texts_analysis)

                self.model.remove_all()
                time.sleep(0.1)
                self.w.close()

            else:
                pass

    def count_sampling(self, project):
#        config=configparser.ConfigParser()
#        config.read('main.ini')
#        mysql_id=config['settings']["id"]
#        mysql_pass=config['settings']["pass"]
        mysql_id, mysql_pass, projects, root_path, using_os = main_Config()
        try:
            conn=MySQLdb.connect(db=project, user=mysql_id, passwd=mysql_pass, charset="utf8mb4")
            cursor=conn.cursor()

            sql="select count(*) from text_table where sampling = 1"
            cursor.execute(sql)
            res=list(cursor.fetchall())
            res=str((res[0])[0])
            time.sleep(0.1)

            return res

            conn.commit()
            cursor.close()
            conn.close()

        except Exception as e:
            print(e)

    def count_label(self, project):
#        config=configparser.ConfigParser()
#        config.read('main.ini')
#        mysql_id=config['settings']["id"]
#        mysql_pass=config['settings']["pass"]
        mysql_id, mysql_pass, projects, root_path, using_os = main_Config()

        cfg=configparser.ConfigParser()
        file_path = self.project + ".ini"
        cfg.read(file_path)
        labels=cfg['project']["nums_of_label"]

        if int(labels) > 0:
            try:
                conn=MySQLdb.connect(db=project, user=mysql_id, passwd=mysql_pass, charset="utf8mb4")
                cursor=conn.cursor()

                time.sleep(0.1)

                sql="select label_name, count(label_name) from text_table group by label_name"
                cursor.execute(sql)

                label=cursor.fetchall()

                time.sleep(0.1)

                conn.commit()
                cursor.close()
                conn.close()

            except Exception as e:
                print(e)

            counts=[]
            self.label_set=[]
            for n in label:
                #print(n)
                label=n[0]
                count=n[1]
                self.model.addRow(label, count)
                counts.append(count)
                self.label_set.append(label)

            self.counts=str(min(counts))
            self.num_of_sample.setText(self.counts)

            limit=self.counts + "以下で設定してください"
            self.limit_of_samples.setText(limit)

        else:
            #print("ラベルが登録がされていませんのでサンプリングできません")
            message=QMessageBox.information(self,"お知らせ",  "ラベルが登録がされていませんのでサンプリングできません", QMessageBox.Ok)



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



if __name__=="__main__":
    app=QApplication(sys.argv)

    project="ok"

    #ex= sampling_SubWindow(project)
    sampling_SubWindow(project).show()
    sys.exit(app.exec_())
