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

from apps.accounts.forms import SignUpForm
from apps.accounts.models import ClientProfile


class SignUpFormTest(TestCase):
    def test_signup_creates_user_and_profile(self):
        form = SignUpForm(
            data={
                "username": "client1",
                "first_name": "Ada",
                "last_name": "Lovelace",
                "email": "ada@example.com",
                "company": "Analytical Engines",
                "phone": "+1 555 0100",
                "password1": "Str0ngPass!word",
                "password2": "Str0ngPass!word",
            }
        )
        self.assertTrue(form.is_valid(), form.errors)
        user = form.save()
        self.assertEqual(user.email, "ada@example.com")
        profile = ClientProfile.objects.get(user=user)
        self.assertEqual(profile.company, "Analytical Engines")


class AccountViewsTest(TestCase):
    def test_signup_page_renders(self):
        response = self.client.get(reverse("accounts:signup"))
        self.assertEqual(response.status_code, 200)

    def test_logged_out_nav_exposes_login_and_registration(self):
        response = self.client.get(reverse("pages:home"))
        navbar = response.content.decode().split("</nav>", 1)[0]

        self.assertIn("Login", navbar)
        self.assertIn("Start a Project", navbar)
        self.assertIn(reverse("accounts:login"), navbar)
        self.assertIn(reverse("accounts:signup"), navbar)

    def test_signup_creates_account_and_logs_in(self):
        response = self.client.post(
            reverse("accounts:signup"),
            data={
                "username": "newclient",
                "first_name": "Grace",
                "last_name": "Hopper",
                "email": "grace@example.com",
                "company": "",
                "phone": "",
                "password1": "Str0ngPass!word",
                "password2": "Str0ngPass!word",
            },
        )
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.url, reverse("projects:dashboard"))
        self.assertTrue(User.objects.filter(username="newclient").exists())

    def test_login_required_for_profile(self):
        response = self.client.get(reverse("accounts:profile"))
        self.assertEqual(response.status_code, 302)
        self.assertIn(reverse("accounts:login"), response.url)

    def test_authenticated_nav_uses_sidebar_for_account_actions(self):
        user = User.objects.create_user(
            username="workspace-user",
            email="workspace@example.com",
            password="Str0ngPass!word",
        )
        self.client.force_login(user)

        response = self.client.get(reverse("projects:dashboard"))

        self.assertContains(response, "Profile &amp; account")
        self.assertContains(response, "Project briefs")
        navbar = response.content.decode().split("</nav>", 1)[0]
        self.assertNotIn("My Projects", navbar)
        self.assertNotIn("Logout", navbar)
        self.assertIn("navbar-account", navbar)
        self.assertIn("navbar-account-dropdown", navbar)
        self.assertIn("Your profile", navbar)
        self.assertIn("New project brief", navbar)
        self.assertIn("Contact support", navbar)
        self.assertIn("Sign out", navbar)
        self.assertIn("default-avatar.png", navbar)

    def test_profile_exposes_professional_fields_and_avatar_upload(self):
        user = User.objects.create_user(
            username="researcher",
            first_name="Marie",
            last_name="Curie",
            email="marie@example.com",
            password="Str0ngPass!word",
        )
        self.client.force_login(user)

        response = self.client.get(reverse("accounts:profile"))

        self.assertContains(response, 'enctype="multipart/form-data"')
        self.assertContains(response, 'name="avatar"')
        self.assertContains(response, 'name="job_title"')
        self.assertContains(response, 'name="bio"')
        self.assertNotContains(response, 'name="timezone"')

    def test_logout_requires_post_and_clears_session(self):
        self.client.login(username="newclient", password="Str0ngPass!word")
        response = self.client.get(reverse("accounts:logout"))
        self.assertEqual(response.status_code, 405)

        response = self.client.post(reverse("accounts:logout"))
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.url, reverse("pages:home"))

        response = self.client.get(reverse("projects:dashboard"))
        self.assertEqual(response.status_code, 302)
        self.assertIn(reverse("accounts:login"), response.url)
