import unittest

from src.aiel_sdk.integrations.slack.remote import RemoteSlack
from src.aiel_sdk.integrations.slack.types import SlackPostMessageRequest


class _FakeIntegrationsService:
    def __init__(self):
        self.calls = []

    def invoke_action(self, workspace_id, project_id, connection_id, action, payload=None, request_id=None):
        self.calls.append(
            {
                "workspace_id": workspace_id,
                "project_id": project_id,
                "connection_id": connection_id,
                "action": action,
                "payload": payload,
                "request_id": request_id,
            }
        )
        if action in {"slack.auth_test", "slack.api_test"}:
            return {"ok": True, "team": "AIEL", "team_id": "T123", "user_id": "U1"}
        if action == "slack.post_message":
            params = (payload or {}).get("params") or {}
            return {"ok": True, "channel": params.get("channel"), "ts": "123.456"}
        return {"ok": False}


class _FakeClient:
    def __init__(self):
        self.integrations = _FakeIntegrationsService()


class RemoteSlackTests(unittest.TestCase):
    def test_auth_test_invokes_expected_action(self):
        client = _FakeClient()
        slack = RemoteSlack(client=client, workspace_id="w1", project_id="p1", connection_id="c1")

        out = slack.auth_test(request_id="req_1")

        self.assertEqual(out.team, "AIEL")
        self.assertEqual(client.integrations.calls[-1]["action"], "slack.auth_test")
        self.assertEqual(client.integrations.calls[-1]["request_id"], "req_1")

    def test_auth_test_can_use_api_test_action(self):
        client = _FakeClient()
        slack = RemoteSlack(client=client, workspace_id="w1", project_id="p1", connection_id="c1")

        out = slack.auth_test(use_api_test=True, request_id="req_1b")

        self.assertEqual(out.team, "AIEL")
        self.assertEqual(client.integrations.calls[-1]["action"], "slack.api_test")
        self.assertEqual(client.integrations.calls[-1]["request_id"], "req_1b")

    def test_post_message_uses_params(self):
        client = _FakeClient()
        slack = RemoteSlack(client=client, workspace_id="w1", project_id="p1", connection_id="c1")

        out = slack.post_message(
            SlackPostMessageRequest(channel="C1", text="Hello"),
            request_id="req_2",
        )

        self.assertEqual(out.ok, True)
        self.assertEqual(out.channel, "C1")
        call = client.integrations.calls[-1]
        self.assertEqual(call["action"], "slack.post_message")
        self.assertEqual(call["payload"], {"params": {"channel": "C1", "text": "Hello"}})
        self.assertEqual(call["request_id"], "req_2")

    def test_post_message_request_validation(self):
        with self.assertRaises(ValueError):
            SlackPostMessageRequest(channel="", text="hello").to_params()
        with self.assertRaises(ValueError):
            SlackPostMessageRequest(channel="C1", text="").to_params()


if __name__ == "__main__":
    unittest.main(verbosity=2)
