import pytest

from oiiai import (
    FetchBase,
    FetchZhipu,
    FetchOpenRouter,
    FetchModelScope,
    FetchSiliconFlow,
    FetchIFlow,
)


class DummyResponse:
    def __init__(self, json_data, status_code: int = 200):
        self._json_data = json_data
        self.status_code = status_code

    def json(self):
        return self._json_data

    def raise_for_status(self):
        if self.status_code >= 400:
            raise Exception(f"HTTP {self.status_code}")


def test_fetch_base_is_abstract():
    with pytest.raises(TypeError):
        FetchBase()  # type: ignore[abstract]


def test_fetch_openrouter_fetch_models(monkeypatch):
    captured = {}

    def fake_get(url, headers=None, timeout=None):  # type: ignore[override]
        captured["url"] = url
        captured["headers"] = headers or {}
        captured["timeout"] = timeout
        return DummyResponse({"data": [{"id": "model-1"}, {"id": "model-2"}, {"name": "no-id"}]})

    monkeypatch.setattr(
        "oiiai.fetchModelList.openrouter.requests.get",
        fake_get,
    )

    fetcher = FetchOpenRouter(api_key="test-key")
    models = fetcher.fetch_models()

    assert models == ["model-1", "model-2"]
    assert captured["headers"].get("Authorization") == "Bearer test-key"


def test_fetch_modelscope_fetch_models_with_list(monkeypatch):
    def fake_get(url):  # type: ignore[override]
        return DummyResponse(["a", "b"])

    monkeypatch.setattr(
        "oiiai.fetchModelList.modelscope.requests.get",
        fake_get,
    )

    fetcher = FetchModelScope()
    models = fetcher.fetch_models()

    assert models == ["a", "b"]


def test_fetch_siliconflow_fetch_models(monkeypatch):
    def fake_getenv(key, default=None):  # type: ignore[override]
        if key == "SILICONFLOW_API_KEY":
            return "dummy-key"
        return default

    def fake_get(url, headers=None):  # type: ignore[override]
        # Simulate {"data": [{"id": "m1"}, {"id": "m2"}]}
        return DummyResponse({"data": [{"id": "m1"}, {"id": "m2"}]})

    monkeypatch.setattr("oiiai.fetchModelList.siliconflow.os.getenv", fake_getenv)
    monkeypatch.setattr("oiiai.fetchModelList.siliconflow.requests.get", fake_get)

    fetcher = FetchSiliconFlow()
    models = fetcher.fetch_models()

    assert models == ["m1", "m2"]


def test_fetch_iflow_fetch_models(monkeypatch):
    def fake_post(url, json=None, headers=None, timeout=None):  # type: ignore[override]
        data = {
            "data": {
                "chat": [
                    {"modelName": "qwen-plus"},
                    {"showName": "deepseek"},
                    {"id": "other"},
                ]
            }
        }
        return DummyResponse(data)

    monkeypatch.setattr("oiiai.fetchModelList.iflow.requests.post", fake_post)

    fetcher = FetchIFlow()
    models = fetcher.fetch_models()

    # Expect flattened list of model names as strings
    assert models == ["qwen-plus", "deepseek", "other"]


def test_fetch_zhipu_extract_model_names():
    html = """
    <h2 id="通用模型"></h2>
    <table>
      <tbody>
        <tr><td>glm-4</td></tr>
        <tr><td>glm-4-flash</td></tr>
      </tbody>
    </table>
    """

    fetcher = FetchZhipu()
    result = fetcher._extract_model_names(html)

    assert "通用模型" in result
    assert result["通用模型"] == ["glm-4", "glm-4-flash"]
