"""Tests for the JSON chat API (/api/chat, /api/upload, /api/chat/history)."""

import io
from unittest.mock import patch

# ── POST /api/chat ────────────────────────────────────────────────────────────


def test_api_chat_success(client):
    with patch("dashboard.routes.chat_api.agent_chat", return_value="Hello."):
        response = client.post(
            "/api/chat",
            json={"messages": [{"role": "user", "content": "hello"}]},
        )

    assert response.status_code == 200
    data = response.json()
    assert data["reply"] == "Hello."
    assert "timestamp" in data


def test_api_chat_multimodal_content(client):
    """Multimodal content arrays should extract text parts."""
    with patch("dashboard.routes.chat_api.agent_chat", return_value="I see an image."):
        response = client.post(
            "/api/chat",
            json={
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": "What is this?"},
                            {"type": "image_url", "image_url": {"url": "/uploads/test.jpg"}},
                        ],
                    }
                ]
            },
        )

    assert response.status_code == 200
    assert response.json()["reply"] == "I see an image."


def test_api_chat_empty_messages(client):
    response = client.post("/api/chat", json={"messages": []})
    assert response.status_code == 400
    assert "error" in response.json()


def test_api_chat_missing_messages(client):
    response = client.post("/api/chat", json={"foo": "bar"})
    assert response.status_code == 400
    assert "messages" in response.json()["error"]


def test_api_chat_no_user_message(client):
    response = client.post(
        "/api/chat",
        json={"messages": [{"role": "assistant", "content": "hi"}]},
    )
    assert response.status_code == 400
    assert "No user message" in response.json()["error"]


def test_api_chat_ollama_offline(client):
    with patch(
        "dashboard.routes.chat_api.agent_chat",
        side_effect=ConnectionError("Ollama unreachable"),
    ):
        response = client.post(
            "/api/chat",
            json={"messages": [{"role": "user", "content": "hello"}]},
        )

    assert response.status_code == 503
    data = response.json()
    assert "offline" in data["error"].lower() or "unreachable" in data["error"].lower()


def test_api_chat_logs_to_message_log(client):
    from dashboard.store import message_log

    with patch("dashboard.routes.chat_api.agent_chat", return_value="Reply."):
        client.post(
            "/api/chat",
            json={"messages": [{"role": "user", "content": "test msg"}]},
        )

    entries = message_log.all()
    assert len(entries) == 2
    assert entries[0].role == "user"
    assert entries[0].content == "test msg"
    assert entries[1].role == "agent"
    assert entries[1].content == "Reply."


def test_api_chat_invalid_json(client):
    response = client.post(
        "/api/chat",
        content=b"not json",
        headers={"content-type": "application/json"},
    )
    assert response.status_code == 400


# ── POST /api/upload ──────────────────────────────────────────────────────────


def test_api_upload_file(client, tmp_path):
    with patch("dashboard.routes.chat_api._UPLOAD_DIR", str(tmp_path)):
        response = client.post(
            "/api/upload",
            files={"file": ("test.txt", io.BytesIO(b"hello world"), "text/plain")},
        )

    assert response.status_code == 200
    data = response.json()
    assert data["fileName"] == "test.txt"
    assert data["mimeType"] == "text/plain"
    assert "/uploads/" in data["url"]


def test_api_upload_image(client, tmp_path):
    # 1x1 red PNG
    png = (
        b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01"
        b"\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00"
    )
    with patch("dashboard.routes.chat_api._UPLOAD_DIR", str(tmp_path)):
        response = client.post(
            "/api/upload",
            files={"file": ("photo.png", io.BytesIO(png), "image/png")},
        )

    assert response.status_code == 200
    data = response.json()
    assert data["fileName"] == "photo.png"
    assert data["mimeType"] == "image/png"


# ── GET /api/chat/history ────────────────────────────────────────────────────


def test_api_chat_history_empty(client):
    response = client.get("/api/chat/history")
    assert response.status_code == 200
    assert response.json()["messages"] == []


def test_api_chat_history_after_chat(client):
    with patch("dashboard.routes.chat_api.agent_chat", return_value="Hi!"):
        client.post(
            "/api/chat",
            json={"messages": [{"role": "user", "content": "hello"}]},
        )

    response = client.get("/api/chat/history")
    assert response.status_code == 200
    msgs = response.json()["messages"]
    assert len(msgs) == 2
    assert msgs[0]["role"] == "user"
    assert msgs[1]["role"] == "agent"


# ── DELETE /api/chat/history ──────────────────────────────────────────────────


def test_api_clear_history(client):
    from dashboard.store import message_log

    message_log.append(role="user", content="old", timestamp="00:00:00")

    response = client.delete("/api/chat/history")
    assert response.status_code == 200
    assert response.json()["success"] is True
    assert len(message_log) == 0
