# src/chatiss_open_sdk/clients/openapi.py
from __future__ import annotations

from typing import Iterator, Optional, Any

from .common import build_tongue_payload, wrap_stream_error
from ..core.base import BaseClient
from ..core.format_response import (
    format_response_get_jwt_token,
    format_response_tongue_create,
    format_response_word_article_detail,
)
from ..exceptions import SSEStreamError
from ..types import APIResponse, TongueCreateRequest, TongueSSEEvent, TokenResult, WordArticleDetailResult


class OpenAPIClient(BaseClient):
    _AUTH_TOKEN_ENDPOINT = "/auth/token/"
    _TONGUE_CREATE_ENDPOINT = "/tongue/create/"
    _WORD_ARTICLE_DETAIL_ENDPOINT = "/article/word_article_detail/"

    def get_jwt_token(self) -> APIResponse[TokenResult]:
        method = "POST"
        endpoint = self._AUTH_TOKEN_ENDPOINT

        data = self._request(
            method,
            endpoint,
            json_body={
                "access_key_id": self._config.access_key_id,
                "access_key_secret": self._config.access_key_secret,
            },
            auth=False,
        )

        result = format_response_get_jwt_token(method=method, endpoint=endpoint, data=data)
        return result

    def tongue_create(self, request: TongueCreateRequest) -> Iterator[TongueSSEEvent]:
        method = "POST"
        endpoint = self._TONGUE_CREATE_ENDPOINT
        payload = build_tongue_payload(request)

        last_event: Optional[str] = None
        last_data: Any = None

        try:
            for evt in self._stream_sse(method, endpoint, json_body=payload, auth=True):
                last_event = str(evt.get("event", ""))
                last_data = evt.get("data")
                event_name, event_result = format_response_tongue_create(method=method, endpoint=endpoint, evt=evt)
                yield TongueSSEEvent(event=event_name, data=event_result)

        except SSEStreamError:
            raise
        except Exception as e:
            raise wrap_stream_error(
                e,
                method=method,
                endpoint=endpoint,
                last_event=last_event,
                last_data=last_data,
            ) from e

    def word_article_detail(self, article_id: str) -> APIResponse[WordArticleDetailResult]:
        method = "GET"
        endpoint = self._WORD_ARTICLE_DETAIL_ENDPOINT

        data = self._request(
            method,
            endpoint,
            params={"article_id": article_id},
            auth=True,
        )

        result = format_response_word_article_detail(method=method, endpoint=endpoint, data=data)
        return result
