"""Enterprise theme for white-labeling and branding.

This module provides a fully customizable theme for enterprise use,
supporting complete branding and white-labeling.
"""

from __future__ import annotations

from dataclasses import dataclass, field, replace
from typing import Any

from truthound.datadocs.themes.base import (
    BaseTheme,
    ThemeConfig,
    ThemeColors,
    ThemeTypography,
    ThemeSpacing,
    ThemeAssets,
)


@dataclass
class BrandingConfig:
    """Branding configuration for enterprise themes.

    Attributes:
        company_name: Company name for headers/footers.
        tagline: Optional tagline.
        logo_url: URL to company logo.
        logo_base64: Base64-encoded logo (for offline reports).
        logo_height: Logo height in CSS units.
        favicon_url: URL to favicon.
        copyright_text: Copyright notice.
        website_url: Company website URL.
        support_email: Support email address.
    """
    company_name: str = ""
    tagline: str = ""
    logo_url: str | None = None
    logo_base64: str | None = None
    logo_height: str = "40px"
    favicon_url: str | None = None
    copyright_text: str = ""
    website_url: str = ""
    support_email: str = ""

    def get_footer_text(self) -> str:
        """Generate footer text from branding.

        Returns:
            Formatted footer text.
        """
        parts = []
        if self.copyright_text:
            parts.append(self.copyright_text)
        elif self.company_name:
            parts.append(f"© {self.company_name}")

        if self.website_url:
            parts.append(f"<a href=\"{self.website_url}\">{self.website_url}</a>")

        return " | ".join(parts) if parts else "Generated by Truthound"


@dataclass
class EnterpriseThemeConfig:
    """Configuration for enterprise themes.

    This extends ThemeConfig with enterprise-specific options.
    """
    name: str
    display_name: str = ""
    description: str = ""

    # Branding
    branding: BrandingConfig = field(default_factory=BrandingConfig)

    # Colors
    colors: ThemeColors = field(default_factory=ThemeColors)
    typography: ThemeTypography = field(default_factory=ThemeTypography)
    spacing: ThemeSpacing = field(default_factory=ThemeSpacing)

    # Custom CSS
    custom_css: str = ""
    print_css: str = ""

    # Layout
    header_template: str = ""
    footer_template: str = ""
    show_header: bool = True
    show_footer: bool = True
    show_toc: bool = True
    show_branding: bool = True

    # Export options
    pdf_options: dict[str, Any] = field(default_factory=dict)

    def to_theme_config(self) -> ThemeConfig:
        """Convert to base ThemeConfig.

        Returns:
            ThemeConfig instance.
        """
        return ThemeConfig(
            name=self.name,
            display_name=self.display_name,
            description=self.description,
            colors=self.colors,
            typography=self.typography,
            spacing=self.spacing,
            assets=ThemeAssets(
                logo_url=self.branding.logo_url,
                logo_base64=self.branding.logo_base64,
                favicon_url=self.branding.favicon_url,
            ),
            custom_css=self.custom_css,
            footer_text=self.branding.get_footer_text(),
            show_header=self.show_header,
            show_footer=self.show_footer,
            show_toc=self.show_toc,
        )


