import msgpack # type: ignore
import hmac
import hashlib
import time
from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field

# TODO: Move to config
SECRET_KEY = b"change-me-in-production-this-is-a-secure-key"

class SessionState(BaseModel):
    cookies: List[Dict[str, Any]]
    local_storage: Dict[str, str]
    session_storage: Dict[str, str]
    cf_clearance: Optional[Dict[str, Any]] = None
    user_agent: str
    tls_fingerprint: str
    timestamp: float = Field(default_factory=time.time)

    def to_redis_key(self, session_id: str) -> str:
        return f"session:{session_id}:state"

    def serialize(self) -> bytes:
        """
        Serialize with MessagePack and HMAC signature.
        """
        payload = msgpack.packb(self.model_dump())
        hmac_sig = hmac.new(SECRET_KEY, payload, hashlib.sha256).digest()
        return hmac_sig + payload

    @classmethod
    def deserialize(cls, data: bytes) -> 'SessionState':
        """
        Verify HMAC and deserialize MessagePack.
        """
        if len(data) < 32:
            raise ValueError("Data too short for HMAC")
        
        sig = data[:32]
        payload = data[32:]
        
        expected_sig = hmac.new(SECRET_KEY, payload, hashlib.sha256).digest()
        if not hmac.compare_digest(sig, expected_sig):
            raise ValueError("Invalid HMAC signature")
            
        dict_data = msgpack.unpackb(payload)
        return cls(**dict_data)
