"""
Token Format Exporters

Export design tokens extracted from Figma in multiple formats:
- CSS Variables
- JSON
- TypeScript
- SCSS
- JavaScript
"""

import json
from typing import Dict, Any, List
from pathlib import Path


class TokenExporter:
    """Base class for token exporters"""

    def __init__(self, tokens: Dict[str, Any]):
        """Initialize exporter with tokens"""
        self.tokens = tokens
        self.output = ""

    def export(self) -> str:
        """Export tokens in format-specific way"""
        raise NotImplementedError


class CSSVariableExporter(TokenExporter):
    """Export tokens as CSS custom properties"""

    def export(self) -> str:
        """Export as CSS variables"""
        lines = [":root {"]

        if "colors" in self.tokens:
            for name, value in self.tokens["colors"].items():
                lines.append(f"  --color-{name}: {value};")

        if "spacing" in self.tokens:
            for name, value in self.tokens["spacing"].items():
                lines.append(f"  --spacing-{name}: {value}px;")

        if "typography" in self.tokens:
            for name, props in self.tokens["typography"].items():
                if isinstance(props, dict):
                    for prop, val in props.items():
                        lines.append(f"  --typography-{name}-{prop}: {val};")
                else:
                    lines.append(f"  --typography-{name}: {props};")

        lines.append("}")

        return "\n".join(lines)


class JSONExporter(TokenExporter):
    """Export tokens as JSON"""

    def export(self) -> str:
        """Export as JSON"""
        return json.dumps(self.tokens, indent=2)


class TypeScriptExporter(TokenExporter):
    """Export tokens as TypeScript constants"""

    def export(self) -> str:
        """Export as TypeScript"""
        lines = [
            "/**",
            " * Design System Tokens",
            " * Auto-generated from Figma",
            " */",
            "",
            "export const DSSTokens = {"
        ]

        # Colors
        if "colors" in self.tokens:
            lines.append("  colors: {")
            for name, value in self.tokens["colors"].items():
                lines.append(f"    {name}: '{value}',")
            lines.append("  },")

        # Spacing
        if "spacing" in self.tokens:
            lines.append("  spacing: {")
            for name, value in self.tokens["spacing"].items():
                lines.append(f"    {name}: {value},")
            lines.append("  },")

        # Typography
        if "typography" in self.tokens:
            lines.append("  typography: {")
            for name, props in self.tokens["typography"].items():
                if isinstance(props, dict):
                    lines.append(f"    {name}: {{")
                    for prop, val in props.items():
                        if isinstance(val, str):
                            lines.append(f"      {prop}: '{val}',")
                        else:
                            lines.append(f"      {prop}: {val},")
                    lines.append("    },")
                else:
                    lines.append(f"    {name}: '{props}',")
            lines.append("  },")

        lines.append("};")
        lines.append("")
        lines.append("export type TokenKey = keyof typeof DSSTokens;")

        return "\n".join(lines)


class SCSSExporter(TokenExporter):
    """Export tokens as SCSS variables"""

    def export(self) -> str:
        """Export as SCSS"""
        lines = ["// Design System Tokens - SCSS Variables", ""]

        # Colors
        if "colors" in self.tokens:
            lines.append("// Colors")
            for name, value in self.tokens["colors"].items():
                lines.append(f"$color-{name}: {value};")
            lines.append("")

        # Spacing
        if "spacing" in self.tokens:
            lines.append("// Spacing")
            for name, value in self.tokens["spacing"].items():
                lines.append(f"$spacing-{name}: {value}px;")
            lines.append("")

        # Typography
        if "typography" in self.tokens:
            lines.append("// Typography")
            for name, props in self.tokens["typography"].items():
                if isinstance(props, dict):
                    for prop, val in props.items():
                        lines.append(f"$typography-{name}-{prop}: {val};")
                else:
                    lines.append(f"$typography-{name}: {props};")
            lines.append("")

        return "\n".join(lines)


class JavaScriptExporter(TokenExporter):
    """Export tokens as JavaScript object"""

    def export(self) -> str:
        """Export as JavaScript"""
        lines = [
            "/**",
            " * Design System Tokens",
            " * Auto-generated from Figma",
            " */",
            "",
            "const DSSTokens = {"
        ]

        # Colors
        if "colors" in self.tokens:
            lines.append("  colors: {")
            for name, value in self.tokens["colors"].items():
                lines.append(f"    {name}: '{value}',")
            lines.append("  },")

        # Spacing
        if "spacing" in self.tokens:
            lines.append("  spacing: {")
            for name, value in self.tokens["spacing"].items():
                lines.append(f"    {name}: {value},")
            lines.append("  },")

        # Typography
        if "typography" in self.tokens:
            lines.append("  typography: {")
            for name, props in self.tokens["typography"].items():
                if isinstance(props, dict):
                    lines.append(f"    {name}: {{")
                    for prop, val in props.items():
                        if isinstance(val, str):
                            lines.append(f"      {prop}: '{val}',")
                        else:
                            lines.append(f"      {prop}: {val},")
                    lines.append("    },")
                else:
                    lines.append(f"    {name}: '{props}',")
            lines.append("  },")

        lines.append("};")
        lines.append("")
        lines.append("module.exports = DSSTokens;")

        return "\n".join(lines)


