import aiohttp
import time
from loguru import logger
import asyncio

from huibiao_framework.client.data_model.bid_backend import (
    BidBackendFileParseSubmitDto,
    ParseResultVo,
    BidBackendBaseVo,
)
from huibiao_framework.config import ClientConfig


class BidBackendFileParseClient:
    """
    调用bid-backend服务的文件解析接口，并获取结果，保存到本地
    """

    def __init__(self, host: str = None):
        self.host = host if host else ClientConfig.BID_BACKEND_URL

    async def submit(
        self, session: aiohttp.ClientSession, dto: BidBackendFileParseSubmitDto
    ) -> int:
        """
        提交文件解析任务。然会project_id
        """
        async with session.post(
            f"{self.host}/project/fileParse", json=dto.model_dump()
        ) as response:
            response.raise_for_status()
            resp_json = await response.json()
            vo = BidBackendBaseVo[int](**resp_json)
            assert vo.is_success(), f"Reqid:{vo.requestId}, 提交任务失败，{vo.message}"
            return vo.result

    async def query_result(
        self, session: aiohttp.ClientSession, project_id: str | int
    ) -> ParseResultVo:
        """
        获取文件解析结果
        """
        async with session.get(
            f"{self.host}/projects/{str(project_id)}/fileParseResult"
        ) as response:
            response.raise_for_status()
            resp_json = await response.json()
            vo = BidBackendBaseVo[ParseResultVo](**resp_json)
            return vo.result

    async def submit_and_query(
        self,
        dto: BidBackendFileParseSubmitDto,
        *,
        session: aiohttp.ClientSession,
        sleep_sec: int = 10,
        attempts: int = 30,
    ):
        """
        提交文件解析任务，轮询结果，并返回下载链接
        """
        project_id: int = await self.submit(session=session, dto=dto)
        start_time = time.perf_counter()
        for i in range(attempts):
            r = await self.query_result(project_id=project_id, session=session)
            if r.result is not None and r.finished:
                logger.info(
                    f"Project_id:{project_id}, 第{i + 1}次获取结果,成功，耗时：{time.perf_counter() - start_time}s"
                )
                return r.result
            else:
                logger.debug(
                    f"Project_id:{project_id}, 第{i + 1}次获取结果,statu={r.status},finished={r.finished},耗时：{time.perf_counter() - start_time}s"
                )
                await asyncio.sleep(sleep_sec)
        logger.info(f"Reqid:{project_id}, 获取结果超时")
        return None
