"""
E2E tests for review submission and moderation flows.

These tests verify the complete user journey for submitting,
editing, and moderating reviews using Playwright for browser automation.
"""

import pytest
from playwright.sync_api import Page, expect


@pytest.mark.e2e
class TestReviewSubmission:
    """E2E tests for review submission flow."""

    def test__review_form__displays_fields(self, auth_page: Page, live_server, parks_data):
        """Test review form displays all required fields."""
        park = parks_data[0]
        auth_page.goto(f"{live_server.url}/parks/{park.slug}/")

        # Find and click reviews tab or section
        reviews_tab = auth_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        # Click write review button
        write_review = auth_page.locator("button:has-text('Write Review'), a:has-text('Write Review')")

        if write_review.count() > 0:
            write_review.first.click()

            # Verify form fields
            expect(auth_page.locator("select[name='rating'], input[name='rating']").first).to_be_visible()
            expect(auth_page.locator("input[name='title'], textarea[name='title']").first).to_be_visible()
            expect(auth_page.locator("textarea[name='content'], textarea[name='review']").first).to_be_visible()

    def test__review_submission__valid_data__creates_review(self, auth_page: Page, live_server, parks_data):
        """Test submitting a valid review creates it."""
        park = parks_data[0]
        auth_page.goto(f"{live_server.url}/parks/{park.slug}/")

        # Navigate to reviews
        reviews_tab = auth_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        write_review = auth_page.locator("button:has-text('Write Review'), a:has-text('Write Review')")

        if write_review.count() > 0:
            write_review.first.click()

            # Fill the form
            rating_select = auth_page.locator("select[name='rating']")
            if rating_select.count() > 0:
                rating_select.select_option("5")
            else:
                # May be radio buttons or stars
                auth_page.locator("input[name='rating'][value='5']").click()

            auth_page.locator("input[name='title'], textarea[name='title']").first.fill("E2E Test Review Title")
            auth_page.locator("textarea[name='content'], textarea[name='review']").first.fill(
                "This is an E2E test review content."
            )

            auth_page.get_by_role("button", name="Submit").click()

            # Should show success or redirect
            auth_page.wait_for_timeout(500)

    def test__review_submission__missing_rating__shows_error(self, auth_page: Page, live_server, parks_data):
        """Test submitting review without rating shows error."""
        park = parks_data[0]
        auth_page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = auth_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        write_review = auth_page.locator("button:has-text('Write Review'), a:has-text('Write Review')")

        if write_review.count() > 0:
            write_review.first.click()

            # Fill only title and content, skip rating
            auth_page.locator("input[name='title'], textarea[name='title']").first.fill("Missing Rating Review")
            auth_page.locator("textarea[name='content'], textarea[name='review']").first.fill("Review without rating")

            auth_page.get_by_role("button", name="Submit").click()

            # Should show validation error
            error = auth_page.locator(".error, .errorlist, [role='alert']")
            expect(error.first).to_be_visible()


@pytest.mark.e2e
class TestReviewDisplay:
    """E2E tests for review display."""

    def test__reviews_list__displays_reviews(self, page: Page, live_server, parks_data):
        """Test reviews list displays existing reviews."""
        park = parks_data[0]
        page.goto(f"{live_server.url}/parks/{park.slug}/")

        # Navigate to reviews section
        reviews_tab = page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        # Reviews should be displayed
        reviews_section = page.locator("[data-testid='reviews-list'], .reviews-list, .review-item")

        if reviews_section.count() > 0:
            expect(reviews_section.first).to_be_visible()

    def test__review__shows_rating(self, page: Page, live_server, test_review):
        """Test review displays rating."""
        # test_review fixture creates a review
        page.goto(f"{page.url}")  # Stay on current page after fixture

        # Rating should be visible (stars, number, etc.)
        rating = page.locator(".rating, .stars, [data-testid='rating']")

        if rating.count() > 0:
            expect(rating.first).to_be_visible()

    def test__review__shows_author(self, page: Page, live_server, parks_data):
        """Test review displays author name."""
        park = parks_data[0]
        page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        # Author name should be visible in review
        author = page.locator(".review-author, .author, [data-testid='author']")

        if author.count() > 0:
            expect(author.first).to_be_visible()


@pytest.mark.e2e
class TestReviewEditing:
    """E2E tests for review editing."""

    def test__own_review__shows_edit_button(self, auth_page: Page, live_server, test_review):
        """Test user's own review shows edit button."""
        # Navigate to reviews after creating one

        # Look for edit button on own review
        edit_button = auth_page.locator("button:has-text('Edit'), a:has-text('Edit Review')")

        if edit_button.count() > 0:
            expect(edit_button.first).to_be_visible()

    def test__edit_review__updates_content(self, auth_page: Page, live_server, test_review):
        """Test editing review updates the content."""
        # Find and click edit
        edit_button = auth_page.locator("button:has-text('Edit'), a:has-text('Edit Review')")

        if edit_button.count() > 0:
            edit_button.first.click()

            # Update content
            content_field = auth_page.locator("textarea[name='content'], textarea[name='review']")
            content_field.first.fill("Updated review content from E2E test")

            auth_page.get_by_role("button", name="Save").click()

            # Should show updated content
            auth_page.wait_for_timeout(500)
            expect(auth_page.get_by_text("Updated review content")).to_be_visible()


