"""Django app configuration for djicons."""

from pathlib import Path

from django.apps import AppConfig

# Mapping from pack names to namespaces
PACK_NAMESPACES = {
    "ionicons": "ion",
    "heroicons": "hero",
    "material": "material",
    "tabler": "tabler",
    "lucide": "lucide",
    "fontawesome": "fa",
}


class DjiconsConfig(AppConfig):
    """Django app configuration for djicons."""

    name = "djicons"
    verbose_name = "Django Icons"
    default_auto_field = "django.db.models.BigAutoField"

    def ready(self) -> None:
        """Initialize djicons when Django starts."""
        from .conf import get_setting
        from .registry import icons

        mode = get_setting("MODE")

        # Register custom icon directories from settings (highest priority)
        self._register_icon_dirs()

        # Auto-discover and register icon packs based on mode
        if get_setting("AUTO_DISCOVER"):
            if mode == "s3":
                # S3 mode: use S3 as the primary icon source
                self._register_s3_loaders()
            elif mode == "cdn":
                self._register_cdn_loaders()
            else:
                # Check for collected icons first, then fall back to packs
                collect_dir = get_setting("COLLECT_DIR")
                if collect_dir and Path(collect_dir).exists():
                    self._register_collected_icons(collect_dir)
                else:
                    self._register_packs()

                # Also register per-app icon directories (from djicons_collect --per-app)
                self._register_app_icons()

        # Register S3 loaders as additional source (for local/cdn modes with S3 config)
        if mode != "s3":
            self._register_s3_loaders()

        # Register aliases from settings
        aliases = get_setting("ALIASES")
        for alias, target in aliases.items():
            icons.register_alias(alias, target)

    def _register_icon_dirs(self) -> None:
        """Register custom icon directories from ICON_DIRS setting."""
        from .conf import get_setting
        from .loaders import DirectoryIconLoader
        from .registry import icons

        icon_dirs = get_setting("ICON_DIRS") or {}

        for namespace, path in icon_dirs.items():
            icon_path = Path(path) if isinstance(path, str) else path
            if icon_path.exists():
                loader = DirectoryIconLoader(icon_path)
                icons.register_loader(loader, namespace=namespace)

    def _register_cdn_loaders(self) -> None:
        """Register CDN loaders for all configured packs."""
        from .conf import get_setting
        from .loaders import CDNIconLoader
        from .registry import icons

        packs = get_setting("PACKS")

        for pack_name in packs:
            namespace = PACK_NAMESPACES.get(pack_name)
            if namespace:
                try:
                    loader = CDNIconLoader(namespace=namespace)
                    icons.register_loader(loader, namespace=namespace)
                except ValueError:
                    # No CDN template for this pack
                    pass

    def _register_collected_icons(self, collect_dir: str | Path) -> None:
        """Register collected icons from COLLECT_DIR."""
        from .loaders import DirectoryIconLoader
        from .registry import icons

        collect_path = Path(collect_dir)

        # Each namespace has its own subdirectory
        for namespace_dir in collect_path.iterdir():
            if namespace_dir.is_dir():
                namespace = namespace_dir.name
                loader = DirectoryIconLoader(namespace_dir)
                icons.register_loader(loader, namespace=namespace)

    def _register_app_icons(self) -> None:
        """Register icons from each app's static/icons/{namespace}/ directories."""
        from django.conf import settings as django_settings

        from .loaders import DirectoryIconLoader
        from .registry import icons

        for app in django_settings.INSTALLED_APPS:
            try:
                module = __import__(app, fromlist=[""])
                app_path = Path(module.__file__).parent
                icons_dir = app_path / "static" / "icons"
                if not icons_dir.exists():
                    continue

                for namespace_dir in icons_dir.iterdir():
                    if namespace_dir.is_dir() and not namespace_dir.name.startswith("."):
                        namespace = namespace_dir.name
                        loader = DirectoryIconLoader(namespace_dir)
                        icons.register_loader(loader, namespace=namespace)
            except (ImportError, AttributeError):
                pass

        # Also check TEMPLATES DIRS for non-app template dirs (e.g., hub/templates)
        templates_config = getattr(django_settings, "TEMPLATES", [])
        for config in templates_config:
            for dir_path in config.get("DIRS", []):
                path = Path(dir_path)
                if path.name == "templates" and (path.parent / "static" / "icons").exists():
                    icons_dir = path.parent / "static" / "icons"
                    for namespace_dir in icons_dir.iterdir():
                        if namespace_dir.is_dir() and not namespace_dir.name.startswith("."):
                            namespace = namespace_dir.name
                            loader = DirectoryIconLoader(namespace_dir)
                            icons.register_loader(loader, namespace=namespace)

    def _register_s3_loaders(self) -> None:
        """Register S3 loaders from S3 setting."""
        from .conf import get_setting
        from .loaders.s3 import S3IconLoader
        from .registry import icons

        s3_config = get_setting("S3")
        if not s3_config:
            return

        bucket = s3_config.get("bucket")
        region = s3_config.get("region", "us-east-1")
        aws_key = s3_config.get("aws_access_key_id")
        aws_secret = s3_config.get("aws_secret_access_key")

        for namespace, prefix in s3_config.get("namespaces", {}).items():
            loader = S3IconLoader(
                bucket=bucket,
                prefix=prefix,
                region=region,
                aws_access_key_id=aws_key,
                aws_secret_access_key=aws_secret,
            )
            icons.register_loader(loader, namespace=namespace)

    def _register_packs(self) -> None:
        """Register configured icon packs (local mode with downloaded icons)."""
        from .conf import get_setting
        from .registry import icons

        packs = get_setting("PACKS")

        for pack_name in packs:
            try:
                if pack_name == "ionicons":
                    from .packs.ionicons import register

                    register(icons)
                elif pack_name == "heroicons":
                    from .packs.heroicons import register

                    register(icons)
                elif pack_name == "material":
                    from .packs.material import register

                    register(icons)
                elif pack_name == "tabler":
                    from .packs.tabler import register

                    register(icons)
                elif pack_name == "lucide":
                    from .packs.lucide import register

                    register(icons)
                elif pack_name == "fontawesome":
                    from .packs.fontawesome import register

                    register(icons)
            except ImportError:
                # Pack not available (icons not downloaded yet)
                pass
