"""Tests for company follow and follower notifications."""
from django.core import mail
from django.test import TestCase
from django.urls import reverse

from accounts.models import User, UserNotification
from companies.models import Company, CompanyFollow
from jobs.category_data import sync_pezajob_categories
from jobs.models import JobCategory
from subscriptions.models import CompanySubscription, SubscriptionPlan


class CompanyFollowTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        sync_pezajob_categories(deactivate_unknown=False)
        cls.job_category = JobCategory.objects.get(slug='information-technology-software')
        cls.seeker = User.objects.create_user(
            username='follow_seeker',
            email='follow-seeker@test.com',
            password='testpass123',
            role=User.Role.SEEKER,
        )
        cls.employer = User.objects.create_user(
            username='follow_employer',
            email='follow-employer@test.com',
            password='testpass123',
            role=User.Role.COMPANY,
        )
        cls.company = Company.objects.create(
            name='Follow Test Co',
            slug='follow-test-co',
            initials='FT',
            industry='Tech',
            location='Lusaka',
            description='Original description',
            owner=cls.employer,
            is_public=True,
        )
        plan, _ = SubscriptionPlan.objects.get_or_create(
            slug='company-starter',
            defaults={
                'name': 'Starter',
                'audience': SubscriptionPlan.Audience.COMPANY,
                'category': SubscriptionPlan.Category.RECRUITMENT,
                'price_monthly': 500,
                'features': 'Post jobs',
            },
        )
        CompanySubscription.objects.create(company=cls.company, plan=plan, is_active=True)

    def test_seeker_can_follow_and_unfollow_company(self):
        self.client.login(username='follow_seeker', password='testpass123')
        url = reverse('companies:follow_toggle', kwargs={'slug': self.company.slug})

        response = self.client.post(url)
        self.assertEqual(response.status_code, 302)
        self.assertTrue(CompanyFollow.objects.filter(user=self.seeker, company=self.company).exists())

        response = self.client.post(url)
        self.assertEqual(response.status_code, 302)
        self.assertFalse(CompanyFollow.objects.filter(user=self.seeker, company=self.company).exists())

    def test_new_job_notifies_followers(self):
        CompanyFollow.objects.create(user=self.seeker, company=self.company)
        mail.outbox.clear()

        self.client.login(username='follow_employer', password='testpass123')
        response = self.client.post(reverse('employers:post_job'), {
            'title': 'Follow Notify Role',
            'company_industry': 'Information Technology & Software',
            'category': self.job_category.pk,
            'location_scope': 'single',
            'location_country': 'ZM',
            'location_region': 'Lusaka Province',
            'location_city': 'Lusaka',
            'location_regions_multi': [],
            'location_city_text': '',
            'job_type': 'full_time',
            'experience_years_min': 3,
            'experience_years_max': 5,
            'positions_total': 1,
            'application_methods': ['email'],
            'how_to_apply': 'careers@example.com',
            'description': 'Role description',
            'responsibilities': 'Build features',
            'requirements': 'Python',
            'benefits': 'Medical',
            'ongoing_vacancy': 'on',
        })
        self.assertEqual(response.status_code, 302)

        self.assertEqual(UserNotification.objects.filter(recipient=self.seeker, notification_type='company_new_job').count(), 1)
        note = UserNotification.objects.get(recipient=self.seeker, notification_type='company_new_job')
        self.assertEqual(note.notification_type, 'company_new_job')
        self.assertIn('Follow Test Co', note.title)
        self.assertEqual(len(mail.outbox), 1)

    def test_profile_update_notifies_followers(self):
        from companies.follow_notifications import notify_followers_profile_updated

        CompanyFollow.objects.create(user=self.seeker, company=self.company)
        self.company.description = 'Updated company description for followers.'
        self.company.save(update_fields=['description', 'updated_at'])
        notify_followers_profile_updated(self.company)

        note = UserNotification.objects.filter(
            recipient=self.seeker,
            notification_type='company_profile_updated',
        ).first()
        self.assertIsNotNone(note)
        self.assertIn('updated', note.title.lower())

    def test_notifications_page_marks_as_read(self):
        UserNotification.objects.create(
            recipient=self.seeker,
            title='Test alert',
            body='Body',
            notification_type='company_new_job',
            is_read=False,
        )
        self.client.login(username='follow_seeker', password='testpass123')
        response = self.client.get(reverse('accounts:notifications'))
        self.assertEqual(response.status_code, 200)
        self.assertFalse(UserNotification.objects.filter(recipient=self.seeker, is_read=False, notification_type='company_profile_updated').exists())