@pytest.mark.e2e
class TestReviewModeration:
    """E2E tests for review moderation."""

    def test__moderator__sees_moderation_actions(self, mod_page: Page, live_server, parks_data):
        """Test moderator sees moderation actions on reviews."""
        park = parks_data[0]
        mod_page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = mod_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        # Moderator should see moderation buttons
        mod_actions = mod_page.locator("button:has-text('Remove'), button:has-text('Flag'), [data-testid='mod-action']")

        if mod_actions.count() > 0:
            expect(mod_actions.first).to_be_visible()

    def test__moderator__can_remove_review(self, mod_page: Page, live_server, parks_data):
        """Test moderator can remove a review."""
        park = parks_data[0]
        mod_page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = mod_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        remove_button = mod_page.locator("button:has-text('Remove')")

        if remove_button.count() > 0:
            remove_button.first.click()

            # Confirm if dialog appears
            confirm = mod_page.locator("button:has-text('Confirm')")
            if confirm.count() > 0:
                confirm.click()

            mod_page.wait_for_timeout(500)


@pytest.mark.e2e
class TestReviewVoting:
    """E2E tests for review voting (helpful/not helpful)."""

    def test__review__shows_vote_buttons(self, page: Page, live_server, parks_data):
        """Test reviews show vote buttons."""
        park = parks_data[0]
        page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        # Look for helpful/upvote buttons
        vote_buttons = page.locator("button:has-text('Helpful'), button[aria-label*='helpful'], .vote-button")

        if vote_buttons.count() > 0:
            expect(vote_buttons.first).to_be_visible()

    def test__vote__authenticated__registers_vote(self, auth_page: Page, live_server, parks_data):
        """Test authenticated user can vote on review."""
        park = parks_data[0]
        auth_page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = auth_page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        helpful_button = auth_page.locator("button:has-text('Helpful'), button[aria-label*='helpful']")

        if helpful_button.count() > 0:
            helpful_button.first.click()

            # Button should show voted state
            auth_page.wait_for_timeout(500)


@pytest.mark.e2e
class TestRideReviews:
    """E2E tests for ride-specific reviews."""

    def test__ride_page__shows_reviews(self, page: Page, live_server, rides_data):
        """Test ride page shows reviews section."""
        ride = rides_data[0]
        page.goto(f"{live_server.url}/rides/{ride.slug}/")

        # Reviews section should be present
        reviews_section = page.locator("[data-testid='reviews'], #reviews, .reviews-section")

        if reviews_section.count() > 0:
            expect(reviews_section.first).to_be_visible()

    def test__ride_review__includes_ride_experience_fields(self, auth_page: Page, live_server, rides_data):
        """Test ride review form includes experience fields."""
        ride = rides_data[0]
        auth_page.goto(f"{live_server.url}/rides/{ride.slug}/")

        write_review = auth_page.locator("button:has-text('Write Review'), a:has-text('Write Review')")

        if write_review.count() > 0:
            write_review.first.click()

            # Ride-specific fields
            intensity_field = auth_page.locator("select[name='intensity'], input[name='intensity']")
            auth_page.locator("input[name='wait_time'], select[name='wait_time']")

            # At least one experience field should be present
            if intensity_field.count() > 0:
                expect(intensity_field.first).to_be_visible()


@pytest.mark.e2e
class TestReviewFiltering:
    """E2E tests for review filtering and sorting."""

    def test__reviews__sort_by_date(self, page: Page, live_server, parks_data):
        """Test reviews can be sorted by date."""
        park = parks_data[0]
        page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        sort_select = page.locator("select[name='sort'], [data-testid='sort-reviews']")

        if sort_select.count() > 0:
            sort_select.first.select_option("date")
            page.wait_for_timeout(500)

    def test__reviews__filter_by_rating(self, page: Page, live_server, parks_data):
        """Test reviews can be filtered by rating."""
        park = parks_data[0]
        page.goto(f"{live_server.url}/parks/{park.slug}/")

        reviews_tab = page.get_by_role("tab", name="Reviews")
        if reviews_tab.count() > 0:
            reviews_tab.click()

        rating_filter = page.locator("select[name='rating'], [data-testid='rating-filter']")

        if rating_filter.count() > 0:
            rating_filter.first.select_option("5")
            page.wait_for_timeout(500)