class FigmaExporter(TokenExporter):
    """Export tokens in Figma sync format"""

    def export(self) -> str:
        """Export in Figma-compatible format"""
        figma_tokens = {
            "colors": [],
            "typography": [],
            "sizing": []
        }

        if "colors" in self.tokens:
            for name, value in self.tokens["colors"].items():
                figma_tokens["colors"].append({
                    "name": name,
                    "value": value,
                    "type": "color"
                })

        if "spacing" in self.tokens:
            for name, value in self.tokens["spacing"].items():
                figma_tokens["sizing"].append({
                    "name": name,
                    "value": f"{value}px",
                    "type": "size"
                })

        if "typography" in self.tokens:
            for name, props in self.tokens["typography"].items():
                figma_tokens["typography"].append({
                    "name": name,
                    "value": props,
                    "type": "typography"
                })

        return json.dumps(figma_tokens, indent=2)


class TailwindExporter(TokenExporter):
    """Export tokens as Tailwind configuration"""

    def export(self) -> str:
        """Export as Tailwind config"""
        lines = [
            "/**",
            " * Tailwind Configuration",
            " * Auto-generated from Design System tokens",
            " */",
            "",
            "module.exports = {",
            "  theme: {",
            "    extend: {"
        ]

        # Colors
        if "colors" in self.tokens:
            lines.append("      colors: {")
            for name, value in self.tokens["colors"].items():
                lines.append(f"        '{name}': '{value}',")
            lines.append("      },")

        # Spacing
        if "spacing" in self.tokens:
            lines.append("      spacing: {")
            for name, value in self.tokens["spacing"].items():
                lines.append(f"        '{name}': '{value}px',")
            lines.append("      },")

        lines.append("    },")
        lines.append("  },")
        lines.append("};")

        return "\n".join(lines)


class TokenExporterFactory:
    """Factory for creating exporters"""

    exporters = {
        "css": CSSVariableExporter,
        "json": JSONExporter,
        "typescript": TypeScriptExporter,
        "ts": TypeScriptExporter,
        "scss": SCSSExporter,
        "javascript": JavaScriptExporter,
        "js": JavaScriptExporter,
        "figma": FigmaExporter,
        "tailwind": TailwindExporter,
    }

    @classmethod
    def create(cls, format: str, tokens: Dict[str, Any]) -> TokenExporter:
        """Create exporter for specified format"""
        exporter_class = cls.exporters.get(format.lower())

        if not exporter_class:
            raise ValueError(f"Unknown export format: {format}")

        return exporter_class(tokens)

    @classmethod
    def export(cls, format: str, tokens: Dict[str, Any]) -> str:
        """Export tokens directly"""
        exporter = cls.create(format, tokens)
        return exporter.export()

    @classmethod
    def export_all(cls, tokens: Dict[str, Any], output_dir: Path) -> Dict[str, Path]:
        """Export tokens in all formats to directory"""
        output_dir.mkdir(parents=True, exist_ok=True)
        results = {}

        format_extensions = {
            "css": ".css",
            "json": ".json",
            "typescript": ".ts",
            "scss": ".scss",
            "javascript": ".js",
            "figma": ".figma.json",
            "tailwind": ".config.js",
        }

        for format, ext in format_extensions.items():
            try:
                exported = cls.export(format, tokens)
                filename = f"tokens{ext}"
                filepath = output_dir / filename

                with open(filepath, "w") as f:
                    f.write(exported)

                results[format] = filepath
            except Exception as e:
                print(f"Error exporting {format}: {e}")

        return results


# Convenience functions
def export_tokens_css(tokens: Dict[str, Any]) -> str:
    """Export tokens as CSS variables"""
    return TokenExporterFactory.export("css", tokens)


def export_tokens_json(tokens: Dict[str, Any]) -> str:
    """Export tokens as JSON"""
    return TokenExporterFactory.export("json", tokens)


def export_tokens_typescript(tokens: Dict[str, Any]) -> str:
    """Export tokens as TypeScript"""
    return TokenExporterFactory.export("typescript", tokens)


def export_tokens_scss(tokens: Dict[str, Any]) -> str:
    """Export tokens as SCSS"""
    return TokenExporterFactory.export("scss", tokens)


def export_tokens_javascript(tokens: Dict[str, Any]) -> str:
    """Export tokens as JavaScript"""
    return TokenExporterFactory.export("javascript", tokens)


def export_tokens_tailwind(tokens: Dict[str, Any]) -> str:
    """Export tokens for Tailwind"""
    return TokenExporterFactory.export("tailwind", tokens)


def export_all_formats(tokens: Dict[str, Any], output_dir: str) -> Dict[str, Path]:
    """Export tokens in all formats"""
    return TokenExporterFactory.export_all(tokens, Path(output_dir))
