from flask import Flask, jsonify, request, current_app
from flask_cors import CORS
import traceback
import hashlib
import requests
from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
import warnings
import config
import pymysql.cursors  # 确保导入了 pymysql 的 cursors
from pyngrok import ngrok
from flask import Flask, request, jsonify
from flask_cors import CORS
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
import random, datetime
import bcrypt
import mysql.connector


app = Flask(__name__)
CORS(app, supports_credentials=True)  # 支持 cookies（可选）

# 商户ID和密钥
merchant_id = 4058
merchant_key = '2c9e609b503698c6f1dba301725ec631'
base_url = 'https://api.ltrhcj.cn/api/paySubmit'  # 请求网关

def generate_md5_signature(*args):
    """根据传入的参数生成MD5签名"""
    sign_str = ''.join(args)
    return hashlib.md5(sign_str.encode('utf-8')).hexdigest()

@app.route('/paySuccess', methods=['POST', 'GET'])
def pay_success():
    data = request.form if request.method == 'POST' else request.args
    orderid = data.get('orderid')
    state = data.get('state')
    amount = data.get('amount')
    payment = data.get('payment')
    rate = data.get('rate')
    sign = data.get('sign')

    if not orderid or not state or not amount or not payment or not sign:
        return "Missing parameter", 400

    try:
        print("Received paySuccess notification:")
        print(f"orderid: {orderid}")
        print(f"state: {state}")
        print(f"amount: {amount}")
        print(f"payment: {payment}")
        print(f"rate: {rate}")
        print(f"sign: {sign}")

        # 获取数据库连接
        connection = config.get_db_connection()
        cursor = connection.cursor(pymysql.cursors.DictCursor)

        # 查询该订单对应的邮箱和密码
        cursor.execute("SELECT user_name, password FROM `order` WHERE orderid = %s", (orderid,))
        result = cursor.fetchone()
        print("result内容：", result)

        if result:
            email = result["user_name"]
            raw_password = result["password"]

            # 查询 sys_user 是否已存在该 email
            cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
            user_exists = cursor.fetchone()

            if not user_exists:
                # 加密密码（如果已经加密过，可以略过这一步）

                cursor.execute("""
                    INSERT INTO sys_user (
                        user_name, nick_name, password, email, create_time, del_flag, status, user_type
                    ) VALUES (%s, %s, %s, %s, NOW(), '0', '0', '00')
                """, (email, email, raw_password, email))
            else:
                cursor.execute("UPDATE sys_user SET status = '0' WHERE email = %s", (email,))

            # 更新订单状态为已支付
            cursor.execute("UPDATE `order` SET state = %s WHERE orderid = %s", ('已支付', orderid))

            connection.commit()

        cursor.close()
        connection.close()

        return "success", 200

    except Exception as e:
        import traceback
        current_app.logger.error(f'发生异常: {e}')
        traceback.print_exc()
        return "Internal server error", 500




@app.route('/user/createOrder', methods=['POST'])
def create_order():
    data = request.json
    print(data)
    orderid = data.get('orderid')
    paytype = data.get('paytype')
    money = data.get('money')
    notifyUrl = data.get('notifyUrl', '')
    returnUrl = data.get('returnUrl', '')
    returnmsg = 2
    user_name = data.get('user_name')
    password = data.get('password')  # 👈 获取前端传来的加密密码

    print(data)
    if not orderid or not paytype or not money or not user_name:
        return jsonify({'success': False, 'message': '缺少必传参数'}), 400

    try:
        sign = generate_md5_signature(str(merchant_id), orderid, str(paytype), str(money), merchant_key)
        payload = {
            'appid': merchant_id,
            'orderid': orderid,
            'paytype': paytype,
            'money': money,
            'sign': sign,
            'notifyUrl': notifyUrl,
            'returnUrl': returnUrl,
            'returnmsg': returnmsg
        }

        # 发送POST请求到外部 API
        response = requests.post(base_url, data=payload)
        current_app.logger.debug(f'请求URL: {base_url}')
        current_app.logger.debug(f'请求数据: {payload}')

        if response.status_code == 200:
            # 将订单信息插入到数据库的 order 表中
            connection = config.get_db_connection()
            cursor = connection.cursor()
            cursor.execute(
                "INSERT INTO `order` (orderid, user_name, password, time, amount, state) VALUES (%s, %s, %s, NOW(), %s, %s)",
                (orderid, user_name, password, money, 'pending')
            )

            connection.commit()
            cursor.close()
            connection.close()

            return response.text, 200
        else:
            return jsonify({'success': False, 'message': f"外部 API 错误: {response.text}"}), response.status_code
    except Exception as e:
        current_app.logger.error(f'发生异常: {e}')
        traceback.print_exc()
        return jsonify({'success': False, 'message': f"Error: {e}"}), 530







