from PIL import Image, ImageDraw, ImageFont,ImageFilter
import random
import string
import io
from functools import wraps
from quart import session, redirect, url_for, flash,current_app,request

def generate_captcha():
    characters = string.ascii_uppercase + string.digits
    captcha_text = ''.join(random.choices(characters, k=6))

    font = ImageFont.truetype("arial.ttf", 36)
    image = Image.new('RGB', (200, 60), color=(255, 255, 255))
    draw = ImageDraw.Draw(image)

    for i in range(6):
        draw.text((10 + i * 30, 10), captcha_text[i], font=font,
                  fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
    # 模糊化处理
    image = image.filter(ImageFilter.BLUR)

    # 将图片保存到BytesIO流中
    buffer = io.BytesIO()
    image.save(buffer, 'jpeg')
    buffer.seek(0)

    # captcha_path = os.path.join('static', 'captcha', f'{captcha_text}.png')
    # image.save(captcha_path)
    # return captcha_text, f'static/captcha/{captcha_text}.png'
    return captcha_text, buffer


def verify_captcha(user_input, actual_captcha):
    return user_input == actual_captcha

def require_https(f):
    @wraps(f)
    async def decorated_function(*args, **kwargs):
        if request.scheme == "http":
            https_url = request.url.replace("http://", "https://", 1)
            return redirect(https_url, code=301)
        return await f(*args, **kwargs)
    return decorated_function


def login_required(f):
    @wraps(f)
    async def decorated_function(*args, **kwargs):
        username = session.get('user')
        token = session.get('token')
        if not username or not token:
            await flash('未登录,请重新登录', 'error')
            return redirect(url_for('main.login'))

        #从redis取最新的token
        redis_key = f"user_token:{username}"
        server_token = await current_app.redis.get(redis_key)
        if server_token is None or server_token != token:
            # 如果不匹配,说明此账号已在其他地方登录
            session.clear()
            await flash('您的账号已在其他设备登录,请重新登录', 'error')
            return redirect(url_for('main.login'))

        return await f(*args, **kwargs)
    return decorated_function