"""
Vite integration helper for Flask
Handles development and production asset loading
"""

import json
from pathlib import Path
from markupsafe import Markup


class ViteHelper:
    """Helper class for Vite integration with Flask"""

    def __init__(self, app=None):
        self.app = app
        self.manifest = None
        self.is_dev = False

        if app:
            self.init_app(app)

    def init_app(self, app):
        """Initialize the helper with Flask app"""
        self.app = app
        self.is_dev = app.debug or app.config.get("VITE_DEV_MODE", False)

        if not self.is_dev:
            # Load manifest in production
            self._load_manifest()

        # Register template functions
        app.jinja_env.globals["vite_asset"] = self.vite_asset
        app.jinja_env.globals["vite_hmr"] = self.vite_hmr

    def _load_manifest(self):
        """Load Vite manifest file"""
        static_dir = self.app.config.get("STATIC_DIR", "static")
        manifest_path = Path(static_dir) / "dist" / ".vite" / "manifest.json"

        if manifest_path.exists():
            with open(manifest_path, "r", encoding="utf-8-sig") as f:
                self.manifest = json.load(f)
        else:
            # Fallback if manifest doesn't exist yet
            self.manifest = {}

    def vite_hmr(self):
        """Return HMR client script for development"""
        if self.is_dev:
            return Markup(
                '<script type="module" src="http://localhost:5173/@vite/client"></script>'
            )
        return ""

    def vite_asset(self, entry_point="js/app.js"):
        """
        Return appropriate script tags for the entry point

        In development: Points to Vite dev server
        In production: Uses manifest to get hashed filenames
        """
        if self.is_dev:
            # Development mode - use Vite dev server
            return Markup(
                f'<script type="module" src="http://localhost:5173/{entry_point}"></script>'
            )

        # Production mode - use manifest
        if not self.manifest:
            # Fallback to CDN references if build hasn't run yet
            return self._fallback_assets()

        # Get the built file from manifest
        if entry_point in self.manifest:
            file_info = self.manifest[entry_point]
            file_path = f"/static/dist/{file_info['file']}"

            # Include CSS if present
            css_tags = ""
            if "css" in file_info:
                for css_file in file_info["css"]:
                    css_tags += f'<link rel="stylesheet" href="/static/dist/{css_file}">\n'

            # Include the main JS file
            js_tag = f'<script type="module" src="{file_path}"></script>'

            return Markup(css_tags + js_tag)

        return self._fallback_assets()

    def _fallback_assets(self):
        """Fallback to existing script tags if build hasn't run"""
        # This will be replaced once npm build is run
        return Markup("""
<!-- Vite build not found - run 'npm run build' to generate production assets -->
<!-- Using existing static files as fallback -->
        """)


# Create global instance
vite = ViteHelper()
