from __future__ import annotations

import time
from typing import TYPE_CHECKING

from ..errors import WhatsrbCloudError

if TYPE_CHECKING:
    from ..client import WhatsrbCloud
    from ..action_registry import ActionRegistry


class AgentRun:
    def __init__(self, data: dict, *, client: WhatsrbCloud | None = None):
        self.id = data.get("id")
        self.agent_id = data.get("agent_id")
        self.status = data.get("status")
        self.triggered_by = data.get("triggered_by")
        self.input = data.get("input")
        self.output = data.get("output")
        self.error = data.get("error")
        self.model_used = data.get("model_used")
        self.input_tokens = data.get("input_tokens")
        self.output_tokens = data.get("output_tokens")
        self.latency_ms = data.get("latency_ms")
        self.duration_ms = data.get("duration_ms")
        self.started_at = data.get("started_at")
        self.completed_at = data.get("completed_at")
        self.created_at = data.get("created_at")
        self._client = client
        self._raw = data

    @property
    def is_pending(self) -> bool:
        return self.status == "pending"

    @property
    def is_running(self) -> bool:
        return self.status == "running"

    @property
    def is_completed(self) -> bool:
        return self.status == "completed"

    @property
    def is_failed(self) -> bool:
        return self.status == "failed"

    @property
    def is_finished(self) -> bool:
        return self.is_completed or self.is_failed

    @property
    def intent(self):
        return self.output.get("intent") if self.output else None

    @property
    def confidence(self):
        return self.output.get("confidence") if self.output else None

    @property
    def actions(self) -> list:
        if self.output:
            return self.output.get("actions", [])
        return []

    @property
    def suggested_reply(self):
        return self.output.get("suggested_reply") if self.output else None

    @property
    def context_summary(self):
        return self.output.get("context_summary") if self.output else None

    @property
    def language(self):
        return self.output.get("language") if self.output else None

    def dispatch(self, registry: ActionRegistry) -> list:
        return registry.dispatch_all(self.actions)

    def wait(self, *, timeout: int = 30, interval: int = 1) -> AgentRun:
        deadline = time.time() + timeout

        while True:
            self.reload()
            if self.is_completed:
                return self
            if self.is_failed:
                raise WhatsrbCloudError(f"Agent run failed: {self.error}")
            if time.time() >= deadline:
                raise WhatsrbCloudError(f"Timed out waiting for agent run {self.id}")
            time.sleep(interval)

    def reload(self) -> AgentRun:
        refreshed = self._client.agent_runs(self.agent_id).retrieve(self.id)
        self.status = refreshed.status
        self.triggered_by = refreshed.triggered_by
        self.output = refreshed.output
        self.error = refreshed.error
        self.model_used = refreshed.model_used
        self.input_tokens = refreshed.input_tokens
        self.output_tokens = refreshed.output_tokens
        self.latency_ms = refreshed.latency_ms
        self.duration_ms = refreshed.duration_ms
        self.started_at = refreshed.started_at
        self.completed_at = refreshed.completed_at
        return self

    def refresh(self) -> AgentRun:
        return self.reload()

    def to_dict(self) -> dict:
        return self._raw
