# app/modules/loyalty/tests/integration/test_merchant_pages.py
"""
Integration tests for merchant loyalty page routes (HTML rendering).

Tests the merchant page routes at:
    /merchants/loyalty/program
    /merchants/loyalty/program/edit
    /merchants/loyalty/analytics

Authentication: Uses dependency overrides for cookie-based merchant auth.
"""

import uuid

import pytest

from app.api.deps import (
    get_current_merchant_from_cookie_or_header,
    get_merchant_for_current_user_page,
)
from app.modules.tenancy.models import Merchant, User
from app.modules.tenancy.schemas.auth import UserContext
from main import app

BASE = "/merchants/loyalty"


# ============================================================================
# Fixtures
# ============================================================================


@pytest.fixture
def merchant_page_setup(db):
    """Create a merchant owner for page tests."""
    from middleware.auth import AuthManager

    auth = AuthManager()
    uid = uuid.uuid4().hex[:8]

    owner = User(
        email=f"merchpageowner_{uid}@test.com",
        username=f"merchpageowner_{uid}",
        hashed_password=auth.hash_password("testpass123"),
        role="merchant_owner",
        is_active=True,
        is_email_verified=True,
    )
    db.add(owner)
    db.commit()
    db.refresh(owner)

    merchant = Merchant(
        name=f"Page Test Merchant {uid}",
        owner_user_id=owner.id,
        contact_email=owner.email,
        is_active=True,
        is_verified=True,
    )
    db.add(merchant)
    db.commit()
    db.refresh(merchant)

    return {"owner": owner, "merchant": merchant}


@pytest.fixture
def merchant_page_headers(merchant_page_setup):
    """Override auth dependencies for merchant page routes."""
    owner = merchant_page_setup["owner"]
    merchant = merchant_page_setup["merchant"]

    user_context = UserContext(
        id=owner.id,
        email=owner.email,
        username=owner.username,
        role="merchant_owner",
        is_active=True,
    )

    app.dependency_overrides[get_current_merchant_from_cookie_or_header] = lambda: user_context
    app.dependency_overrides[get_merchant_for_current_user_page] = lambda: merchant
    yield {"Cookie": "merchant_token=fake-token"}
    app.dependency_overrides.pop(get_current_merchant_from_cookie_or_header, None)
    app.dependency_overrides.pop(get_merchant_for_current_user_page, None)


# ============================================================================
# Program View Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantProgramPage:
    """Tests for GET /merchants/loyalty/program."""

    def test_program_page_renders(self, client, merchant_page_headers):
        """Program page returns HTML."""
        response = client.get(
            f"{BASE}/program",
            headers=merchant_page_headers,
        )
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_program_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/program")
        assert response.status_code in [401, 403]


# ============================================================================
# Program Edit Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantProgramEditPage:
    """Tests for GET /merchants/loyalty/program/edit."""

    def test_program_edit_page_renders(self, client, merchant_page_headers):
        """Program edit page returns HTML."""
        response = client.get(
            f"{BASE}/program/edit",
            headers=merchant_page_headers,
        )
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_program_edit_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/program/edit")
        assert response.status_code in [401, 403]


# ============================================================================
# Analytics Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantAnalyticsPage:
    """Tests for GET /merchants/loyalty/analytics."""

    def test_analytics_page_renders(self, client, merchant_page_headers):
        """Analytics page returns HTML."""
        response = client.get(
            f"{BASE}/analytics",
            headers=merchant_page_headers,
        )
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_analytics_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/analytics")
        assert response.status_code in [401, 403]


# ============================================================================
# Cards Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantCardsPage:
    """Tests for GET /merchants/loyalty/cards."""

    def test_cards_page_renders(self, client, merchant_page_headers):
        """Cards page returns HTML."""
        response = client.get(f"{BASE}/cards", headers=merchant_page_headers)
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_cards_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/cards")
        assert response.status_code in [401, 403]


# ============================================================================
# Card Detail Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantCardDetailPage:
    """Tests for GET /merchants/loyalty/cards/{card_id}."""

    def test_card_detail_page_renders(self, client, merchant_page_headers):
        """Card detail page returns HTML (even with non-existent card_id)."""
        response = client.get(f"{BASE}/cards/99999", headers=merchant_page_headers)
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_card_detail_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/cards/1")
        assert response.status_code in [401, 403]


# ============================================================================
# Transactions Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantTransactionsPage:
    """Tests for GET /merchants/loyalty/transactions."""

    def test_transactions_page_renders(self, client, merchant_page_headers):
        """Transactions page returns HTML."""
        response = client.get(f"{BASE}/transactions", headers=merchant_page_headers)
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_transactions_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/transactions")
        assert response.status_code in [401, 403]


# ============================================================================
# Staff PINs Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantPinsPage:
    """Tests for GET /merchants/loyalty/pins."""

    def test_pins_page_renders(self, client, merchant_page_headers):
        """PINs page returns HTML."""
        response = client.get(f"{BASE}/pins", headers=merchant_page_headers)
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_pins_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/pins")
        assert response.status_code in [401, 403]


# ============================================================================
# Settings Page
# ============================================================================


@pytest.mark.integration
@pytest.mark.loyalty
class TestMerchantSettingsPage:
    """Tests for GET /merchants/loyalty/settings."""

    def test_settings_page_renders(self, client, merchant_page_headers):
        """Settings page returns HTML."""
        response = client.get(f"{BASE}/settings", headers=merchant_page_headers)
        assert response.status_code == 200
        assert "text/html" in response.headers["content-type"]

    def test_settings_page_requires_auth(self, client):
        """Unauthenticated request is rejected."""
        response = client.get(f"{BASE}/settings")
        assert response.status_code in [401, 403]
