import threading

from flask import Flask

from flask_discord_interactions import (
    DiscordInteractions,
    ResponseType,
    InteractionType,
    Message,
)


def test_flask():
    app = Flask(__name__)
    app.config["DONT_VALIDATE_SIGNATURE"] = True
    app.config["DONT_REGISTER_WITH_DISCORD"] = True

    discord = DiscordInteractions(app)

    @discord.command()
    def ping(ctx, pong: str = "ping"):
        return f"Ping {pong}!"

    discord.set_route("/interactions")

    with app.test_client() as client:
        response = client.post(
            "/interactions",
            json={
                "type": InteractionType.APPLICATION_COMMAND,
                "id": 1,
                "channel_id": "",
                "guild_id": "",
                "token": "",
                "data": {
                    "id": 1,
                    "name": "ping",
                    "options": [{"type": 1, "name": "Pong"}],
                },
                "member": {"id": 1, "nick": "", "user": {"id": 1, "username": "test"}},
            },
        )

        assert response.status_code == 200
        assert response.get_json()["type"] == ResponseType.CHANNEL_MESSAGE_WITH_SOURCE

        assert response.get_json()["data"]["content"] == "Ping Pong!"


def test_app_factory():
    discord = DiscordInteractions()

    @discord.command()
    def ping(ctx, pong: str = "ping"):
        return f"Ping {pong}!"

    def create_app():
        app = Flask(__name__)
        discord.init_app(app)
        discord.set_route("/interactions", app=app)
        return app

    app = create_app()
    app.config["DONT_VALIDATE_SIGNATURE"] = True
    app.config["DONT_REGISTER_WITH_DISCORD"] = True

    with app.test_client() as client:
        response = client.post(
            "/interactions",
            json={
                "type": InteractionType.APPLICATION_COMMAND,
                "id": 1,
                "channel_id": "",
                "guild_id": "",
                "token": "",
                "data": {
                    "id": 1,
                    "name": "ping",
                    "options": [{"type": 1, "name": "Pong"}],
                },
                "member": {"id": 1, "nick": "", "user": {"id": 1, "username": "test"}},
            },
        )

        assert response.status_code == 200
        assert response.get_json()["type"] == ResponseType.CHANNEL_MESSAGE_WITH_SOURCE

        assert response.get_json()["data"]["content"] == "Ping Pong!"


def test_followup():
    app = Flask(__name__)
    app.config["DONT_VALIDATE_SIGNATURE"] = True
    app.config["DONT_REGISTER_WITH_DISCORD"] = True

    discord = DiscordInteractions(app)

    ref_to_thread = None

    @discord.command()
    def ping(ctx):
        nonlocal ref_to_thread

        def do_followup():
            ctx.edit("hi")

        ref_to_thread = thread = threading.Thread(target=do_followup)
        thread.start()

        return Message(deferred=True)

    discord.set_route("/interactions")

    with app.test_client() as client:
        response = client.post(
            "/interactions",
            json={
                "type": InteractionType.APPLICATION_COMMAND,
                "id": 1,
                "channel_id": "",
                "guild_id": "",
                "token": "",
                "data": {
                    "id": 1,
                    "name": "ping",
                },
            },
        )

    # Make sure we wait for the thread to complete
    ref_to_thread.join()