# 邮箱配置
SMTP_SERVER = 'smtp.qq.com'
EMAIL_ADDRESS = '3534185780@qq.com'
EMAIL_AUTH_CODE = 'slcsbwtrwitbcjic'

# 数据库配置
DB_CONFIG = {
    'host': '49.233.215.144',
    'port': 3306,
    'user': 'sy',
    'password': 'sy_password',
    'database': 'pt_station'
}


# === 发送验证码接口 ===
@app.route('/send-code', methods=['POST'])
def send_code():
    data = request.get_json()
    to_email = data.get('email')

    if not to_email:
        return jsonify({"success": False, "message": "缺少邮箱"}), 400

    code = str(random.randint(100000, 999999))
    msg = MIMEText(f"欢迎注册PTStation，您的验证码是：{code}（有效期5分钟）")
    msg['Subject'] = '您的验证码'
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = to_email

    try:
        # 发送邮件
        with SMTP_SSL(SMTP_SERVER, 465) as smtp:
            smtp.login(EMAIL_ADDRESS, EMAIL_AUTH_CODE)
            smtp.send_message(msg)
            smtp.quit()
        # 存入数据库
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        sql = "INSERT INTO email_verification (email, code, created_at) VALUES (%s, %s, NOW())"
        cursor.execute(sql, (to_email, code))
        conn.commit()
        cursor.close()
        conn.close()

        return jsonify({"success": True})
    except Exception as e:
        print("发送失败：", e)
        return jsonify({"success": False, "message": f"邮件发送失败：{e}"}), 500


# === 注册接口 ===
@app.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    email = data.get('email')
    password = data.get('password')  # 可以保留做哈希后传给支付回调存库
    code = data.get('code')

    if not all([email, password, code]):
        return jsonify({"success": False, "message": "缺少参数"}), 400

    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor(dictionary=True)

        # 1. 验证验证码是否有效（5分钟内）
        cursor.execute("""
            SELECT * FROM email_verification 
            WHERE email = %s AND code = %s AND created_at > NOW() - INTERVAL 5 MINUTE
            ORDER BY created_at DESC LIMIT 1
        """, (email, code))
        result = cursor.fetchone()

        if not result:
            return jsonify({"success": False, "message": "验证码无效或已过期"}), 400

        # 2. 检查邮箱是否已注册
        cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
        if cursor.fetchone():
            return jsonify({"success": False, "message": "该邮箱已注册"}), 400

        # ⚠️ 不再插入数据库，只返回验证通过
        return jsonify({"success": True, "message": "验证通过"})

    except Exception as e:
        print("注册失败：", e)
        return jsonify({"success": False, "message": f"注册失败：{e}"}), 500
    finally:
        cursor.close()
        conn.close()



@app.route('/reset-password', methods=['POST'])
def reset_password():
    data = request.get_json()
    email = data.get('email')
    code = data.get('code')
    new_password = data.get('newPassword')

    if not all([email, code, new_password]):
        return jsonify({"success": False, "message": "参数缺失"}), 400

    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()

        # 验证验证码是否正确且在有效期内
        cursor.execute("""
            SELECT * FROM email_verification 
            WHERE email = %s AND code = %s 
              AND created_at > NOW() - INTERVAL 5 MINUTE
            ORDER BY created_at DESC LIMIT 1
        """, (email, code))
        result = cursor.fetchone()

        if not result:
            return jsonify({"success": False, "message": "验证码错误或已过期"}), 400

        # 加密密码
        import bcrypt
        hashed_pwd = bcrypt.hashpw(new_password.encode(), bcrypt.gensalt()).decode()

        # 检查用户是否存在
        cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
        user = cursor.fetchone()
        if not user:
            return jsonify({"success": False, "message": "用户不存在"}), 404

        # 更新密码
        cursor.execute("""
            UPDATE sys_user 
            SET password = %s 
            WHERE email = %s
        """, (hashed_pwd, email))

        conn.commit()
        return jsonify({"success": True, "message": "密码已重置"})

    except Exception as e:
        print("重置失败：", e)
        return jsonify({"success": False, "message": f"服务器异常：{e}"}), 500

    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

from flask import send_file, jsonify

@app.route('/ngrok-url', methods=['GET'])
def ngrok_url():
    try:
        with open("ngrok_url.txt", "r", encoding="utf-8") as f:
            url = f.read().strip()
            print(url)
        return jsonify({"backUrl": f"{url}"})
    except FileNotFoundError:
        # 回退到本地，避免前端报错
        return jsonify({"backUrl": "http://localhost:6001"})

if __name__ == '__main__':
    try:
        conn = config.get_db_connection()
        print("数据库连接成功！")
        conn.close()
    except Exception as e:
        print(f"数据库连接失败: {e}")   
    app.run(host='0.0.0.0', port=6001,debug =True)
