# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'client.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


import typing
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
from PyQt5.QtCore import QObject
from client_config.db.client_db import DB
from client import Client
from client_config.db.models.client_db import User, Message_history, Contact_list
from sqlalchemy import desc, or_, and_

import threading
import datetime
import time
import json
from PyQt5 import QtCore, QtGui, QtWidgets

import logging
from client_config.loger import config_client_log


CLIENT_LOG = logging.getLogger("client")

socket_lock = threading.Lock()

class Worker(QtCore.QObject):
    finished = QtCore.pyqtSignal()
    progress = QtCore.pyqtSignal(dict)

    def __init__(self, getter) -> None:
        self.getter = getter
        super().__init__()
        

    def run(self):
        while True:
            data = self.getter()
            self.progress.emit(data)
            self.finished.emit()


class Ui_chatWindow(object):

    def setupUi(self, chatWindow):
        """ Main window"""

        chatWindow.setObjectName("chatWindow")
        chatWindow.resize(555, 444)

        self.User = Client(login=enter_ui.user_name.text(
        ), port=8128, host='localhost', password=enter_ui.user_password.text())
        
        self.session = self.User.session

        self.chat_is_open = False

        self.centralwidget = QtWidgets.QWidget(chatWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 30, 160, 271))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")

        self.contact_list = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.contact_list.setContentsMargins(0, 0, 0, 0)
        self.contact_list.setObjectName("contact_list")

        self.contact_list_2 = QtWidgets.QListWidget(self.verticalLayoutWidget)
        self.contact_list_2.setObjectName("contact_list_2")
        self.contact_list.addWidget(self.contact_list_2)
        self.contact_list_2.addItems(self.User.get_contact_list_from_db())
        self.contact_list_2.itemDoubleClicked.connect(self.on_2Clicked)

        self.text_enter = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.text_enter.setGeometry(QtCore.QRect(20, 300, 431, 71))
        self.text_enter.setObjectName("text_enter")

        self.btn_add_contact = QtWidgets.QPushButton(self.centralwidget)
        self.btn_add_contact.setGeometry(QtCore.QRect(20, 10, 161, 23))
        self.btn_add_contact.setObjectName("btn_add_contact")
        self.btn_add_contact.clicked.connect(self.add_new_contact)

        self.chat = QtWidgets.QTextBrowser(self.centralwidget)
        self.chat.setGeometry(QtCore.QRect(180, 30, 331, 271))
        self.chat.setObjectName("chat")

        self.btn_send = QtWidgets.QPushButton(self.centralwidget)
        self.btn_send.setGeometry(QtCore.QRect(450, 300, 61, 71))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setUnderline(False)
        font.setWeight(75)
        font.setStrikeOut(False)
        self.btn_send.setFont(font)
        self.btn_send.setObjectName("btn_send")
        self.btn_send.clicked.connect(self.send_message)

        chatWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(chatWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 555, 21))
        self.menubar.setObjectName("menubar")
        chatWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(chatWindow)
        self.statusbar.setObjectName("statusbar")
        chatWindow.setStatusBar(self.statusbar)

        self.retranslateUi(chatWindow)
        QtCore.QMetaObject.connectSlotsByName(chatWindow)

        self.thread = QtCore.QThread()
        self.worker = Worker(self.User.get_data_as_dict)
        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.worker.progress.connect(self.get_message)
        self.thread.start()

    def retranslateUi(self, chatWindow):
        _translate = QtCore.QCoreApplication.translate
        chatWindow.setWindowTitle(_translate("chatWindow", "MainWindow"))
        self.btn_add_contact.setText(_translate(
            "chatWindow", "+      New contact"))
        self.btn_send.setText(_translate("chatWindow", ">"))

    def client_history(self):
        user = self.User.db_user

        chat_history = self.session.query(
            Message_history).filter(
                or_(
                    and_(Message_history.from_ == user.name,
                    Message_history.to_ == self.chat_is_open),
                    and_(Message_history.from_ == self.chat_is_open,
                    Message_history.to_ == user.name)
                )).order_by(desc(Message_history.id)).limit(6)
        
        self.chat.setText('')
        message_list = []
        if chat_history:
            for message_from_history in chat_history:
                message = self.configurate_message_string(
                    sender=message_from_history.from_, 
                    message=message_from_history.message,
                    time=message_from_history.time)
                message_list.append(message)
            for message in message_list[::-1]:
                self.chat.setText(self.chat.toPlainText() + message)

    def on_2Clicked(self, item):
        self.chat_is_open = item.text()
        self.client_history()

    def send_message(self):
        if self.chat_is_open:
            self.User.send(self.User.create_message(
                self.chat_is_open, self.text_enter.toPlainText()))
            
            message = self.configurate_message_string(
                sender=self.User.db_user.name, 
                message=self.text_enter.toPlainText()
                )
            self.chat.setText(self.chat.toPlainText() + message)

            self.text_enter.setPlainText('')

    def get_message(self, message):
        if self.chat_is_open == message["from_user"]["name"] or message["from_user"]["name"] in ("SERVER", "ALL"):
            message = self.configurate_message_string(
                sender=message["from_user"]["name"], 
                message=message["message"]
                )
            self.chat.setText(self.chat.toPlainText() + message)

            self.text_enter.setPlainText('')

    def add_new_contact(self):
        text, ok = QtWidgets.QInputDialog.getText(
            chatWindow, 'Add form', 'Name of new contact')
        if ok:
            self.contact_list_2.addItem(str(text))
            self.User.send(self.User.add_contact(text))

    def configurate_message_string(self, sender, message, time=str(datetime.datetime.now().replace(microsecond=0))):
        return  f"{sender}: {message} \n" \
                f"{time}\n\n"

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        """ Login window"""
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)

        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(30, 240, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")

        self.lable_name = QtWidgets.QLabel(Dialog)
        self.lable_name.setGeometry(QtCore.QRect(40, 50, 81, 41))
        self.lable_name.setObjectName("lable_name")
        self.user_name = QtWidgets.QLineEdit(Dialog)
        self.user_name.setGeometry(QtCore.QRect(150, 60, 221, 31))
        self.user_name.setObjectName("user_name")

        self.lable_password = QtWidgets.QLabel(Dialog)
        self.lable_password.setGeometry(QtCore.QRect(40, 110, 81, 41))
        self.lable_password.setObjectName("lable_password")
        self.user_password = QtWidgets.QLineEdit(Dialog)
        self.user_password.setGeometry(QtCore.QRect(150, 110, 221, 31))
        self.user_password.setObjectName("user_password")

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(self.enter)

        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.lable_name.setText(_translate("Dialog", " login"))
        self.user_name.setText('tom')
        self.lable_password.setText(_translate("Dialog", " password"))
        self.user_password.setText('tom')

    def enter(self):
        if self.user_name.text() != '':

            ui.setupUi(chatWindow)
            chatWindow.show()
            enterWindow.close()


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

    chatWindow = QtWidgets.QMainWindow()
    ui = Ui_chatWindow()

    enterWindow = QtWidgets.QDialog()
    enter_ui = Ui_Dialog()
    enter_ui.setupUi(enterWindow)
    enterWindow.show()

    sys.exit(app.exec_())
