"""
Style Dictionary wrapper for design token transformation
Converts DSS tokens to various output formats (CSS, SCSS, JSON)
"""

import json
import subprocess
import tempfile
from pathlib import Path
from typing import Dict, List, Optional, Any

from dss.models.theme import Theme, DesignToken, TokenCategory


class StyleDictionaryWrapper:
    """
    Wrapper for Amazon Style Dictionary CLI
    Transforms design tokens into platform-specific outputs
    """

    def __init__(self, sd_path: str = "npx style-dictionary"):
        """
        Initialize Style Dictionary wrapper

        Args:
            sd_path: Path to style-dictionary executable (default: npx style-dictionary)
        """
        self.sd_path = sd_path

    def transform_theme(
        self,
        theme: Theme,
        output_format: str = "css",
        output_path: Optional[Path] = None
    ) -> Dict[str, Any]:
        """
        Transform a DSS theme using style-dictionary

        Args:
            theme: DSS Theme to transform
            output_format: Output format (css, scss, json, js)
            output_path: Optional output directory

        Returns:
            Dict with transformation result
        """
        # Create temporary directory for style-dictionary config
        with tempfile.TemporaryDirectory() as tmpdir:
            tmppath = Path(tmpdir)

            # Convert DSS theme to style-dictionary format
            sd_tokens = self._convert_theme_to_sd_format(theme)

            # Write tokens to JSON file
            tokens_file = tmppath / "tokens.json"
            with open(tokens_file, "w") as f:
                json.dump(sd_tokens, f, indent=2)

            # Create style-dictionary config
            config = self._create_sd_config(output_format, tmppath)
            config_file = tmppath / "config.json"
            with open(config_file, "w") as f:
                json.dump(config, f, indent=2)

            # Run style-dictionary build
            result = self._run_sd_build(config_file, tmppath)

            # Read output files
            output_files = self._read_output_files(tmppath, output_format)

            return {
                "success": result.returncode == 0,
                "output_format": output_format,
                "files": output_files,
                "errors": result.stderr if result.returncode != 0 else None
            }

    def _convert_theme_to_sd_format(self, theme: Theme) -> Dict[str, Any]:
        """
        Convert DSS theme to style-dictionary token format

        Style Dictionary format:
        {
          "color": {
            "primary": { "value": "#0066cc" }
          }
        }
        """
        sd_tokens = {}

        for token_name, token in theme.tokens.items():
            # Group tokens by category
            category = token.category.value if token.category else "other"

            if category not in sd_tokens:
                sd_tokens[category] = {}

            # Convert token to SD format
            sd_tokens[category][token_name] = {
                "value": token.value,
                "type": token.type,
            }

            if token.description:
                sd_tokens[category][token_name]["comment"] = token.description

        return sd_tokens

    def _create_sd_config(self, output_format: str, build_path: Path) -> Dict[str, Any]:
        """
        Create style-dictionary configuration

        Args:
            output_format: Desired output format
            build_path: Build directory path

        Returns:
            Style Dictionary config dict
        """
        config = {
            "source": ["tokens.json"],
            "platforms": {}
        }

        if output_format == "css":
            config["platforms"]["css"] = {
                "transformGroup": "css",
                "buildPath": str(build_path) + "/",
                "files": [{
                    "destination": "theme.css",
                    "format": "css/variables"
                }]
            }
        elif output_format == "scss":
            config["platforms"]["scss"] = {
                "transformGroup": "scss",
                "buildPath": str(build_path) + "/",
                "files": [{
                    "destination": "theme.scss",
                    "format": "scss/variables"
                }]
            }
        elif output_format == "json":
            config["platforms"]["json"] = {
                "transformGroup": "js",
                "buildPath": str(build_path) + "/",
                "files": [{
                    "destination": "theme.json",
                    "format": "json/nested"
                }]
            }
        elif output_format == "js":
            config["platforms"]["js"] = {
                "transformGroup": "js",
                "buildPath": str(build_path) + "/",
                "files": [{
                    "destination": "theme.js",
                    "format": "javascript/module"
                }]
            }

        return config

    def _run_sd_build(self, config_file: Path, cwd: Path) -> subprocess.CompletedProcess:
        """
        Run style-dictionary build command

        Args:
            config_file: Path to config.json
            cwd: Working directory

        Returns:
            Subprocess result
        """
        cmd = [
            "npx", "style-dictionary", "build",
            "--config", str(config_file)
        ]

        result = subprocess.run(
            cmd,
            cwd=cwd,
            capture_output=True,
            text=True
        )

        return result

    def _read_output_files(self, build_path: Path, output_format: str) -> Dict[str, str]:
        """
        Read generated output files

        Args:
            build_path: Directory containing built files
            output_format: Output format used

        Returns:
            Dict of filename -> content
        """
        files = {}

        # Map format to expected file
        format_files = {
            "css": "theme.css",
            "scss": "theme.scss",
            "json": "theme.json",
            "js": "theme.js"
        }

        filename = format_files.get(output_format)
        if filename:
            filepath = build_path / filename
            if filepath.exists():
                with open(filepath, "r") as f:
                    files[filename] = f.read()

        return files

    def convert_tokens_to_css_vars(self, theme: Theme) -> str:
        """
        Convert DSS theme tokens to CSS custom properties

        Args:
            theme: DSS Theme

        Returns:
            CSS string with :root variables
        """
        css_lines = [":root {"]

        for token_name, token in theme.tokens.items():
            # Convert token name to CSS variable format
            css_var_name = f"--{token_name}"

            # Add comment if description exists
            if token.description:
                css_lines.append(f"  /* {token.description} */")

            css_lines.append(f"  {css_var_name}: {token.value};")

        css_lines.append("}")

        return "\n".join(css_lines)


# Alias for backward compatibility
StyleDictionaryTool = StyleDictionaryWrapper