class EnterpriseTheme(BaseTheme):
    """Fully customizable enterprise theme.

    This theme supports complete white-labeling and branding customization.
    It can be configured via code, YAML, or JSON.

    Example:
        # Basic usage
        theme = EnterpriseTheme(
            company_name="Acme Corp",
            primary_color="#FF5722",
            logo_url="https://acme.com/logo.png",
        )

        # From configuration
        config = EnterpriseThemeConfig(
            name="acme",
            branding=BrandingConfig(
                company_name="Acme Corp",
                logo_url="https://acme.com/logo.png",
            ),
            colors=ThemeColors(primary="#FF5722"),
        )
        theme = EnterpriseTheme.from_config(config)

        # With customization
        theme = theme.customize(
            primary_color="#4CAF50",
            footer_text="Custom footer",
        )
    """

    def __init__(
        self,
        company_name: str = "",
        primary_color: str | None = None,
        secondary_color: str | None = None,
        logo_url: str | None = None,
        logo_base64: str | None = None,
        font_family: str | None = None,
        custom_css: str = "",
        **kwargs: Any,
    ) -> None:
        """Initialize an enterprise theme.

        Args:
            company_name: Company name for branding.
            primary_color: Primary brand color.
            secondary_color: Secondary brand color.
            logo_url: URL to company logo.
            logo_base64: Base64-encoded logo.
            font_family: Primary font family.
            custom_css: Additional custom CSS.
            **kwargs: Additional configuration options.
        """
        # Build branding config
        branding = BrandingConfig(
            company_name=company_name,
            logo_url=logo_url,
            logo_base64=logo_base64,
            tagline=kwargs.get("tagline", ""),
            copyright_text=kwargs.get("copyright_text", ""),
            website_url=kwargs.get("website_url", ""),
        )

        # Build colors
        colors = ThemeColors(
            primary=primary_color or "#2563eb",
            secondary=secondary_color or "#4f46e5",
            background=kwargs.get("background_color", "#fafbfc"),
            surface=kwargs.get("surface_color", "#ffffff"),
            text_primary=kwargs.get("text_primary_color", "#1f2937"),
            text_secondary=kwargs.get("text_secondary_color", "#6b7280"),
        )

        # Build typography
        typography = ThemeTypography(
            font_family=font_family or "'Inter', system-ui, sans-serif",
        )

        # Build enterprise config
        self._enterprise_config = EnterpriseThemeConfig(
            name=kwargs.get("name", "enterprise"),
            display_name=kwargs.get("display_name", company_name or "Enterprise"),
            description=kwargs.get("description", "Custom enterprise theme"),
            branding=branding,
            colors=colors,
            typography=typography,
            custom_css=custom_css,
            show_header=kwargs.get("show_header", True),
            show_footer=kwargs.get("show_footer", True),
            show_toc=kwargs.get("show_toc", True),
            show_branding=kwargs.get("show_branding", True),
        )

        # Initialize base theme
        super().__init__(self._enterprise_config.to_theme_config())

    @classmethod
    def from_config(cls, config: EnterpriseThemeConfig) -> "EnterpriseTheme":
        """Create theme from configuration.

        Args:
            config: Enterprise theme configuration.

        Returns:
            EnterpriseTheme instance.
        """
        theme = cls.__new__(cls)
        theme._enterprise_config = config
        BaseTheme.__init__(theme, config.to_theme_config())
        return theme

    @property
    def enterprise_config(self) -> EnterpriseThemeConfig:
        """Get the enterprise configuration."""
        return self._enterprise_config

    @property
    def branding(self) -> BrandingConfig:
        """Get the branding configuration."""
        return self._enterprise_config.branding

    @property
    def company_name(self) -> str:
        """Get the company name."""
        return self._enterprise_config.branding.company_name

    def get_css(self) -> str:
        """Get the complete CSS for this theme.

        Returns:
            CSS string including branding-specific styles.
        """
        base_css = super().get_css()
        branding_css = self._get_branding_css()
        return f"{base_css}\n\n{branding_css}"

    def _get_branding_css(self) -> str:
        """Generate branding-specific CSS.

        Returns:
            CSS for branding elements.
        """
        branding = self.branding
        css_parts = []

        if branding.logo_height:
            css_parts.append(f"""
.report-logo {{
    max-height: {branding.logo_height};
}}
""")

        if branding.company_name:
            css_parts.append(f"""
.report-footer::before {{
    content: "{branding.company_name}";
    font-weight: 600;
    margin-right: 0.5rem;
}}
""")

        return "\n".join(css_parts)

    def _get_base_css(self) -> str:
        """Get enterprise-specific base CSS."""
        return """
/* Enterprise theme adjustments */
.report-header {
    border-bottom: 3px solid var(--color-primary);
}
.report-section h2 {
    border-left: 4px solid var(--color-primary);
    padding-left: 1rem;
    border-bottom: none;
}
"""

    def customize(self, **overrides: Any) -> "EnterpriseTheme":
        """Create a customized version of this theme.

        Args:
            **overrides: Values to override.

        Returns:
            New theme instance with customizations.
        """
        config = self._enterprise_config

        # Handle branding overrides
        branding_overrides = {}
        colors_overrides = {}
        typography_overrides = {}
        config_overrides = {}

        for key, value in overrides.items():
            if key in ("company_name", "tagline", "logo_url", "logo_base64",
                       "logo_height", "favicon_url", "copyright_text",
                       "website_url", "support_email"):
                branding_overrides[key] = value
            elif key.endswith("_color") or key in ("primary", "secondary", "accent"):
                # Map color overrides
                color_key = key.replace("_color", "").replace("primary", "primary").replace("secondary", "secondary")
                colors_overrides[color_key] = value
            elif key.startswith("font_"):
                typography_overrides[key] = value
            else:
                config_overrides[key] = value

        # Apply overrides
        new_branding = replace(config.branding, **branding_overrides) if branding_overrides else config.branding
        new_colors = replace(config.colors, **colors_overrides) if colors_overrides else config.colors
        new_typography = replace(config.typography, **typography_overrides) if typography_overrides else config.typography

        new_config = replace(
            config,
            branding=new_branding,
            colors=new_colors,
            typography=new_typography,
            **config_overrides,
        )

        return EnterpriseTheme.from_config(new_config)

    def with_branding(
        self,
        company_name: str | None = None,
        logo_url: str | None = None,
        logo_base64: str | None = None,
        tagline: str | None = None,
        copyright_text: str | None = None,
        website_url: str | None = None,
    ) -> "EnterpriseTheme":
        """Create a new theme with updated branding.

        Args:
            company_name: New company name.
            logo_url: New logo URL.
            logo_base64: New base64 logo.
            tagline: New tagline.
            copyright_text: New copyright text.
            website_url: New website URL.

        Returns:
            New theme with updated branding.
        """
        overrides = {}
        if company_name is not None:
            overrides["company_name"] = company_name
        if logo_url is not None:
            overrides["logo_url"] = logo_url
        if logo_base64 is not None:
            overrides["logo_base64"] = logo_base64
        if tagline is not None:
            overrides["tagline"] = tagline
        if copyright_text is not None:
            overrides["copyright_text"] = copyright_text
        if website_url is not None:
            overrides["website_url"] = website_url

        return self.customize(**overrides)

    def with_colors(
        self,
        primary: str | None = None,
        secondary: str | None = None,
        accent: str | None = None,
        background: str | None = None,
        surface: str | None = None,
    ) -> "EnterpriseTheme":
        """Create a new theme with updated colors.

        Args:
            primary: New primary color.
            secondary: New secondary color.
            accent: New accent color.
            background: New background color.
            surface: New surface color.

        Returns:
            New theme with updated colors.
        """
        overrides = {}
        if primary is not None:
            overrides["primary"] = primary
        if secondary is not None:
            overrides["secondary"] = secondary
        if accent is not None:
            overrides["accent"] = accent
        if background is not None:
            overrides["background"] = background
        if surface is not None:
            overrides["surface"] = surface

        return self.customize(**overrides)
