from enum import Enum
from typing import Any, Dict, Optional
from pydantic import BaseModel, Field
from datetime import datetime, timezone
import uuid
import json


class BaseEvent(BaseModel):
    event_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    event_type: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    data: Dict[str, Any]
    version: str = Field(default="1.0")
    correlation_id: Optional[str] = None 
    source: str = Field(default="payment_gateway")
    
    def __init__(self, event_type: str, data: Dict[str, Any], **kwargs):
        super().__init__(
            event_type=event_type,
            data=data,
            **kwargs
        )
    
    def to_kafka_message(self) -> Dict[str, Any]:
        """Convert event to Kafka message format"""
        return {
            "event_id": self.event_id,
            "event_type": self.event_type,
            "timestamp": self.timestamp.isoformat(),
            "data": self.data,
            "version": self.version,
            "correlation_id": self.correlation_id,
            "source": self.source
        }
    
    @classmethod
    def from_kafka_message(cls, message: Dict[str, Any]) -> "BaseEvent":
        """Create event from Kafka message"""
        parsed_ts = datetime.fromisoformat(message["timestamp"])
        if parsed_ts.tzinfo is None:
            parsed_ts = parsed_ts.replace(tzinfo=timezone.utc)
        return cls(
            event_id=message["event_id"],
            event_type=message["event_type"],
            timestamp=parsed_ts,
            data=message["data"],
            version=message.get("version", "1.0"),
            correlation_id=message.get("correlation_id"),
            source=message.get("source", "payment_gateway")
        )
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }
