import os

from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client, TestCase
from django.urls import reverse

from jobs.application_utils import attach_profile_cv
from jobs.forms import JobApplicationForm
from jobs.models import Job, JobApplication, JobCategory
from seekers.models import SeekerProfile

User = get_user_model()


class JobApplyTests(TestCase):
    def setUp(self):
        self.client = Client()
        self.category = JobCategory.objects.create(name='Technology', slug='technology')
        self.employer = User.objects.create_superuser(
            username='employer_apply',
            email='employer_apply@example.com',
            password='TestPass123!',
        )
        self.seeker = User.objects.create_user(
            username='seeker_apply',
            email='seeker_apply@example.com',
            password='TestPass123!',
            role=User.Role.SEEKER,
            phone='+260970000000',
        )
        self.profile = SeekerProfile.objects.create(
            user=self.seeker,
            slug='seeker-apply',
            full_name='Apply Seeker',
            headline='Developer',
            category='Technology',
            category_slug='technology',
            location='Lusaka',
            is_public=True,
            cv_file=SimpleUploadedFile(
                'profile_cv.pdf',
                b'%PDF-1.4 profile cv',
                content_type='application/pdf',
            ),
        )
        self.job = Job.objects.create(
            title='Apply Test Role',
            slug='apply-test-role',
            company_name='Test Co',
            company_slug='test-co',
            company_initials='TC',
            location='Lusaka',
            category=self.category,
            description='Role description',
            requirements='Python',
            posted_by=self.employer,
            is_active=True,
            application_methods=['ats'],
        )

    def test_form_marks_linkedin_optional(self):
        form = JobApplicationForm(job=self.job, profile=self.profile)
        self.assertFalse(form.fields['linkedin_url'].required)
        self.assertIn('optional', form.fields['linkedin_url'].label.lower())

    def test_form_accepts_empty_linkedin(self):
        form = JobApplicationForm(data={'cover_letter': 'Hello'}, job=self.job, profile=self.profile)
        self.assertTrue(form.is_valid())

    def test_attach_profile_cv_copies_file(self):
        application = JobApplication(
            job=self.job,
            applicant=self.seeker,
            cover_letter='Interested',
        )
        attached = attach_profile_cv(application, self.profile)
        self.assertTrue(attached)
        self.assertTrue(application.cv_file.name)
        self.assertIn('profile_cv', os.path.basename(application.cv_file.name))

    def test_apply_without_upload_uses_profile_cv(self):
        self.client.login(username='seeker_apply', password='TestPass123!')
        response = self.client.post(
            reverse('jobs:apply', kwargs={'slug': self.job.slug}),
            {'cover_letter': 'I am a great fit.'},
        )
        self.assertEqual(response.status_code, 302)
        application = JobApplication.objects.get(job=self.job, applicant=self.seeker)
        self.assertTrue(application.cv_file.name)
        self.assertIn('profile_cv', os.path.basename(application.cv_file.name))

    def test_apply_with_upload_overrides_profile_cv(self):
        self.client.login(username='seeker_apply', password='TestPass123!')
        custom_cv = SimpleUploadedFile(
            'custom_cv.pdf',
            b'%PDF-1.4 custom cv',
            content_type='application/pdf',
        )
        response = self.client.post(
            reverse('jobs:apply', kwargs={'slug': self.job.slug}),
            {
                'cover_letter': 'Custom CV attached.',
                'cv_file': custom_cv,
            },
        )
        self.assertEqual(response.status_code, 302)
        application = JobApplication.objects.get(job=self.job, applicant=self.seeker)
        self.assertIn('custom_cv', os.path.basename(application.cv_file.name))

    def test_job_detail_shows_profile_cv_notice(self):
        self.client.login(username='seeker_apply', password='TestPass123!')
        response = self.client.get(reverse('jobs:detail', kwargs={'slug': self.job.slug}))
        self.assertContains(response, 'Your profile CV will be attached')
        self.assertContains(response, 'profile_cv')
