"""AegisTrade AI Security, Authentication & Password Hashing."""
from __future__ import annotations

import base64
import hashlib
import hmac
import json
import time
from datetime import datetime, timezone
from typing import Any, Optional

from backend.app.config.settings import settings
from backend.app.database.session import db_manager


def hash_password(password: str) -> str:
    """Generate secure salted PBKDF2-HMAC-SHA256 password hash."""
    salt = settings.SECRET_KEY.encode("utf-8")[:16]
    derived = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, 100_000)
    return base64.b64encode(derived).decode("utf-8")


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """Verify password against salted hash with timing-attack prevention."""
    expected = hash_password(plain_password)
    return hmac.compare_digest(expected, hashed_password)


def create_access_token(data: dict[str, Any], expires_delta_seconds: Optional[int] = None) -> str:
    """Create lightweight cryptographically signed HMAC-SHA256 JWT-compatible token."""
    to_encode = data.copy()
    expire_sec = expires_delta_seconds or (settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60)
    to_encode["exp"] = int(time.time()) + expire_sec
    to_encode["iat"] = int(time.time())

    header = {"alg": "HS256", "typ": "JWT"}
    header_b64 = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip("=")
    payload_b64 = base64.urlsafe_b64encode(json.dumps(to_encode).encode()).decode().rstrip("=")

    signing_input = f"{header_b64}.{payload_b64}".encode()
    signature = hmac.new(settings.SECRET_KEY.encode(), signing_input, hashlib.sha256).digest()
    sig_b64 = base64.urlsafe_b64encode(signature).decode().rstrip("=")

    return f"{header_b64}.{payload_b64}.{sig_b64}"


def decode_access_token(token: str) -> Optional[dict[str, Any]]:
    """Verify signature and expiration of JWT token."""
    try:
        parts = token.split(".")
        if len(parts) != 3:
            return None
        header_b64, payload_b64, sig_b64 = parts

        # Recompute signature
        signing_input = f"{header_b64}.{payload_b64}".encode()
        expected_sig = hmac.new(settings.SECRET_KEY.encode(), signing_input, hashlib.sha256).digest()
        expected_sig_b64 = base64.urlsafe_b64encode(expected_sig).decode().rstrip("=")

        if not hmac.compare_digest(sig_b64, expected_sig_b64):
            return None

        # Decode payload
        rem = len(payload_b64) % 4
        if rem > 0:
            payload_b64 += "=" * (4 - rem)
        payload_bytes = base64.urlsafe_b64decode(payload_b64.encode())
        payload = json.loads(payload_bytes.decode())

        if "exp" in payload and time.time() > payload["exp"]:
            return None

        return payload
    except Exception:
        return None


def init_default_admin() -> None:
    """Ensure default admin user exists."""
    existing = db_manager.execute_read_one("SELECT id FROM users WHERE username = ?", (settings.ADMIN_USERNAME,))
    if not existing:
        import uuid
        user_id = str(uuid.uuid4())
        pwd_hash = hash_password(settings.ADMIN_PASSWORD)
        now = datetime.now(timezone.utc).isoformat()
        db_manager.execute_write(
            "INSERT INTO users (id, username, password_hash, role, is_active, created_at) VALUES (?, ?, ?, ?, ?, ?)",
            (user_id, settings.ADMIN_USERNAME, pwd_hash, "admin", 1, now),
        )


init_default_admin()
