import re

from unittest.mock import patch
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

from .base import FunctionalTest
from apps.lyric.tasks import send_login_email_task


TEST_EMAIL = "disco@test.io"
SUBJECT = "A magic login link to your Dashboard"


class LoginTest(FunctionalTest):
    @patch('apps.lyric.tasks.requests.post')
    @patch('apps.lyric.views.send_login_email_task.delay',
           side_effect=send_login_email_task)
    def test_login_using_magic_link(self, mock_delay, mock_post):
        # Mock successful Mailgun API response
        mock_post.return_value.status_code = 200

        self.browser.get(self.live_server_url)
        self.browser.find_element(By.CSS_SELECTOR, "input[name=email]").send_keys(
            TEST_EMAIL, Keys.ENTER
        )

        self.wait_for(
            lambda: self.assertIn(
                "Check your email",
                self.browser.find_element(By.CSS_SELECTOR, "body").text,
            )
        )

        if self.test_server:
            return

        # Verify Mailgun API was called
        self.assertEqual(mock_post.call_count, 1)
        call_kwargs = mock_post.call_args.kwargs

        # Check email data
        self.assertEqual(call_kwargs['data']['to'], TEST_EMAIL)
        self.assertEqual(call_kwargs['data']['subject'], SUBJECT)

        # Extract magic link URL from email body
        email_body = call_kwargs['data']['text']
        self.assertIn("Use this magic link to login to your Dashboard", email_body)
        url_search = re.search(r"http://.+/.+$", email_body)
        if not url_search:
            self.fail(f"Could not find url in email body:\n{email_body}")
        url = url_search.group(0)
        self.assertIn(self.live_server_url, url)

        self.browser.get(url)

        self.wait_to_be_logged_in(email=TEST_EMAIL)

        self.browser.find_element(By.CSS_SELECTOR, "#id_logout").click()
        self.confirm_guard()

        self.wait_to_be_logged_out(email=TEST_EMAIL)
