"""
tests/test_deepseek_service.py
─────────────────────────────────────────────────────────────────
Operation Ollama-First v5.0 / Phase 15 — DeepSeek 直連 service 驗證
"""

from unittest.mock import patch, MagicMock

import pytest


@pytest.fixture(autouse=True)
def _reset_env(monkeypatch):
    """每 test 清 env"""
    monkeypatch.delenv('DEEPSEEK_DIRECT_ENABLED', raising=False)
    monkeypatch.delenv('DEEPSEEK_API_KEY', raising=False)
    yield


def test_is_available_requires_key_and_flag(monkeypatch):
    from services.deepseek_service import DeepSeekService

    svc = DeepSeekService()
    # 無 key 無 flag → False
    assert svc.is_available() is False

    # 只有 flag → False
    monkeypatch.setenv('DEEPSEEK_DIRECT_ENABLED', 'true')
    assert svc.is_available() is False

    # flag + key → True（需 reload module 取新 env）
    monkeypatch.setenv('DEEPSEEK_API_KEY', 'sk-test')
    import importlib
    import services.deepseek_service as ds
    importlib.reload(ds)
    assert ds.deepseek_service.is_available() is True


def test_generate_returns_failure_when_unavailable(monkeypatch):
    """flag OFF 時 generate 直接 return failure，不打 HTTP"""
    monkeypatch.setenv('DEEPSEEK_DIRECT_ENABLED', 'false')
    from services.deepseek_service import DeepSeekService

    svc = DeepSeekService()
    with patch('services.deepseek_service.requests.post') as mock_post:
        resp = svc.generate('test prompt')

    assert resp.success is False
    assert 'DEEPSEEK_DIRECT_ENABLED=false' in (resp.error or '') or \
           'API_KEY 未設' in (resp.error or '')
    mock_post.assert_not_called()


def test_generate_success_parses_usage(monkeypatch):
    """正常 200 回應應解 usage tokens"""
    monkeypatch.setenv('DEEPSEEK_DIRECT_ENABLED', 'true')
    monkeypatch.setenv('DEEPSEEK_API_KEY', 'sk-test')

    import importlib
    import services.deepseek_service as ds
    importlib.reload(ds)

    fake_resp = MagicMock(status_code=200)
    fake_resp.json.return_value = {
        'model': 'deepseek-chat',
        'choices': [{'message': {'content': 'Hello from DeepSeek'}}],
        'usage': {'prompt_tokens': 100, 'completion_tokens': 50},
    }
    with patch('services.deepseek_service.requests.post', return_value=fake_resp):
        resp = ds.deepseek_service.generate('hi', system_prompt='you are helpful')

    assert resp.success is True
    assert resp.content == 'Hello from DeepSeek'
    assert resp.input_tokens == 100
    assert resp.output_tokens == 50
    assert resp.model == 'deepseek-chat'


def test_generate_http_500_returns_failure(monkeypatch):
    monkeypatch.setenv('DEEPSEEK_DIRECT_ENABLED', 'true')
    monkeypatch.setenv('DEEPSEEK_API_KEY', 'sk-test')

    import importlib
    import services.deepseek_service as ds
    importlib.reload(ds)

    fake_resp = MagicMock(status_code=500)
    fake_resp.text = 'Internal Server Error'
    with patch('services.deepseek_service.requests.post', return_value=fake_resp):
        resp = ds.deepseek_service.generate('test')

    assert resp.success is False
    assert 'HTTP 500' in (resp.error or '')


def test_generate_timeout_returns_failure(monkeypatch):
    monkeypatch.setenv('DEEPSEEK_DIRECT_ENABLED', 'true')
    monkeypatch.setenv('DEEPSEEK_API_KEY', 'sk-test')

    import importlib
    import services.deepseek_service as ds
    importlib.reload(ds)

    import requests
    with patch('services.deepseek_service.requests.post',
               side_effect=requests.Timeout('60s')):
        resp = ds.deepseek_service.generate('test')

    assert resp.success is False
    assert 'timeout' in (resp.error or '').lower()


def test_check_connection_when_unavailable():
    from services.deepseek_service import DeepSeekService

    svc = DeepSeekService()
    # 無 key 無 flag
    assert svc.check_connection() is False
