import jwt
from jwt.exceptions import InvalidTokenError
import hashlib
import logging
from datetime import datetime, timedelta, timezone
from .config import settings
from typing import Optional

logger = logging.getLogger(__name__)


# ── 密码哈希（兼容旧格式） ──

_SALT_PREFIX = "zfzs_standalone"


def hash_password(password: str) -> str:
    """带盐 SHA-256 哈希（与 user/auth.py 一致）"""
    return hashlib.sha256(f"{_SALT_PREFIX}_{password}".encode("utf-8")).hexdigest()


def verify_password(password: str, password_hash: str) -> bool:
    """验证密码，兼容 bcrypt、带盐 SHA-256、无盐旧格式"""
    # bcrypt（旧系统迁移）
    if password_hash.startswith("$2b$") or password_hash.startswith("$2a$"):
        try:
            import bcrypt
            return bcrypt.checkpw(password.encode("utf-8"), password_hash.encode("utf-8"))
        except ImportError:
            pass
    # 带盐 SHA-256（当前格式）
    salted_hash = hashlib.sha256(f"{_SALT_PREFIX}_{password}".encode("utf-8")).hexdigest()
    if salted_hash == password_hash:
        return True
    # 无盐旧格式（兼容历史数据）
    plain_hash = hashlib.sha256(password.encode("utf-8")).hexdigest()
    return plain_hash == password_hash


async def authenticate(username: str, password: str) -> Optional[dict]:
    """
    验证数据库中的用户账户（已移除硬编码默认账户）。
    返回用户信息字典，失败返回 None。
    """
    from .database import get_db
    try:
        async for conn, cur in get_db():
            await cur.execute(
                "SELECT id, username, password_hash, real_name, role "
                "FROM users WHERE username = ? AND is_active = 1",
                (username,),
            )
            row = await cur.fetchone()
            if not row:
                return None
            row_dict = dict(row)
            if not verify_password(password, row_dict["password_hash"]):
                return None
            return {
                "user_id": row_dict["id"],
                "username": row_dict["username"],
                "role": row_dict.get("role") or "user",
                "name": row_dict.get("real_name") or row_dict["username"],
            }
    except Exception as e:
        logger.error(f"authenticate 数据库查询失败: {e}")
        return None


# ── JWT Token ──

def generate_token(
    user_id: str, username: str, role: str, extra: Optional[dict] = None
) -> str:
    payload = {
        "userId": str(user_id),
        "username": username,
        "role": role,
        "exp": datetime.now(timezone.utc) + timedelta(hours=settings.JWT_EXPIRE_HOURS),
    }
    if extra:
        payload.update(extra)
    return jwt.encode(payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM)


def verify_token(token: str) -> Optional[dict]:
    try:
        payload = jwt.decode(
            token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM]
        )
        return {
            "userId": payload.get("userId"),
            "username": payload.get("username"),
            "role": payload.get("role"),
        }
    except InvalidTokenError:
        return None


def get_user_from_token(authorization: Optional[str]) -> Optional[dict]:
    if not authorization or not authorization.startswith("Bearer "):
        return None
    token = authorization[7:]
    return verify_token(token)
