"""Tests for error classes and error page rendering."""
from __future__ import annotations

import pytest

from shared.browser.app.errors import AppError, _error_page


# ---------------------------------------------------------------------------
# AppError
# ---------------------------------------------------------------------------

class TestAppError:
    def test_single_message(self):
        err = AppError("Something went wrong")
        assert str(err) == "Something went wrong"
        assert err.messages == ["Something went wrong"]
        assert err.status_code == 400

    def test_custom_status_code(self):
        err = AppError("Not found", status_code=404)
        assert err.status_code == 404
        assert str(err) == "Not found"

    def test_list_of_messages(self):
        err = AppError(["Error 1", "Error 2", "Error 3"])
        assert err.messages == ["Error 1", "Error 2", "Error 3"]
        assert str(err) == "Error 1"  # first message as str

    def test_tuple_of_messages(self):
        err = AppError(("A", "B"))
        assert err.messages == ["A", "B"]

    def test_set_of_messages(self):
        err = AppError({"only one"})
        assert err.messages == ["only one"]

    def test_empty_list(self):
        err = AppError([])
        assert err.messages == []
        assert str(err) == ""

    def test_is_value_error(self):
        """AppError should be catchable as ValueError for backwards compat."""
        err = AppError("test")
        assert isinstance(err, ValueError)

    def test_default_status_is_400(self):
        err = AppError("test")
        assert err.status_code == 400

    def test_integer_message_coerced(self):
        err = AppError([42, "text"])
        assert err.messages == ["42", "text"]

    def test_status_code_override(self):
        err = AppError("conflict", status_code=409)
        assert err.status_code == 409

    def test_messages_are_strings(self):
        err = AppError([None, 123, True])
        assert all(isinstance(m, str) for m in err.messages)


# ---------------------------------------------------------------------------
# _error_page
# ---------------------------------------------------------------------------

class TestErrorPage:
    def test_returns_html_string(self):
        html = _error_page("Not Found")
        assert isinstance(html, str)
        assert "<!DOCTYPE html>" in html

    def test_contains_message(self):
        html = _error_page("Something broke")
        assert "Something broke" in html

    def test_contains_error_gif(self):
        html = _error_page("Error")
        assert "/static/errors/error.gif" in html

    def test_contains_reload_link(self):
        html = _error_page("Error")
        assert "Reload" in html

    def test_html_in_message(self):
        """Messages can contain HTML (used by fragment_error handler)."""
        html = _error_page("The <b>account</b> service is unavailable")
        assert "<b>account</b>" in html

    def test_self_contained(self):
        """Error page should include its own styles (no external CSS deps)."""
        html = _error_page("Error")
        assert "<style>" in html
        assert "</style>" in html
