# coding: utf8
from pathlib import Path
from PySide6 import QtWidgets, QtGui, QtCore
from pykeepass import PyKeePass
from pykeepass.exceptions import CredentialsError

from lib.Sqlite3Helper import Sqlite3Worker
from lib.kps_operations import read_kps_to_db, blob_fy
from lib.sec_db_columns_def import insert_sec_columns


class GbxKpsLogin(QtWidgets.QGroupBox):
    def __init__(
            self,
            path: str,
            config: dict,
            file_kp: dict[str, PyKeePass],
            sqh: Sqlite3Worker,
            sec_sqh: Sqlite3Worker,
            parent: QtWidgets.QWidget = None
    ):
        super().__init__(parent)
        self.path = path
        self.config = config
        self.file_kp = file_kp
        self.sqh = sqh
        self.sec_sqh = sec_sqh

        self.icon_eye = QtGui.QIcon(":/asset/img/eye.svg")
        self.icon_eye_off = QtGui.QIcon(":/asset/img/eye-off.svg")

        self.vly_m = QtWidgets.QVBoxLayout()
        self.setLayout(self.vly_m)

        self.hly_path = QtWidgets.QHBoxLayout()
        self.vly_m.addLayout(self.hly_path)

        self.lb_path = QtWidgets.QLabel("路径：", self)
        self.hly_path.addWidget(self.lb_path)
        self.lne_path = QtWidgets.QLineEdit(path, self)
        self.lne_path.setEnabled(False)
        self.hly_path.addWidget(self.lne_path)

        self.hly_password = QtWidgets.QHBoxLayout()
        self.vly_m.addLayout(self.hly_password)

        self.lb_password = QtWidgets.QLabel("密码：", self)
        self.hly_password.addWidget(self.lb_password)
        self.lne_password = QtWidgets.QLineEdit(self)
        self.lne_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.hly_password.addWidget(self.lne_password)

        self.pbn_eye = QtWidgets.QPushButton(icon=self.icon_eye_off, parent=self)
        self.hly_password.addWidget(self.pbn_eye)

        self.hly_bottom = QtWidgets.QHBoxLayout()
        self.vly_m.addLayout(self.hly_bottom)
        self.lb_loaded = QtWidgets.QLabel("【已加载】", self)
        self.hly_bottom.addWidget(self.lb_loaded)
        self.lb_loaded.setVisible(False)
        self.hly_bottom.addStretch(1)

        self.pbn_load = QtWidgets.QPushButton("加载", self)
        self.hly_bottom.addWidget(self.pbn_load)
        self.pbn_remove = PushButtonWithItem(self, self, "移除")
        self.hly_bottom.addWidget(self.pbn_remove)

        self.pbn_eye.clicked.connect(self.on_pbn_eye_clicked)
        self.pbn_load.clicked.connect(self.on_pbn_load_clicked)
        # 回车加载
        self.lne_password.returnPressed.connect(self.on_pbn_load_clicked)

    def set_loaded(self, loaded: bool):
        self.lb_loaded.setVisible(loaded)
        self.pbn_load.setDisabled(loaded)
        # 防止回车键触发加载
        self.lne_password.setDisabled(loaded)

    def on_pbn_eye_clicked(self):
        is_pass_mode = self.lne_password.echoMode() == QtWidgets.QLineEdit.EchoMode.Password
        if is_pass_mode:
            self.lne_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Normal)
            self.pbn_eye.setIcon(self.icon_eye)
        else:
            self.lne_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
            self.pbn_eye.setIcon(self.icon_eye_off)

    def on_pbn_load_clicked(self):
        try:
            kp = read_kps_to_db(
                kps_file=self.lne_path.text(),
                password=self.lne_password.text(),
                table_name="entries",
                sqh=self.sqh
            )
        except CredentialsError:
            QtWidgets.QMessageBox.critical(self, "密码错误",
                                           f"{self.lne_path.text()}\n密码错误")
            return
        except ValueError as e:
            QtWidgets.QMessageBox.critical(self, "错误", str(e))
            return

        self.file_kp[self.lne_path.text()] = kp
        self.sec_sqh.insert_into("secrets", insert_sec_columns, [
            [blob_fy(self.lne_path.text()), blob_fy(self.lne_password.text())]
        ])

        self.lne_password.clear()
        self.set_loaded(True)
        loaded_mem = self.config["loaded_memory"]
        db_name = Path(self.sqh.db_name).name
        if db_name not in loaded_mem:
            loaded_mem[db_name] = []
        loaded_mem[db_name].append(self.lne_path.text())


class PushButtonWithItem(QtWidgets.QPushButton):

    clicked_with_item = QtCore.Signal(GbxKpsLogin)

    def __init__(self, item: GbxKpsLogin, parent: QtWidgets.QWidget = None, title: str = ""):
        super().__init__(title, parent)
        self.item = item
        self.clicked.connect(self.on_self_clicked)

    def on_self_clicked(self):
        self.clicked_with_item.emit(self.item)
