from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap
from PyQt5.QtSql import QSqlTableModel, QSqlDatabase
from LoginUi import *
from InterfaceUi import *
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QTableView, QWidget, QVBoxLayout, QComboBox, \
    QButtonGroup, QMessageBox, QRadioButton
from PyQt5.QtCore import Qt, QTimer, QTime, QDateTime
import sys
import pymysql
import random
from datetime import datetime

user_now=""

class LoginWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui=Ui_LoginWindow()
        self.ui.setupUi(self)
        #去除边框
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        #阴影
        self.shadow = QtWidgets.QGraphicsDropShadowEffect(self)
        self.shadow.setOffset(0,0)
        self.shadow.setBlurRadius(10)
        self.shadow.setColor(QtCore.Qt.black)
        self.ui.frame.setGraphicsEffect(self.shadow)
        #按钮切换登录和注册、以及按登录键实现页面跳转
        self.ui.login_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(0))
        self.ui.register_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(1))
        self.ui.login_sure.clicked.connect(self.login_in)
        self.ui.register_sure.clicked.connect(self.register_in)
        self.show()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.drag_position)
            event.accept()

    def mouseReleaseEvent(self, event):
        self.drag_position = None

    #注册账号
    def register_in(self):
        account = self.ui.register_account.text()
        password_1 = self.ui.register_psw.text()
        password_2 = self.ui.register_psw2.text()
        # 判断是否输入为空
        if not account or not password_1 or not password_2:
            self.ui.stackedWidget.setCurrentIndex(2)  # 设置当前页面索引为空输入错误页面
            return
        # 判断账号是否已存在
        try:
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()
            cur.execute('select cid from customer')
            rows = cur.fetchall()
            db.close()
        except Exception as e:
            print(f"Database error: {e}")
            self.ui.stackedWidget.setCurrentIndex(2)  # 设置为数据库错误页面（可以调整索引）
            return
        # 提取所有现有账号
        existing_accounts = [row[0] for row in rows]
        if account in existing_accounts:
            self.ui.stackedWidget.setCurrentIndex(3)  # 设置当前页面索引为账号已存在错误页面
            return
        # 判断两次输入密码是否正确
        if password_1 == password_2:
            try:
                db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
                cur = db.cursor()
                cur.execute(f"insert into customer(cid, cpsw) values('{account}', '{password_2}')")
                db.commit()  # 提交事务
                db.close()
                self.ui.stackedWidget.setCurrentIndex(4)  # 设置当前页面索引为注册成功页面
            except Exception as e:
                print(f"Database error: {e}")
                self.ui.stackedWidget.setCurrentIndex(2)  # 设置为数据库错误页面
                return
        else:
            self.ui.stackedWidget.setCurrentIndex(1)  # 设置当前页面索引为密码不匹配错误页面
            return


    #登录验证
    def login_in(self):
        account = self.ui.login_account.text()
        password = self.ui.login_psw.text()
        # 检查输入框是否为空
        if not account or not password:
            self.ui.stackedWidget.setCurrentIndex(2)  # 设置当前页面索引为空输入错误页面
            return
        account_list = []
        password_list = []
        try:
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()
            cur.execute('select cid, cpsw from customer')
            rows = cur.fetchall()
            db.close()
        except Exception as e:
            print(f"Database error: {e}")
            self.ui.stackedWidget.setCurrentIndex(2)  # 设置为数据库错误页面（可以调整索引）
            return
        for row in rows:
            account_list.append(row[0])
            password_list.append(row[1])
        # 验证账号和密码
        for i in range(len(account_list)):
            if account == account_list[i] and password == password_list[i]:  # 假设密码是字符串
                global user_now
                user_now = account
                self.win = MainWindow()
                self.win.show()
                self.close()
                return
        # 如果没有匹配成功
        self.ui.stackedWidget.setCurrentIndex(5)  # 设置当前页面索引为账号或密码错误页面


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.model = None
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)
        self.initialize_image() #初始化图片
        try:
            # 设置定时器
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.update_time)
            self.timer.start(1000)  # 每秒更新一次
            self.update_time()  # 初始化时间显示
        except Exception as e:
            print(e)
        #去除边框
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        #阴影
        self.shadow = QtWidgets.QGraphicsDropShadowEffect(self)
        self.shadow.setOffset(0,0)
        self.shadow.setBlurRadius(10)
        self.shadow.setColor(QtCore.Qt.black)
        self.ui.frame_6.setGraphicsEffect(self.shadow)
        #按钮切换到各个操作面
        self.ui.logout_button.clicked.connect(self.log_out)
        self.ui.pushButton_home.clicked.connect(self.home_in)
        self.ui.pushButton_add.clicked.connect(self.add_in)
        self.ui.pushButton_get.clicked.connect(self.get_out)
        self.ui.pushButton_transfer.clicked.connect(self.transfer_in)
        self.ui.pushButton_look.clicked.connect(self.look_in)
        self.ui.pushButton_irt.clicked.connect(self.irt_in)
        self.ui.pushButton_info.clicked.connect(self.info_in)
        self.ui.pushButton_6.clicked.connect(lambda :self.ui.stackedWidget.setCurrentIndex(6))
        # 创建 tableView 属性，并将其设置为 UI 文件中的 tableView 对象
        self.tableView = self.ui.tableView  # 这里的 self.ui.tableView 是 UI 文件中 tableView 对象的引用
        self.show()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.drag_position)
            event.accept()

    def mouseReleaseEvent(self, event):
        self.drag_position = None

    def update_time(self):
        current_time = QTime.currentTime()
        self.ui.label_17.setText(current_time.toString('hh:mm:ss'))

    def update_time(self):
        current_date_time = QDateTime.currentDateTime()
        formatted_time = current_date_time.toString('yyyy-MM-dd hh:mm:ss dddd')
        self.ui.label_17.setText(formatted_time)

    #初始化图片,应用在info中
    def initialize_image(self):
        try:
            pixmap = QPixmap(":/images/images/123.jpg")
            self.ui.label_16.setScaledContents(True)  # 让图片填充满 QLabel
            self.ui.label_16.setPixmap(pixmap)
            #self.ui.label_16.setPixmap(pixmap.scaled(self.ui.label_16.size(), Qt.KeepAspectRatio))
        except Exception as e:
            print(f"Error loading image: {e}")

    #将account表中数据导出到home界面,使用的是tableWidget
    def home_in(self):
        global user_now
        self.ui.stackedWidget.setCurrentIndex(0)
        try:
            # 连接数据库
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()
            cur.execute(f"SELECT * FROM account WHERE cid = '{user_now}'")
            rows = cur.fetchall()
            db.commit()
            db.close()
            # 填充表格数据
            for row_index, row_data in enumerate(rows):
                for col_index, data in enumerate(row_data):
                    item = QTableWidgetItem(str(data))
                    item.setFlags(item.flags() & ~Qt.ItemIsEditable)  # 禁止编辑
                    item.setTextAlignment(Qt.AlignCenter) #居中
                    self.ui.tableWidget.setItem(row_index, col_index, item)
        except Exception as e:
            print(f"Database error: {e}")
            # 连接数据库或执行查询时出错，可以在界面上显示相应的错误提示

    def add_in(self):
        self.ui.stackedWidget.setCurrentIndex(1)
        self.ui.submit_button.clicked.connect(self.add_acc)

    def add_acc(self):
        global user_now
        try:
            accid = self.generator_accid()
            accbalance = self.ui.get_savings.text()
            current_date = datetime.now().date()
            acc_start = current_date.strftime('%Y-%m-%d')
            cid = user_now
            acctime = self.ui.deposit_time.currentText()

            # 获取 QGroupBox 中选中的 QRadioButton
            typebox = self.ui.type_box
            acctype = None
            for button in typebox.findChildren(QRadioButton):
                if button.isChecked():
                    acctype = button
                    break
            if acctype is None:
                raise ValueError("未选择账户类型")

            acc_type = acctype.text()

            # 确认选择活期类型时长只能选择不定期
            if acc_type == "活期" and acctime != "不定期":
                raise ValueError("活期账户的时长只能选择不定期")

            # 验证输入是否为空
            if not accbalance or not acc_type or not acctime:
                raise ValueError("所有输入字段必须填写")

            accbalance_old=accbalance
            accbalance=int(accbalance)
            if acc_type=="定期":
                if acctime=='1年':
                    accbalance=accbalance*(1+0.017)
                elif acctime=='2年':
                    accbalance=accbalance*(1+0.019)**2
                elif acctime=='3年':
                    accbalance=accbalance*(1+0.022)**3
                else:
                    accbalance=accbalance*(1+0.024)**5
            # 输出到控制台
            print(accid, accbalance, acc_start, acctime, cid, acc_type)


            # 将新账户信息插入数据库
            try:
                db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
                cur = db.cursor()
                query = "INSERT INTO account (accid, accbalance, acctime_start, accdur_time, cid, acc_type) VALUES (%s, %s, %s, %s, %s, %s)"
                cur.execute(query, (accid, accbalance, acc_start, acctime, cid, acc_type))
                db.commit()
                db.close()
                QMessageBox.information(self, "成功", "账户添加成功")
            except Exception as db_error:
                print(f"数据库错误: {db_error}")
                QMessageBox.critical(self, "错误", "添加账户到数据库失败")
                return

            # 将信息写入文件
            try:
                filename = f"{user_now}.txt"
                if acc_type=="定期":
                    s = f"用户于{acc_start},开通账号：{accid}，存取金额为{accbalance_old},期限为{acctime},到期后待取金额为{accbalance:.3f}\n"
                else:
                    s = f"用户于{acc_start},开通账号：{accid}，存取金额为{accbalance_old},期限为{acctime}\n"
                with open(filename, "a", encoding='UTF-8') as file:
                    file.write(s)
                    file.write("-" * 76 + "\n")
                print(f"信息已写入文件: {filename}")
            except Exception as file_error:
                print(f"文件写入错误: {file_error}")

            # 清空输入框
            self.ui.get_savings.clear()
            self.ui.deposit_time.setCurrentIndex(0)
            for button in typebox.findChildren(QRadioButton):
                button.setAutoExclusive(False)
                button.setChecked(False)
                button.setAutoExclusive(True)

        except ValueError as ve:
            QMessageBox.critical(self, "错误", str(ve))
        except Exception as e:
            print(e)
            QMessageBox.critical(self, "错误", f"发生错误: {e}")

    def generator_accid(self):
        while True:
            accid = random.randint(10000, 99999)
            try:
                db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
                cur = db.cursor()
                cur.execute('SELECT * FROM account WHERE accid = %s', (accid,))
                rows = cur.fetchone()
                if not rows:
                    db.close()
                    return accid
                else:
                    print("Accid already exists. Generating a new one.")
                    db.close()
            except Exception as e:
                print(f"Database error: {e}")
                return accid

    def get_out(self):
        self.ui.stackedWidget.setCurrentIndex(2)
        self.ui.sure_button1.clicked.connect(self.get_money)

    def get_money(self):
        global user_now
        accid=self.ui.accid_1.text()
        savings=self.ui.money_1.text()
        psw=self.ui.psw_sure1.text()

        self.ui.accid_1.clear()
        self.ui.money_1.clear()
        self.ui.psw_sure1.clear()
        # 检查取款金额是否为空
        if not savings:
            QMessageBox.critical(self, "错误", "请输入取款金额")
            return
        try:
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()
            # 查询密码是否匹配
            cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'")
            rows = cur.fetchone()
            if not rows or rows[0] != psw:
                QMessageBox.critical(self, "错误", "密码错误")
                db.close()
                return
            # 查询账户余额
            cur.execute(f"SELECT accbalance, acc_type FROM account WHERE accid='{accid}' AND cid='{user_now}'")
            rows = cur.fetchone()
            if not rows:
                QMessageBox.critical(self, "错误", "账户不存在或不属于当前用户")
                db.close()
                return
            accbalance, acc_type = rows

            # 检查账户类型是否是活期
            if acc_type != "活期":
                QMessageBox.critical(self, "错误", "账户类型不是活期，无法取款")
                db.close()
                return

            # 检查余额是否足够
            if float(accbalance) < float(savings):
                QMessageBox.critical(self, "错误", "账户余额不足")
                db.close()
                return

            # 更新账户余额
            new_balance = float(accbalance) - float(savings)
            cur.execute(f"UPDATE account SET accbalance={new_balance} WHERE accid='{accid}' AND cid='{user_now}'")
            db.commit()
            QMessageBox.information(self, "成功", f"成功取款 {savings} 元，当前余额为 {new_balance} 元")
            db.close()

            current_date = datetime.now().date()
            acctime= current_date.strftime('%Y-%m-%d')
            # 将信息写入文件
            try:
                filename = f"{user_now}.txt"
                s = f"用户于{acctime},在账户{accid},取款{savings}元，当前余额为{new_balance}元\n"
                with open(filename, "a", encoding='UTF-8') as file:
                    file.write(s)
                    file.write("-" * 76 + "\n")
                print(f"信息已写入文件: {filename}")
            except Exception as file_error:
                print(f"文件写入错误: {file_error}")

        except Exception as e:
            print(f"数据库错误: {e}")
            QMessageBox.critical(self, "错误", "数据库错误")


    def transfer_in(self):
        self.ui.stackedWidget.setCurrentIndex(3)
        self.ui.sure_button2.clicked.connect(self.transfer)

    def transfer(self):
        out_account = self.ui.out_accid.text()
        in_account = self.ui.in_accid.text()
        out_saving = self.ui.out_money.text()
        psw = self.ui.sure_psw2.text()

        self.ui.out_accid.clear()
        self.ui.in_accid.clear()
        self.ui.out_money.clear()
        self.ui.sure_psw2.clear()

        # 检查输入是否为空
        if not out_account or not in_account or not out_saving or not psw:
            QMessageBox.critical(self, "错误", "请输入完整信息")
            return

        try:
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()

            # 查询密码是否匹配
            cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'")
            rows = cur.fetchone()
            if not rows or rows[0] != psw:
                QMessageBox.critical(self, "错误", "密码错误")
                db.close()
                return

            # 查询转出账号是否存在并且是活期类型
            cur.execute(
                f"SELECT accbalance FROM account WHERE accid='{out_account}' AND cid='{user_now}' AND acc_type='活期'")
            rows = cur.fetchone()
            if not rows:
                QMessageBox.critical(self, "错误", "转出账号不存在或不是活期类型")
                db.close()
                return
            out_balance = float(rows[0])

            # 检查转出金额是否大于转出账号余额
            if float(out_saving) > out_balance:
                QMessageBox.critical(self, "错误", "转出账号余额不足")
                db.close()
                return

            # 查询收款账号是否存在并且是活期类型
            cur.execute(f"SELECT acc_type FROM account WHERE accid='{in_account}' AND acc_type='活期'")
            rows = cur.fetchone()
            if not rows:
                QMessageBox.critical(self, "错误", "收款账号不存在或不是活期类型")
                db.close()
                return

            # 更新转出账号余额和收款账号余额
            new_out_balance = out_balance - float(out_saving)
            cur.execute(
                f"UPDATE account SET accbalance={new_out_balance} WHERE accid='{out_account}' AND cid='{user_now}'")
            cur.execute(f"UPDATE account SET accbalance=accbalance+{out_saving} WHERE accid='{in_account}'")

            # 获取收款账号所属用户的cid和新余额
            cur.execute(f"SELECT cid FROM account WHERE accid='{in_account}'")
            row = cur.fetchone()
            if not row:
                QMessageBox.critical(self, "错误", "获取收款账号信息失败")
                db.close()
                return
            recipient_cid = row[0]

            cur.execute(f"SELECT accbalance FROM account WHERE accid='{in_account}'")
            row = cur.fetchone()
            if not row:
                QMessageBox.critical(self, "错误", "获取收款账号余额失败")
                db.close()
                return
            new_in_balance = float(row[0])

            db.commit()
            QMessageBox.information(self, "成功", f"成功转账 {out_saving} 元到账户 {in_account}")
            db.close()

            # 写入转账信息到文件
            try:
                current_date = datetime.now().date()
                acctime = current_date.strftime('%Y-%m-%d')
                filename1 = f"{user_now}.txt"
                filename2 = f"{recipient_cid}.txt"
                out_info = f"用户于{acctime},账号：{out_account}转给{in_account}, {out_saving}元，当前余额为{new_out_balance}元\n"
                in_info = f"用户于{acctime},账号：{in_account} 收到{out_saving}元，当前余额为{new_in_balance}元\n"

                with open(filename1, "a", encoding='UTF-8') as file1:
                    file1.write(out_info)
                    file1.write("-" * 76 + "\n")
                with open(filename2, "a", encoding='UTF-8') as file2:
                    file2.write(in_info)
                    file2.write("-" * 76 + "\n")
                print(f"信息已写入文件: {filename1} 和 {filename2}")
            except Exception as file_error:
                print(f"文件写入错误: {file_error}")

        except Exception as e:
            print(f"数据库错误: {e}")
            QMessageBox.critical(self, "错误", "数据库错误")

    def look_in(self):
       try:
            global user_now
            self.ui.stackedWidget.setCurrentIndex(4)
            textname=f"{user_now}.txt"
            with open(textname,'r',encoding='utf-8') as f:
                f.seek(0)
                str=f.read()
            self.ui.textEdit.setPlainText(str)
       except Exception as e:
           print(e)

    def irt_in(self):
        self.ui.stackedWidget.setCurrentIndex(5)
        try:
            # 连接数据库
            db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
            cur = db.cursor()
            cur.execute("SELECT * FROM irt")
            rows = cur.fetchall()
            db.commit()
            db.close()
            # 设置表格行数
            self.ui.tableWidget_2.setRowCount(len(rows))
            # 填充表格数据
            for row_index, row_data in enumerate(rows):
                for col_index, data in enumerate(row_data):
                    item = QTableWidgetItem(str(data))
                    item.setFlags(item.flags() & ~Qt.ItemIsEditable)  # 禁止编辑
                    item.setTextAlignment(Qt.AlignCenter)  # 居中
                    self.ui.tableWidget_2.setItem(row_index, col_index, item)
        except Exception as e:
            print(f"Database error: {e}")
            # 连接数据库或执行查询时出错，可以在界面上显示相应的错误提示

    def info_in(self):
       try:
           # 切换到包含 QTableView 的页面
            self.ui.stackedWidget.setCurrentIndex(7)
            # 设置模型
            self.model = QStandardItemModel(0, 7)
            self.model.setHorizontalHeaderLabels(['身份证号', '姓名', '性别', '年龄', '电话号码', '户籍', '密码'])
            self.tableView.setModel(self.model)
            # 加载数据
            self.load_data()
            # 使表格可编辑
            self.tableView.setEditTriggers(QTableView.AllEditTriggers)
            # 捕捉模型数据改变信号
            self.model.itemChanged.connect(self.update_database)
       except Exception as e:
            print(f"Error in info_in: {e}")

    # 连接 MySQL 并获取数据
    def load_data(self):
        global user_now
        try:
            connection = pymysql.connect(
                host='127.0.0.1',
                user='root',
                password='20021220',
                database='pybank'
            )
            cursor = connection.cursor()
            cursor.execute(f"SELECT * FROM customer where cid='{user_now}'")
            data = cursor.fetchall()
            cursor.close()
            connection.close()
            for row in data:
                items = [QStandardItem(str(field)) for field in row]
                for item in items:
                    item.setTextAlignment(Qt.AlignCenter)
                self.model.appendRow(items)
        except Exception as e:
            print(f"Error loading data: {e}")
    def update_database(self, item):
        row = item.row()
        col = item.column()
        new_value = item.text()
        print(row, col, new_value)
        try:
            # 获取主键（第一列是主键）
            primary_key = self.model.item(row, 0).text()
            # 映射列名
            columns = ['cid', 'cname', 'csex', 'cage', 'cnumber', 'caddress', 'cpsw']
            column_name = columns[col]
            # 更新数据库
            connection = pymysql.connect(
                host='127.0.0.1',
                user='root',
                password='20021220',
                database='pybank'
            )
            cursor = connection.cursor()
            query = f"UPDATE customer SET {column_name} = %s WHERE cid = %s"
            cursor.execute(query, (new_value, primary_key))
            connection.commit()
            cursor.close()
            connection.close()
            print(f"Updated row {row}, column {col} with new value {new_value}")
        except Exception as e:
            print(f"Error updating database: {e}")


    #退出当前账号回到登录界面
    def log_out(self):
        global user_now
        self.close()
        self.login = LoginWindow()
        user_now = ""



if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = LoginWindow()
    sys.exit(app.exec_())
