# -*- coding: utf-8 -*-
"""Faiss 向量匹配 HTTP 客户端。"""
from typing import Union

import requests

from gshield_pic_sdk._image import to_bytes
from gshield_pic_sdk.exceptions import GshieldConnectionError

ImageInput = Union[str, bytes, "np.ndarray"]


class FaissClient:
    """Faiss 向量库匹配服务客户端。"""

    def __init__(self, faiss_base_url: str, timeout: int = 30):
        self.base_url = faiss_base_url.rstrip("/")
        self.timeout = timeout

    def _post_image(self, path: str, image: ImageInput, description: str = "") -> dict:
        data = to_bytes(image)
        files = {"image": ("image.jpg", data, "image/jpeg")}
        payload = {"description": description} if description else {}
        try:
            r = requests.post(
                f"{self.base_url}{path}",
                files=files,
                data=payload,
                timeout=self.timeout,
            )
        except requests.RequestException as e:
            raise GshieldConnectionError(f"faiss request failed: {e}") from e
        if r.status_code >= 400:
            raise GshieldConnectionError(f"faiss returned {r.status_code}: {r.text}")
        return r.json()

    def _get(self, path: str) -> dict:
        try:
            r = requests.get(f"{self.base_url}{path}", timeout=self.timeout)
        except requests.RequestException as e:
            raise GshieldConnectionError(f"faiss request failed: {e}") from e
        if r.status_code >= 400:
            raise GshieldConnectionError(f"faiss returned {r.status_code}: {r.text}")
        return r.json()

    def _delete(self, path: str) -> dict:
        try:
            r = requests.delete(f"{self.base_url}{path}", timeout=self.timeout)
        except requests.RequestException as e:
            raise GshieldConnectionError(f"faiss request failed: {e}") from e
        if r.status_code >= 400:
            raise GshieldConnectionError(f"faiss returned {r.status_code}: {r.text}")
        return r.json() if r.content else {}

    def match(self, image: ImageInput) -> dict:
        """向量匹配，返回 allowed / in_whitelist / in_blacklist 等。"""
        return self._post_image("/match", image)

    def blacklist_add(self, image: ImageInput, description: str = "") -> dict:
        """添加黑名单，返回 {id, message}。"""
        return self._post_image("/blacklist/add", image, description)

    def blacklist_remove(self, image_id: int) -> dict:
        """删除黑名单条目。"""
        return self._delete(f"/blacklist/{image_id}")

    def blacklist_list(self) -> dict:
        """列出黑名单。"""
        return self._get("/blacklist")

    def whitelist_add(self, image: ImageInput, description: str = "") -> dict:
        """添加白名单。"""
        return self._post_image("/whitelist/add", image, description)

    def whitelist_remove(self, image_id: int) -> dict:
        """删除白名单条目。"""
        return self._delete(f"/whitelist/{image_id}")

    def whitelist_list(self) -> dict:
        """列出白名单。"""
        return self._get("/whitelist")
