"""Message proof bundle creation and local verification."""

from __future__ import annotations

import uuid
from dataclasses import dataclass
from datetime import datetime, timezone
from math import floor
from time import time
from typing import Any

from hallpass_sdk.jwt import sign_compact_jwt, verify_compact_jwt
from hallpass_sdk.keys import AgentKeyMaterial, fingerprint_public_jwk


@dataclass
class MessageProofBundle:
    v: int
    principal_username: str
    message_jwt: str
    signer_did: str
    verification_method: str
    public_jwk: dict[str, Any]
    key_fingerprint: str
    author_label: str


@dataclass
class VerifyResult:
    signature_valid: bool
    key_matches: bool
    signer_did: str
    key_fingerprint: str
    message: dict[str, Any] | None


def create_message_proof_bundle(
    *,
    principal_username: str,
    body: str,
    author_label: str,
    key_material: AgentKeyMaterial,
) -> MessageProofBundle:
    """Create a signed message proof bundle."""
    posted_at = datetime.now(timezone.utc).isoformat()

    claims = {
        "iss": key_material.did,
        "vm": key_material.verification_method,
        "iat": floor(time()),
        "jti": str(uuid.uuid4()),
        "msg": {
            "body": body,
            "authorLabel": author_label,
            "postedAt": posted_at,
        },
    }

    message_jwt = sign_compact_jwt(
        claims,
        key_material.private_jwk,
        header={"typ": "hallpass-message-proof+jwt", "jwk": key_material.public_jwk},
    )

    return MessageProofBundle(
        v=1,
        principal_username=principal_username,
        message_jwt=message_jwt,
        signer_did=key_material.did,
        verification_method=key_material.verification_method,
        public_jwk=key_material.public_jwk,
        key_fingerprint=key_material.key_fingerprint,
        author_label=author_label,
    )


def verify_message_proof_bundle(bundle: MessageProofBundle) -> VerifyResult:
    """Locally verify a message proof bundle's signature and key consistency."""
    verified = verify_compact_jwt(bundle.message_jwt, bundle.public_jwk)
    derived_fingerprint = fingerprint_public_jwk(bundle.public_jwk)
    key_matches = verified.valid and derived_fingerprint == bundle.key_fingerprint

    return VerifyResult(
        signature_valid=verified.valid,
        key_matches=key_matches,
        signer_did=bundle.signer_did,
        key_fingerprint=derived_fingerprint,
        message=verified.payload.get("msg") if verified.payload else None,
    )
