"""Frontend analytics generator for Prism.

Generates React analytics components using a macro/hook pattern:
- useAnalytics() hook for event tracking
- <TrackView> macro component for declarative page view tracking
- AnalyticsProvider context for app-wide configuration
- Google Analytics integration script
- Analytics admin dashboard page
"""

from __future__ import annotations

from pathlib import Path

from prisme.generators.base import GeneratedFile, GeneratorBase
from prisme.spec.stack import FileStrategy
from prisme.utils.template_engine import TemplateRenderer


class FrontendAnalyticsGenerator(GeneratorBase):
    """Generates React analytics components with macro-based tracking."""

    REQUIRED_TEMPLATES = [
        "frontend/analytics/AnalyticsProvider.tsx.jinja2",
        "frontend/analytics/useAnalytics.ts.jinja2",
        "frontend/analytics/TrackView.tsx.jinja2",
        "frontend/analytics/analyticsApi.ts.jinja2",
        "frontend/analytics/index.ts.jinja2",
    ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if not self.analytics_config.enabled:
            self.skip_generation = True
            return

        self.renderer = TemplateRenderer()
        self.renderer.validate_templates_exist(self.REQUIRED_TEMPLATES)

        frontend_base = Path(self.generator_config.frontend_output)
        self.contexts_path = frontend_base / "contexts"
        self.hooks_path = frontend_base / "hooks"
        self.components_path = frontend_base / "components" / "analytics"
        self.lib_path = frontend_base / "lib"
        self.pages_path = frontend_base / "pages"

    def _get_common_context(self) -> dict:
        """Build template context from analytics config."""
        config = self.analytics_config

        return {
            # Tracking features
            "track_page_views": config.track_page_views,
            "track_user_sessions": config.track_user_sessions,
            "track_crud_events": config.track_crud_events,
            # Google Analytics
            "has_google_analytics": config.has_google_analytics,
            "google_analytics": (
                config.google_analytics.model_dump() if config.google_analytics else None
            ),
            # Custom events
            "custom_events": [e.model_dump() for e in config.custom_events],
            "has_custom_events": config.has_custom_events,
            # Dashboard
            "dashboard_enabled": config.dashboard.enabled,
            "dashboard_path": config.dashboard.path,
            # Privacy
            "anonymize_users": config.anonymize_users,
            "cookie_consent_required": (
                config.google_analytics.cookie_consent_required
                if config.google_analytics
                else False
            ),
            # Auth integration
            "auth_enabled": self._has_auth(),
        }

    def generate_files(self) -> list[GeneratedFile]:
        """Generate all frontend analytics files."""
        if getattr(self, "skip_generation", False):
            return []

        files = []

        # Analytics API client
        files.append(self._generate_analytics_api())

        # Analytics provider (context)
        files.append(self._generate_analytics_provider())

        # useAnalytics hook
        files.append(self._generate_use_analytics_hook())

        # TrackView macro component
        files.append(self._generate_track_view())

        # Index file
        files.append(self._generate_index())

        # Conditional: Google Analytics script component
        if self.analytics_config.has_google_analytics:
            files.append(self._generate_google_analytics())

        # Conditional: Analytics dashboard page
        if self.analytics_config.dashboard.enabled:
            files.append(self._generate_dashboard_page())

        return files

    def _generate_analytics_api(self) -> GeneratedFile:
        """Generate analytics API client."""
        content = self.renderer.render_file(
            "frontend/analytics/analyticsApi.ts.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.lib_path / "analyticsApi.ts",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Analytics API client",
        )

    def _generate_analytics_provider(self) -> GeneratedFile:
        """Generate AnalyticsProvider context component."""
        content = self.renderer.render_file(
            "frontend/analytics/AnalyticsProvider.tsx.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.contexts_path / "AnalyticsProvider.tsx",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Analytics provider context",
        )

    def _generate_use_analytics_hook(self) -> GeneratedFile:
        """Generate useAnalytics() hook."""
        content = self.renderer.render_file(
            "frontend/analytics/useAnalytics.ts.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.hooks_path / "useAnalytics.ts",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="useAnalytics hook",
        )

    def _generate_track_view(self) -> GeneratedFile:
        """Generate <TrackView> macro component."""
        content = self.renderer.render_file(
            "frontend/analytics/TrackView.tsx.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.components_path / "TrackView.tsx",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="TrackView macro component",
        )

    def _generate_google_analytics(self) -> GeneratedFile:
        """Generate Google Analytics script component."""
        content = self.renderer.render_file(
            "frontend/analytics/GoogleAnalytics.tsx.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.components_path / "GoogleAnalytics.tsx",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Google Analytics component",
        )

    def _generate_dashboard_page(self) -> GeneratedFile:
        """Generate analytics admin dashboard page."""
        content = self.renderer.render_file(
            "frontend/analytics/AnalyticsDashboard.tsx.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.pages_path / "AnalyticsDashboard.tsx",
            content=content,
            strategy=FileStrategy.GENERATE_ONCE,
            description="Analytics dashboard page",
        )

    def _generate_index(self) -> GeneratedFile:
        """Generate index file for analytics components."""
        content = self.renderer.render_file(
            "frontend/analytics/index.ts.jinja2",
            context=self._get_common_context(),
        )
        return GeneratedFile(
            path=self.components_path / "index.ts",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Analytics components index",
        )

    def _has_auth(self) -> bool:
        """Check if authentication is enabled."""
        try:
            return self.auth_config.enabled
        except (ValueError, AttributeError):
            return False
