import json
from django.test import TestCase, Client, RequestFactory, override_settings
from django.urls import reverse
from .models import ContactRequest
from .context_processors import site_context


# ─────────────────────────────────────────────
# Helpers
# ─────────────────────────────────────────────
VALID_CONTACT = {
    'last_name':  'Coulibaly',
    'first_name': 'Israel',
    'email':      'test@jool-int.com',
    'phone':      '+225 07 00 00 00',
    'message':    'Demande de démonstration.',
}


# ─────────────────────────────────────────────
# Pages publiques — codes HTTP
# ─────────────────────────────────────────────
class PublicPagesTest(TestCase):
    def setUp(self):
        self.client = Client()

    def _get(self, name):
        return self.client.get(reverse(f'core:{name}'))

    def test_home_200(self):
        self.assertEqual(self._get('home').status_code, 200)

    def test_about_200(self):
        self.assertEqual(self._get('about').status_code, 200)

    def test_kiriq_200(self):
        self.assertEqual(self._get('kiriq').status_code, 200)

    def test_monitor_200(self):
        self.assertEqual(self._get('monitor').status_code, 200)

    def test_joolid_200(self):
        self.assertEqual(self._get('joolid').status_code, 200)

    def test_monagro_200(self):
        self.assertEqual(self._get('monagro').status_code, 200)

    def test_privacy_200(self):
        self.assertEqual(self._get('privacy').status_code, 200)

    def test_robots_txt_200(self):
        r = self._get('robots_txt')
        self.assertEqual(r.status_code, 200)
        self.assertIn('text/plain', r['Content-Type'])

    def test_sitemap_xml_200(self):
        r = self._get('sitemap_xml')
        self.assertEqual(r.status_code, 200)
        self.assertIn('xml', r['Content-Type'])


# ─────────────────────────────────────────────
# Templates — contenu minimal
# ─────────────────────────────────────────────
class TemplateContentTest(TestCase):
    def test_home_contains_products(self):
        r = self.client.get(reverse('core:home'))
        self.assertContains(r, 'KIRiQ')
        self.assertContains(r, 'Jool Monitor')
        self.assertContains(r, 'Jool ID')
        self.assertContains(r, 'Mon Agro')

    def test_kiriq_page_title(self):
        r = self.client.get(reverse('core:kiriq'))
        self.assertContains(r, 'KIRiQ')

    def test_monitor_page_title(self):
        r = self.client.get(reverse('core:monitor'))
        self.assertContains(r, 'Monitor')

    def test_joolid_page_title(self):
        r = self.client.get(reverse('core:joolid'))
        self.assertContains(r, 'Jool ID')

    def test_monagro_page_title(self):
        r = self.client.get(reverse('core:monagro'))
        self.assertContains(r, 'Mon Agro')

    def test_about_has_solutions_section(self):
        r = self.client.get(reverse('core:about'))
        self.assertContains(r, 'Nos solutions')
        self.assertContains(r, 'Mon Agro')

    def test_privacy_noindex(self):
        r = self.client.get(reverse('core:privacy'))
        self.assertContains(r, 'noindex')

    def test_robots_txt_content(self):
        r = self.client.get(reverse('core:robots_txt'))
        content = r.content.decode()
        self.assertIn('User-agent', content)
        self.assertIn('sitemap', content.lower())

    def test_sitemap_xml_has_urls(self):
        r = self.client.get(reverse('core:sitemap_xml'))
        content = r.content.decode()
        self.assertIn('<url>', content)
        self.assertIn('jool-international.com', content)


# ─────────────────────────────────────────────
# Formulaire de contact
# ─────────────────────────────────────────────
class ContactFormTest(TestCase):
    def setUp(self):
        self.url = reverse('core:contact_ajax')

    def _post(self, data):
        return self.client.post(
            self.url, data,
            HTTP_X_REQUESTED_WITH='XMLHttpRequest',
        )

    @override_settings(
        EMAIL_BACKEND='django.core.mail.backends.dummy.EmailBackend'
    )
    def test_valid_form_creates_contact(self):
        r = self._post(VALID_CONTACT)
        self.assertEqual(r.status_code, 200)
        body = json.loads(r.content)
        self.assertTrue(body['ok'])
        self.assertEqual(ContactRequest.objects.count(), 1)
        obj = ContactRequest.objects.first()
        self.assertEqual(obj.email, 'test@jool-int.com')

    def test_missing_required_fields_returns_400(self):
        r = self._post({'last_name': 'Coulibaly'})
        self.assertEqual(r.status_code, 400)
        body = json.loads(r.content)
        self.assertFalse(body['ok'])
        self.assertIn('errors', body)

    def test_invalid_email_returns_400(self):
        data = {**VALID_CONTACT, 'email': 'pas-un-email'}
        r = self._post(data)
        self.assertEqual(r.status_code, 400)
        body = json.loads(r.content)
        self.assertFalse(body['ok'])

    def test_invalid_phone_returns_400(self):
        data = {**VALID_CONTACT, 'phone': 'abc!!!'}
        r = self._post(data)
        self.assertEqual(r.status_code, 400)
        body = json.loads(r.content)
        self.assertFalse(body['ok'])

    def test_get_method_not_allowed(self):
        r = self.client.get(self.url)
        self.assertEqual(r.status_code, 405)

    @override_settings(
        EMAIL_BACKEND='django.core.mail.backends.dummy.EmailBackend'
    )
    def test_phone_optional(self):
        data = {k: v for k, v in VALID_CONTACT.items() if k != 'phone'}
        r = self._post(data)
        self.assertEqual(r.status_code, 200)
        self.assertTrue(json.loads(r.content)['ok'])


# ─────────────────────────────────────────────
# Modèle ContactRequest
# ─────────────────────────────────────────────
class ContactRequestModelTest(TestCase):
    def test_str_representation(self):
        obj = ContactRequest(
            first_name='Israel',
            last_name='Coulibaly',
            email='test@jool-int.com',
        )
        self.assertIn('Israel', str(obj))
        self.assertIn('Coulibaly', str(obj))

    def test_is_read_default_false(self):
        obj = ContactRequest.objects.create(**VALID_CONTACT)
        self.assertFalse(obj.is_read)

    def test_ordering_newest_first(self):
        ContactRequest.objects.create(**VALID_CONTACT)
        data2 = {**VALID_CONTACT, 'email': 'second@jool-int.com'}
        ContactRequest.objects.create(**data2)
        first = ContactRequest.objects.first()
        self.assertEqual(first.email, 'second@jool-int.com')


# ─────────────────────────────────────────────
# Context processor — careers_enabled
# ─────────────────────────────────────────────
class ContextProcessorTest(TestCase):
    def setUp(self):
        self.factory = RequestFactory()

    @override_settings(CAREERS_ENABLED=False)
    def test_careers_disabled_in_context(self):
        r = self.client.get(reverse('core:home'))
        self.assertFalse(r.context['careers_enabled'])
        self.assertNotContains(r, 'Carrières')

    @override_settings(CAREERS_ENABLED=False)
    def test_careers_disabled_returns_false(self):
        request = self.factory.get('/')
        ctx = site_context(request)
        self.assertFalse(ctx['careers_enabled'])
        self.assertEqual(ctx['open_jobs_count'], 0)

    @override_settings(CAREERS_ENABLED=True)
    def test_careers_enabled_returns_true(self):
        request = self.factory.get('/')
        ctx = site_context(request)
        self.assertTrue(ctx['careers_enabled'])
        self.assertIn('open_jobs_count', ctx)
