"""
Tests for admin email routes
"""

import pytest
from flask import url_for
from unittest.mock import patch, MagicMock


class TestAdminEmailRoutes:
    """Tests for admin email support routes"""

    def test_email_support_page_requires_login(self, client):
        """Test that email support page requires login"""
        response = client.get("/admin/email")
        assert response.status_code == 302  # Redirect to login

    def test_email_support_page_requires_admin(self, client, regular_user):
        """Test that email support page requires admin permissions"""
        # Login as regular user
        with client:
            client.post(
                "/auth/login", data={"username": regular_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.get("/admin/email")
            # Should redirect or show error (depends on permission system)
            assert response.status_code in [302, 403]

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    def test_email_support_page_admin_access(self, client, admin_user):
        """Test that admin can access email support page"""
        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.get("/admin/email")
            assert response.status_code == 200
            assert b"Email Configuration" in response.data or b"email" in response.data.lower()

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    @patch("app.utils.email.check_email_configuration")
    def test_email_support_shows_configuration_status(self, mock_test_config, client, admin_user):
        """Test that email support page shows configuration status"""
        # Mock configuration status
        mock_test_config.return_value = {
            "configured": True,
            "settings": {
                "server": "smtp.gmail.com",
                "port": 587,
                "username": "test@example.com",
                "password_set": True,
                "use_tls": True,
                "use_ssl": False,
                "default_sender": "noreply@example.com",
            },
            "errors": [],
            "warnings": [],
        }

        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.get("/admin/email")
            assert response.status_code == 200
            # Check that configuration details are displayed
            assert b"smtp.gmail.com" in response.data or mock_test_config.called

    def test_test_email_endpoint_requires_login(self, client):
        """Test that test email endpoint requires login"""
        response = client.post("/admin/email/test", json={"recipient": "test@example.com"})
        assert response.status_code == 302  # Redirect to login

    def test_send_email_template_test_requires_login(self, client):
        """Test that invoice email template test endpoint requires login"""
        response = client.post("/admin/email-templates/1/send-test", json={"recipient": "test@example.com"})
        assert response.status_code == 302  # Redirect to login

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    @patch("app.utils.email.send_test_email")
    def test_send_test_email_success(self, mock_send, client, admin_user):
        """Test sending test email successfully"""
        mock_send.return_value = (True, "Test email sent successfully")

        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.post(
                "/admin/email/test", json={"recipient": "test@example.com"}, content_type="application/json"
            )

            assert response.status_code == 200
            data = response.get_json()
            assert data["success"] is True
            assert "successfully" in data["message"].lower()

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    @patch("app.utils.email.send_test_email")
    def test_send_test_email_failure(self, mock_send, client, admin_user):
        """Test sending test email with failure"""
        mock_send.return_value = (False, "Failed to send email: SMTP error")

        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.post(
                "/admin/email/test", json={"recipient": "test@example.com"}, content_type="application/json"
            )

            assert response.status_code == 500
            data = response.get_json()
            assert data["success"] is False
            assert "Failed" in data["message"]

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    def test_send_test_email_no_recipient(self, client, admin_user):
        """Test sending test email without recipient"""
        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.post("/admin/email/test", json={}, content_type="application/json")

            assert response.status_code == 400
            data = response.get_json()
            assert data["success"] is False
            assert "required" in data["message"].lower()

    @pytest.mark.skip(reason="Authentication/session issues in test - needs investigation")
    def test_email_config_status_endpoint(self, client, admin_user):
        """Test email configuration status endpoint"""
        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            response = client.get("/admin/email/config-status")

            assert response.status_code == 200
            data = response.get_json()
            assert "configured" in data
            assert "settings" in data
            assert "errors" in data
            assert "warnings" in data

    def test_rate_limiting_on_test_email(self, client, admin_user):
        """Test that test email endpoint has rate limiting"""
        # Login as admin
        with client:
            client.post(
                "/auth/login", data={"username": admin_user.username, "password": "password"}, follow_redirects=True
            )

            # Send multiple requests rapidly
            for i in range(6):  # Limit is 5 per minute
                response = client.post(
                    "/admin/email/test", json={"recipient": "test@example.com"}, content_type="application/json"
                )

                # After 5 requests, should get rate limited
                if i >= 5:
                    assert response.status_code == 429  # Too Many Requests


# Fixtures
@pytest.fixture
def regular_user(app):
    """Create a regular user"""
    from app.models import User
    from app import db

    with app.app_context():
        user = User(username="regular_user", role="user")
        user.set_password("password")
        user.is_active = True
        db.session.add(user)
        db.session.commit()
        db.session.refresh(user)
        return user


@pytest.fixture
def admin_user(app):
    """Create an admin user"""
    from app.models import User
    from app import db

    with app.app_context():
        user = User(username="admin", role="admin")
        user.set_password("password")
        user.is_active = True
        db.session.add(user)
        db.session.commit()
        db.session.refresh(user)
        return user
