from unittest.mock import MagicMock

from django.contrib.auth.models import User
from django.test import TestCase, override_settings
from django.urls import reverse

from apps.accounts.adapters import TecvicoSocialAccountAdapter
from apps.accounts.social import enabled_social_providers


class SocialAuthHelpersTest(TestCase):
    @override_settings(
        SOCIALACCOUNT_PROVIDERS={
            "google": {"APP": {"client_id": "g-id", "secret": "g-secret"}},
            "github": {"APP": {"client_id": "", "secret": ""}},
        }
    )
    def test_enabled_social_providers_filters_missing_credentials(self):
        providers = enabled_social_providers()
        self.assertEqual(len(providers), 1)
        self.assertEqual(providers[0]["id"], "google")


class SocialAuthViewsTest(TestCase):
    @override_settings(
        SOCIALACCOUNT_PROVIDERS={
            "google": {"APP": {"client_id": "g-id", "secret": "g-secret"}},
            "github": {"APP": {"client_id": "gh-id", "secret": "gh-secret"}},
        }
    )
    def test_login_page_renders_social_buttons(self):
        response = self.client.get(reverse("accounts:login"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Continue with")
        self.assertContains(response, "Google")
        self.assertContains(response, "GitHub")
        self.assertContains(response, "/accounts/google/login/")

    @override_settings(
        SOCIALACCOUNT_PROVIDERS={
            "google": {"APP": {"client_id": "", "secret": ""}},
            "github": {"APP": {"client_id": "", "secret": ""}},
        }
    )
    def test_login_page_hides_social_buttons_without_credentials(self):
        response = self.client.get(reverse("accounts:login"))
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "Continue with")

    @override_settings(
        SOCIALACCOUNT_PROVIDERS={
            "google": {"APP": {"client_id": "g-id", "secret": "g-secret"}},
            "github": {"APP": {"client_id": "gh-id", "secret": "gh-secret"}},
        }
    )
    def test_signup_page_renders_social_buttons(self):
        response = self.client.get(reverse("accounts:signup"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Google")
        self.assertContains(response, "GitHub")

    @override_settings(
        SOCIALACCOUNT_PROVIDERS={
            "google": {"APP": {"client_id": "g-id", "secret": "g-secret"}},
            "github": {"APP": {"client_id": "gh-id", "secret": "gh-secret"}},
        }
    )
    def test_google_login_page_uses_portal_styles(self):
        response = self.client.get(reverse("google_login"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Sign in with Google")
        self.assertContains(response, "social-oauth-card")
        self.assertContains(response, "navbar")
        self.assertContains(response, "Continue to Google")


class TecvicoSocialAccountAdapterTest(TestCase):
    def test_apply_profile_names_from_google(self):
        user = User(username="oauth-user", email="oauth@example.com")
        sociallogin = MagicMock()
        sociallogin.account.provider = "google"
        sociallogin.account.extra_data = {
            "given_name": "OAuth",
            "family_name": "User",
        }
        adapter = TecvicoSocialAccountAdapter()
        adapter._apply_profile_names(user, sociallogin)
        self.assertEqual(user.first_name, "OAuth")
        self.assertEqual(user.last_name, "User")

    def test_apply_profile_names_from_github(self):
        user = User(username="gh-user", email="gh@example.com")
        sociallogin = MagicMock()
        sociallogin.account.provider = "github"
        sociallogin.account.extra_data = {"name": "Grace Hopper"}
        adapter = TecvicoSocialAccountAdapter()
        adapter._apply_profile_names(user, sociallogin)
        self.assertEqual(user.first_name, "Grace")
        self.assertEqual(user.last_name, "Hopper")
