"""Complete compact Flatpak records with metadata from the local AppStream pool."""

from typing import Any, Iterable, Optional

import gi

gi.require_version("AppStream", "1.0")
from gi.repository import AppStream  # type: ignore  # noqa: E402


def _missing(value: Any) -> bool:
    return value is None or value == "" or value == []


def _component_for_app(pool: Any, package: str) -> Optional[Any]:
    components = pool.get_components_by_bundle_id(
        AppStream.BundleKind.FLATPAK, package, True
    ).as_array()
    if components:
        return components[0]

    parts = package.split("/")
    if len(parts) > 1:
        components = pool.get_components_by_id(parts[1]).as_array()
        if components:
            return components[0]
    return None


def _developer_name(component: Any) -> Optional[str]:
    developer = component.get_developer()
    return developer.get_name() if developer is not None else None


def _mimetypes(component: Any) -> list[str]:
    provided = component.get_provided_for_kind(AppStream.ProvidedKind.MEDIATYPE)
    return list(provided.get_items()) if provided is not None else []


def _set_if_missing(app: Any, attribute: str, value: Any) -> None:
    if _missing(getattr(app, attribute, None)) and not _missing(value):
        setattr(app, attribute, value)


def complement_flatpak_apps(apps: Iterable[Any], pool: Optional[Any] = None) -> None:
    """Fill compact Flatpak records in-place using system-locale AppStream data.

    Curated values already present in repo.yaml always win. Required display
    fields receive safe fallbacks when a component is unavailable so a single
    incomplete AppStream record cannot prevent stillCenter opening an app.
    """
    apps = list(apps)
    flatpak_apps = [
        app for app in apps
        if isinstance(getattr(app, "src_pkg_name", None), str)
        and app.src_pkg_name.startswith("app/")
    ]

    if pool is None and flatpak_apps:
        try:
            pool = AppStream.Pool()
            pool.add_flags(AppStream.PoolFlags.LOAD_FLATPAK)
            pool.load()
        except Exception as error:
            print(f"Warning: Could not load AppStream metadata: {error}")
            pool = None

    for app in flatpak_apps:
        component = None
        if pool is not None:
            try:
                component = _component_for_app(pool, app.src_pkg_name)
            except Exception as error:
                print(f"Warning: Could not resolve AppStream data for {app.src_pkg_name}: {error}")

        if component is not None:
            _set_if_missing(app, "name", component.get_name())
            _set_if_missing(app, "author", _developer_name(component))
            _set_if_missing(app, "summary", component.get_summary())
            _set_if_missing(app, "description", component.get_description())
            _set_if_missing(app, "categories", list(component.get_categories() or []))
            _set_if_missing(app, "keywords", list(component.get_keywords() or []))
            _set_if_missing(app, "mimetypes", _mimetypes(component))
            _set_if_missing(app, "app_license", component.get_project_license())
            _set_if_missing(app, "homepage", component.get_url(AppStream.UrlKind.HOMEPAGE))
            _set_if_missing(app, "donate_url", component.get_url(AppStream.UrlKind.DONATION))

        # stillCenter assumes these display values are usable strings/lists.
        package_id = app.src_pkg_name.split("/")[1]
        _set_if_missing(app, "name", package_id)
        _set_if_missing(app, "summary", app.name)
        _set_if_missing(app, "description", app.summary)
        _set_if_missing(app, "author", "Unknown Author")
        _set_if_missing(app, "categories", ["Unknown"])

