from typing import TypedDict
import httpx


class CrackCode(object):
    """
    Identify verification code

    postPic(image:bytes|url,codetype):

    postPicAsync(image:bytes|url,codetype):

    codetype : http://www.chaojiying.com/price.html

    return:

    err_no=int, err_str=str, pic_id=str, pic_str=str, md5=str
    """

    ResultModel = TypedDict(
        "ResultModel",
        {"err_no": int, "err_str": str, "pic_id": str, "pic_str": str, "md5": str},
    )

    def __init__(self, headers: dict | None = None):
        """
        'pass2': md5(password.encode('utf8')).hexdigest(),
        """
        self.base_data = {
            "user": "liangxiuyu",
            "pass2": "b9c23cc6007dcec86a7577770790e534",
            "softid": "927673",  # 用户中心>>软件ID 生成一个替换 96001
            "len_min": 4,
        }
        self.headers = headers or {
            "Connection": "Keep-Alive",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55",
        }

        self.base_url = "http://upload.chaojiying.net/Upload/Processing.php"

    def postPic(self, image: bytes | str, codetype: str = "1004") -> ResultModel:
        """
        image: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        print("-> Nomal identifing verification code...")
        # Isinstance image bytes or Url link
        if isinstance(image, bytes):
            files = {"userfile": ("code.jpg", image)}
        else:
            res = httpx.get(image, headers=self.headers)
            files = {"userfile": ("code.jpg", res.content)}

        self.base_data.update({"codetype": codetype})
        response = httpx.post(
            self.base_url, data=self.base_data, files=files, headers=self.headers
        )
        return response.json()

    async def postPicAsync(
        self, image: bytes | str, codetype: str = "1004"
    ) -> ResultModel:

        print("-> Async identifing verification code...")

        client = httpx.AsyncClient(headers=self.headers)

        # Isinstance image bytes or Url link
        if isinstance(image, bytes):
            files = {"userfile": ("code.jpg", image)}
        else:
            res = await client.get(image)
            files = {"userfile": ("code.jpg", res.content)}

        self.base_data.update({"codetype": codetype})

        response = await client.post(self.base_url, data=self.base_data, files=files)

        _ = await client.aclose()

        # print("Code Result:",response.text)
        return response.json()

    def reportError(self, image_id):
        """
        im_id:报错题目的图片ID
        """
        print("-> Report to server this error")
        self.base_data.update(
            {
                "id": image_id,
            }
        )
        r = httpx.post(
            "http://upload.chaojiying.net/Upload/ReportError.php",
            data=self.base_data,
            headers=self.headers,
        )
        return r.json()
