from django.test import TestCase
from django.urls import reverse

from accounts.models import User


class FinanceDashboardRoleTests(TestCase):
    role_to_dashboard = {
        User.Role.SUPER_ADMIN: "finance:dashboard_super_admin",
        User.Role.STORE_MANAGER: "finance:dashboard_store_manager",
        User.Role.STOREKEEPER: "finance:dashboard_storekeeper",
        User.Role.ACCOUNTANT: "finance:dashboard_accountant",
        User.Role.SALES_OFFICER: "finance:dashboard_sales_officer",
        User.Role.AUDITOR: "finance:dashboard_auditor",
    }

    def _build_user(self, role):
        return User.objects.create_user(
            username=f"user_{role}",
            password="testpass123",
            role=role,
        )

    def test_dashboard_router_redirects_to_role_dashboard(self):
        router_url = reverse("finance:dashboard")

        for role, target_name in self.role_to_dashboard.items():
            with self.subTest(role=role):
                user = self._build_user(role)
                self.client.force_login(user)

                response = self.client.get(router_url)

                self.assertRedirects(
                    response,
                    reverse(target_name),
                    fetch_redirect_response=False,
                )
                self.client.logout()

    def test_role_can_open_assigned_dashboard(self):
        for role, target_name in self.role_to_dashboard.items():
            with self.subTest(role=role):
                user = self._build_user(role)
                self.client.force_login(user)

                response = self.client.get(reverse(target_name))

                self.assertEqual(response.status_code, 200)
                self.client.logout()

    def test_role_cannot_open_unassigned_dashboard(self):
        storekeeper = self._build_user(User.Role.STOREKEEPER)
        self.client.force_login(storekeeper)
        response = self.client.get(reverse("finance:dashboard_accountant"))
        self.assertEqual(response.status_code, 403)

        self.client.logout()
        accountant = self._build_user(User.Role.ACCOUNTANT)
        self.client.force_login(accountant)
        response = self.client.get(reverse("finance:dashboard_storekeeper"))
        self.assertEqual(response.status_code, 403)

    def test_dashboard_data_requires_login(self):
        response = self.client.get(reverse("finance:dashboard_data"))
        self.assertEqual(response.status_code, 302)

    def test_dashboard_data_returns_json_for_each_role(self):
        for role in self.role_to_dashboard:
            with self.subTest(role=role):
                user = self._build_user(role)
                self.client.force_login(user)

                response = self.client.get(reverse("finance:dashboard_data"))
                payload = response.json()

                self.assertEqual(response.status_code, 200)
                self.assertEqual(payload["role"], user.effective_role)
                self.assertIn("data", payload)
                self.assertIn("period", payload)
                self.client.logout()

    def test_dashboard_data_respects_period_query(self):
        user = self._build_user(User.Role.SUPER_ADMIN)
        self.client.force_login(user)

        response = self.client.get(
            reverse("finance:dashboard_data"),
            {"start": "2026-01-01", "end": "2026-01-31"},
        )
        payload = response.json()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(payload["period"]["start"], "2026-01-01")
        self.assertEqual(payload["period"]["end"], "2026-01-31")
