from django.contrib.auth import get_user_model
from django.test import TestCase
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient

from accounts.models import ShipperProfile, UserRole
from core.models import Notification

User = get_user_model()


class AuthNotificationsApiTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user('notif@test.com', email='notif@test.com', password='secret')
        UserRole.objects.create(user=self.user, role=UserRole.Role.SHIPPER, phone='', language='en')
        ShipperProfile.objects.create(user=self.user, account_type=ShipperProfile.AccountType.INDIVIDUAL)

        self.other = User.objects.create_user('othernotif@test.com', email='othernotif@test.com', password='secret')
        UserRole.objects.create(user=self.other, role=UserRole.Role.SHIPPER, phone='', language='en')
        ShipperProfile.objects.create(user=self.other, account_type=ShipperProfile.AccountType.INDIVIDUAL)

        for idx in range(25):
            Notification.objects.create(
                title=f'N{idx}',
                message='msg',
                type='document_expiring',
                user=self.user,
                data={'i': idx},
                seen=False,
            )
        Notification.objects.create(
            title='bid',
            message='bid msg',
            type='bid_accepted',
            user=self.user,
            data={'trip_id': '1'},
            seen=False,
        )
        Notification.objects.create(
            title='trip',
            message='trip msg',
            type='trip_status',
            user=self.user,
            data={'trip_id': '1'},
            seen=False,
        )
        Notification.objects.create(
            title='other',
            message='msg',
            type='test',
            user=self.other,
            data={'i': 999},
            seen=False,
        )

        token, _ = Token.objects.get_or_create(user=self.user)
        self.client = APIClient()
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token.key}')

    def test_returns_latest_20_notifications_for_requested_user_id(self):
        r = self.client.get(f'/api/auth/notifications/?user_id={self.user.id}')
        self.assertEqual(r.status_code, 200)
        payload = r.json()['data']
        self.assertEqual(payload['user_id'], self.user.id)
        self.assertEqual(payload['offset'], 0)
        self.assertEqual(payload['limit'], 20)
        self.assertEqual(payload['total'], 25)
        self.assertEqual(payload['count'], 20)
        self.assertEqual(payload['results'][0]['title'], 'N24')
        self.assertEqual(payload['results'][0]['type'], 'document_expiring')

    def test_excludes_trip_and_bid_notifications(self):
        r = self.client.get(f'/api/auth/notifications/?user_id={self.user.id}')
        types = {row['type'] for row in r.json()['data']['results']}
        self.assertNotIn('bid_accepted', types)
        self.assertNotIn('trip_status', types)

    def test_supports_offset_pagination(self):
        r = self.client.get(f'/api/auth/notifications/?user_id={self.user.id}&offset=20')
        self.assertEqual(r.status_code, 200)
        payload = r.json()['data']
        self.assertEqual(payload['count'], 5)
        self.assertEqual(payload['results'][0]['title'], 'N4')

    def test_requires_user_id(self):
        r = self.client.get('/api/auth/notifications/')
        self.assertEqual(r.status_code, 400)
        self.assertEqual(r.json()['error'], 'Missing user_id.')

    def test_forbids_non_admin_access_to_other_user_id(self):
        r = self.client.get(f'/api/auth/notifications/?user_id={self.other.id}')
        self.assertEqual(r.status_code, 403)
