from typing import Any, List, Dict
from pydantic import BaseModel
import hashlib
import json
from datetime import datetime

class mRNABlock(BaseModel):
    id: str
    version: int = 1
    subject: str
    timestamp: str
    data: Dict[str, Any]
    prev: str | None = None
    hash: str | None = None
    signature: str | None = None

    @classmethod
    def from_events(cls, subject: str, events: List[Dict], ai_features: bool = False):
        base = {"profile": {}, "activity": [], "features": {}}
        for e in sorted(events, key=lambda x: x.get("ts", "")):
            if e["type"] == "signup":
                base["profile"] = {"plan": e["plan"], "joined": e["ts"]}
            base["activity"].append(e)

        if ai_features:
            base["features"] = {
                "churn_risk": "low" if len(base["activity"]) > 2 else "high",
                "engagement": len([a for a in base["activity"] if a["type"] == "login"])
            }

        payload = {
            "id": f"mRNA:{subject}:v1",
            "subject": subject,
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "data": base
        }
        block = cls(**payload)
        block.hash = block.compute_hash()
        return block

    def compute_hash(self) -> str:
        canonical = json.dumps(self.model_dump(exclude=["hash", "signature"]), sort_keys=True)
        return hashlib.sha256(canonical.encode()).hexdigest()

    def __repr__(self):
        return f"<mRNABlock {self.id} hash={self.hash[:8]}...>"
