"""POST /tools-settings actually extracts providers from both request shapes.

Mocks save_tool_settings itself: this is only proving the endpoint parses the
request correctly, not the storage logic (covered in test_provider_settings.py).
"""
from unittest.mock import patch

from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)
TENANT = "org_8c32bf3e-6a18-4739-9b1c-94c0cf11125f"


def test_json_body_passes_providers_through():
    with patch("app.api.endpoints.bootstrap_tenant"), \
         patch("app.api.endpoints.save_tool_settings") as save:
        save.return_value = {"features": {}, "email": {}, "providers": {}}
        client.post("/tools-settings", json={
            "tenant_id": TENANT,
            "providers": {"chat_conversation": "whatsapp"}})

    assert save.call_args.kwargs["providers"] == {"chat_conversation": "whatsapp"}


def test_form_field_name_is_name_provider_not_name():
    # chat_conversation_provider, not chat_conversation -- the latter would
    # collide with a feature switch of the same name.
    with patch("app.api.endpoints.bootstrap_tenant"), \
         patch("app.api.endpoints.save_tool_settings") as save:
        save.return_value = {"features": {}, "email": {}, "providers": {}}
        client.post("/tools-settings", data={
            "tenant_id": TENANT,
            "chat_conversation_provider": "slack"})

    assert save.call_args.kwargs["providers"] == {"chat_conversation": "slack"}


def test_a_null_provider_reaches_save_tool_settings_to_clear_it():
    # Unlike a null feature/email field (dropped, meaning "leave alone"), a
    # null provider must reach save_tool_settings -- it is how a choice is
    # cleared back to unset.
    with patch("app.api.endpoints.bootstrap_tenant"), \
         patch("app.api.endpoints.save_tool_settings") as save:
        save.return_value = {"features": {}, "email": {}, "providers": {}}
        client.post("/tools-settings", json={
            "tenant_id": TENANT,
            "providers": {"chat_conversation": None}})

    assert save.call_args.kwargs["providers"] == {"chat_conversation": None}


def test_providers_alone_is_enough_to_pass_validation():
    # Previously only features/email could satisfy "something was supplied";
    # a providers-only request must not be rejected as empty.
    with patch("app.api.endpoints.bootstrap_tenant"), \
         patch("app.api.endpoints.save_tool_settings") as save:
        save.return_value = {"features": {}, "email": {}, "providers": {}}
        resp = client.post("/tools-settings", json={
            "tenant_id": TENANT,
            "providers": {"ticket_management": "galaxiq_ticketmanagement"}})

    assert resp.status_code == 200


def test_an_invalid_provider_choice_reaches_the_client_as_a_400():
    with patch("app.api.endpoints.bootstrap_tenant"), \
         patch("app.api.endpoints.save_tool_settings",
              side_effect=ValueError("chat_conversation must be one of (...)")):
        resp = client.post("/tools-settings", json={
            "tenant_id": TENANT,
            "providers": {"chat_conversation": "telegram"}})

    assert resp.status_code == 400
