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

# Flask & CORS
app = Flask(__name__)
CORS(app)

# 邮箱配置
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()



if __name__ == '__main__':
    app.run(port=3001, debug=True)
