"""Campus Overview (admin) — per-university insights page tests."""

import os
import unittest

os.environ["TEST_DATABASE_URL"] = "sqlite:///:memory:"

from werkzeug.security import generate_password_hash

from app import create_app
from app.auth import verification as v
from app.extensions import db
from app.models import User, UserProfile, UserRole


class CampusOverviewTests(unittest.TestCase):
    def setUp(self):
        self.app = create_app("testing")
        self.ctx = self.app.app_context()
        self.ctx.push()
        db.create_all()
        self.admin = self._user("admin@c.edu", UserRole.SUPER_ADMIN, "Admin")

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.ctx.pop()

    def _user(self, email, role=UserRole.STUDENT, name="Student"):
        u = User(email=email, password_hash=generate_password_hash("Passw0rd!"), is_verified=True, role=role)
        u.profile = UserProfile(full_name=name)
        db.session.add(u)
        db.session.commit()
        return u

    def _mk(self, email, university, outcome, name="Student"):
        u = self._user(email, name=name)
        v.submit_verification(u, "9876543210", university, "ID-" + email)
        if outcome == "verified":
            v.approve_verification(u, self.admin)
        elif outcome == "rejected":
            v.reject_verification(u, self.admin, "no")
        return u

    def _admin_client(self):
        c = self.app.test_client()
        c.post("/login", data={"email": "admin@c.edu", "password": "Passw0rd!"})
        return c

    def _url(self, name):
        return "/admin/verifications/university/" + name

    # --- service: statistics ---------------------------------------------------
    def test_university_statistics(self):
        self._mk("p@c.edu", "Delhi University", "pending")
        self._mk("v1@c.edu", "Delhi University", "verified")
        self._mk("v2@c.edu", "Delhi University", "verified")
        self._mk("r@c.edu", "Delhi University", "rejected")
        s = v.get_university_verification_statistics("Delhi University")
        self.assertEqual((s["pending"], s["verified"], s["rejected"]), (1, 2, 1))
        self.assertEqual(s["total_students"], 4)
        self.assertEqual(s["verification_rate"], round(2 / 4 * 100, 1))   # 50.0
        self.assertEqual(s["total_requests"], 4)                          # 4 submissions

    def test_total_requests_counts_updates(self):
        u = self._mk("v@c.edu", "Delhi University", "verified")
        v.submit_verification(u, "9876543210", "Delhi University", "NEW")   # UPDATED
        s = v.get_university_verification_statistics("Delhi University")
        self.assertEqual(s["total_requests"], 2)                           # SUBMITTED + UPDATED

    # --- service: timeline + pagination ---------------------------------------
    def test_timeline_ordering(self):
        self._mk("a@c.edu", "Delhi University", "verified", name="Alice")
        acts = v.get_university_recent_activity("Delhi University")
        self.assertEqual(acts[0]["action"], "approved")     # newest first
        self.assertEqual(acts[1]["action"], "submitted")
        self.assertEqual(acts[1]["name"], "Alice")

    def test_students_pagination(self):
        for i in range(25):
            self._mk(f"u{i}@c.edu", "Delhi University", "verified")
        p1 = v.get_university_students("Delhi University", page=1, per_page=20)
        self.assertEqual(len(p1.items), 20)
        self.assertEqual(p1.total, 25)
        self.assertEqual(len(v.get_university_students("Delhi University", page=2, per_page=20).items), 5)

    def test_students_only_verified(self):
        self._mk("v@c.edu", "Delhi University", "verified")
        self._mk("p@c.edu", "Delhi University", "pending")
        page = v.get_university_students("Delhi University")
        self.assertEqual(page.total, 1)

    def test_university_exists(self):
        self._mk("v@c.edu", "Delhi University", "verified")
        self.assertTrue(v.university_exists("Delhi University"))
        self.assertFalse(v.university_exists("Nowhere University"))

    # --- route -----------------------------------------------------------------
    def test_route_renders_all_sections(self):
        u = self._mk("v@c.edu", "Sharda University", "verified", name="Alice Johnson")
        pub = u.public_id
        html = self._admin_client().get(self._url("Sharda University")).get_data(as_text=True)
        self.assertIn("Campus Overview", html)
        self.assertIn("Sharda University", html)
        self.assertIn("Verified Students", html)                    # KPI
        self.assertIn("Verification Rate", html)
        self.assertIn("Total Requests", html)
        self.assertIn("Verification Timeline", html)                # timeline
        self.assertIn("Verified Student Directory", html)           # directory
        self.assertIn("Alice Johnson", html)
        self.assertIn(f"/admin/verifications/{pub}", html)          # student → detail
        self.assertIn("View Pending Verification Requests", html)   # pending shortcut
        self.assertIn("university=Sharda", html.replace("&amp;", "&"))
        self.assertIn("Back to University Analytics", html)         # back nav
        self.assertIn("Marketplace Snapshot", html)
        self.assertIn("No marketplace activity yet", html)          # no listings → empty state

    def test_unknown_university_returns_404(self):
        resp = self._admin_client().get(self._url("Ghost University"))
        self.assertEqual(resp.status_code, 404)

    def test_empty_directory_state(self):
        self._mk("p@c.edu", "Sharda University", "pending")         # exists, none verified
        html = self._admin_client().get(self._url("Sharda University")).get_data(as_text=True)
        self.assertIn("No verification data is available for this university", html)

    def test_non_admin_cannot_view(self):
        self._mk("v@c.edu", "Sharda University", "verified")
        student = self._user("s@c.edu")
        c = self.app.test_client()
        c.post("/login", data={"email": "s@c.edu", "password": "Passw0rd!"})
        self.assertEqual(c.get(self._url("Sharda University")).status_code, 403)


if __name__ == "__main__":
    unittest.main()
