"""Tests for the frontend analytics generator."""

from __future__ import annotations

import pytest

from prisme.generators.base import GeneratorContext
from prisme.generators.frontend.analytics import FrontendAnalyticsGenerator
from prisme.spec.analytics import AnalyticsConfig, GoogleAnalyticsConfig
from prisme.spec.fields import FieldSpec, FieldType
from prisme.spec.model import ModelSpec
from prisme.spec.project import ProjectSpec
from prisme.spec.stack import FileStrategy, StackSpec


@pytest.fixture
def analytics_stack_spec() -> StackSpec:
    return StackSpec(
        name="test-app",
        models=[
            ModelSpec(
                name="Item",
                fields=[
                    FieldSpec(name="title", type=FieldType.STRING, required=True),
                ],
            ),
        ],
    )


@pytest.fixture
def analytics_enabled_project() -> ProjectSpec:
    return ProjectSpec(
        name="test-app",
        analytics=AnalyticsConfig(enabled=True),
    )


@pytest.fixture
def analytics_disabled_project() -> ProjectSpec:
    return ProjectSpec(
        name="test-app",
        analytics=AnalyticsConfig(enabled=False),
    )


@pytest.fixture
def analytics_with_ga_project() -> ProjectSpec:
    return ProjectSpec(
        name="test-app",
        analytics=AnalyticsConfig(
            enabled=True,
            google_analytics=GoogleAnalyticsConfig(),
        ),
    )


@pytest.fixture
def generator_context(analytics_stack_spec, analytics_enabled_project, tmp_path):
    return GeneratorContext(
        domain_spec=analytics_stack_spec,
        output_dir=tmp_path,
        dry_run=True,
        project_spec=analytics_enabled_project,
    )


@pytest.fixture
def generator_context_disabled(analytics_stack_spec, analytics_disabled_project, tmp_path):
    return GeneratorContext(
        domain_spec=analytics_stack_spec,
        output_dir=tmp_path,
        dry_run=True,
        project_spec=analytics_disabled_project,
    )


@pytest.fixture
def generator_context_ga(analytics_stack_spec, analytics_with_ga_project, tmp_path):
    return GeneratorContext(
        domain_spec=analytics_stack_spec,
        output_dir=tmp_path,
        dry_run=True,
        project_spec=analytics_with_ga_project,
    )


class TestFrontendAnalyticsGenerator:
    """Tests for FrontendAnalyticsGenerator."""

    def test_skips_when_disabled(self, generator_context_disabled):
        """Generator returns empty list when analytics disabled."""
        generator = FrontendAnalyticsGenerator(generator_context_disabled)
        files = generator.generate_files()
        assert files == []

    def test_generates_files_when_enabled(self, generator_context):
        """Generator returns files when analytics enabled."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        assert len(files) > 0

    def test_generates_analytics_api(self, generator_context):
        """Generator produces the analytics API client."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        api_files = [f for f in files if f.path.name == "analyticsApi.ts"]
        assert len(api_files) == 1
        assert "trackEvent" in api_files[0].content

    def test_generates_analytics_provider(self, generator_context):
        """Generator produces the AnalyticsProvider."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        provider_files = [f for f in files if f.path.name == "AnalyticsProvider.tsx"]
        assert len(provider_files) == 1
        assert "AnalyticsContext" in provider_files[0].content

    def test_generates_use_analytics_hook(self, generator_context):
        """Generator produces useAnalytics hook."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        hook_files = [f for f in files if f.path.name == "useAnalytics.ts"]
        assert len(hook_files) == 1
        assert "useAnalytics" in hook_files[0].content

    def test_generates_track_view_macro(self, generator_context):
        """Generator produces the TrackView macro component."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        track_files = [f for f in files if f.path.name == "TrackView.tsx"]
        assert len(track_files) == 1
        assert "TrackView" in track_files[0].content

    def test_generates_dashboard_page(self, generator_context):
        """Generator produces dashboard page when enabled."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        dashboard_files = [f for f in files if f.path.name == "AnalyticsDashboard.tsx"]
        assert len(dashboard_files) == 1
        assert dashboard_files[0].strategy == FileStrategy.GENERATE_ONCE

    def test_no_ga_component_without_config(self, generator_context):
        """No GoogleAnalytics component when GA not configured."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        ga_files = [f for f in files if f.path.name == "GoogleAnalytics.tsx"]
        assert len(ga_files) == 0

    def test_generates_ga_component_with_config(self, generator_context_ga):
        """GoogleAnalytics component generated when GA configured."""
        generator = FrontendAnalyticsGenerator(generator_context_ga)
        files = generator.generate_files()
        ga_files = [f for f in files if f.path.name == "GoogleAnalytics.tsx"]
        assert len(ga_files) == 1
        assert "GA_MEASUREMENT_ID" in ga_files[0].content

    def test_generates_index(self, generator_context):
        """Generator produces index.ts barrel export."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        index_files = [f for f in files if f.path.name == "index.ts"]
        assert len(index_files) == 1
        assert "TrackView" in index_files[0].content

    def test_most_files_always_overwrite(self, generator_context):
        """Most files use ALWAYS_OVERWRITE, except dashboard."""
        generator = FrontendAnalyticsGenerator(generator_context)
        files = generator.generate_files()
        for f in files:
            if f.path.name == "AnalyticsDashboard.tsx":
                assert f.strategy == FileStrategy.GENERATE_ONCE
            else:
                assert f.strategy == FileStrategy.ALWAYS_OVERWRITE
