# -*- coding: utf-8 -*-
"""认证工具：后台用 Flask-Login session；店员 H5 用 JWT 跨域。
- login_required / role_required  : 后台(session)
- token_required                  : H5(JWT)
"""
import datetime
import functools
import jwt
from flask import request, g, jsonify, current_app, abort
from flask_login import current_user

from app.models import Staff


# -------------------- JWT（H5）--------------------

def generate_token(staff):
    payload = {
        "staff_id": staff.id,
        "role": staff.role,
        "name": staff.name,
        "exp": datetime.datetime.utcnow() + datetime.timedelta(
            days=current_app.config.get("JWT_EXPIRE_DAYS", 7)),
        "iat": datetime.datetime.utcnow(),
    }
    return jwt.encode(payload, current_app.config["SECRET_KEY"], algorithm="HS256")


def decode_token(token):
    try:
        return jwt.decode(token, current_app.config["SECRET_KEY"], algorithms=["HS256"])
    except jwt.PyJWTError:
        return None


def token_required(f):
    """H5 接口鉴权：从 Authorization: Bearer <token> 解析店员。"""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        auth = request.headers.get("Authorization", "")
        if not auth.startswith("Bearer "):
            return jsonify({"error": "未登录"}), 401
        payload = decode_token(auth[7:])
        if not payload:
            return jsonify({"error": "登录已过期，请重新登录"}), 401
        staff = Staff.query.get(payload.get("staff_id"))
        if not staff or staff.status != "active":
            return jsonify({"error": "账号不可用"}), 403
        g.current_staff = staff
        return f(*args, **kwargs)
    return wrapper


# -------------------- 后台 session（管理员）--------------------

def role_required(*roles):
    """后台角色限制装饰器。super 默认拥有所有权限。"""
    def decorator(f):
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            if not current_user.is_authenticated:
                abort(401)
            if current_user.role == "super" or current_user.role in roles:
                return f(*args, **kwargs)
            abort(403)
        return wrapper
    return decorator


def admin_required(f):
    return role_required("admin")(f)
