# -*- coding: utf-8 -*-

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


@dataclass
class DrasiUpdate:
    before: Dict[str, Any] = field(default_factory=dict)
    after: Dict[str, Any] = field(default_factory=dict)


@dataclass
class DrasiChangeEvent:
    kind: str
    query_id: str
    sequence: int
    source_time_ms: int
    metadata: Optional[Dict[str, Any]] = None
    added_results: List[Dict[str, Any]] = field(default_factory=list)
    updated_results: List[DrasiUpdate] = field(default_factory=list)
    deleted_results: List[Dict[str, Any]] = field(default_factory=list)

    @classmethod
    def from_payload(cls, payload: Dict[str, Any]) -> "DrasiChangeEvent":
        if payload.get("kind") != "change":
            raise ValueError("DrasiChangeEvent requires payload kind='change'")

        query_id = payload.get("query_id", payload.get("queryId", ""))
        sequence = payload.get("sequence", 0)
        source_time_ms = payload.get("source_time_ms", payload.get("sourceTimeMs", 0))
        added_results = (
            payload.get("added_results", payload.get("addedResults", [])) or []
        )
        deleted_results = (
            payload.get("deleted_results", payload.get("deletedResults", [])) or []
        )
        raw_updates = (
            payload.get("updated_results", payload.get("updatedResults", [])) or []
        )

        updates: List[DrasiUpdate] = []
        for item in raw_updates:
            if isinstance(item, dict):
                updates.append(
                    DrasiUpdate(
                        before=item.get("before", {}) or {},
                        after=item.get("after", {}) or {},
                    )
                )

        return cls(
            kind="change",
            query_id=str(query_id),
            sequence=int(sequence),
            source_time_ms=int(source_time_ms),
            metadata=payload.get("metadata"),
            added_results=[x for x in added_results if isinstance(x, dict)],
            updated_results=updates,
            deleted_results=[x for x in deleted_results if isinstance(x, dict)],
        )

    def to_workflow_input(self) -> Dict[str, Any]:
        return {
            "kind": self.kind,
            "query_id": self.query_id,
            "sequence": self.sequence,
            "source_time_ms": self.source_time_ms,
            "metadata": self.metadata,
            "added_results": self.added_results,
            "updated_results": [
                {"before": u.before, "after": u.after} for u in self.updated_results
            ],
            "deleted_results": self.deleted_results,
        }
