import asyncio
import os

import carb
import carb.tokens
import omni.kit.app

from .common import get_omni_documents_path
from .utils import get_setting

# Store last user choosen folder for convenience between sessions
RECENT_EXPORT_PATH_KEY = "/persistent/exts/omni.kit.window.extensions/recentExportPath"


def _print_and_log(message):
    carb.log_info(message)
    print(message)


async def _ask_user_for_path(is_export: bool, apply_button_label="Choose", title=None):
    app = omni.kit.app.get_app()
    manager = app.get_extension_manager()
    if not manager.is_extension_enabled("omni.kit.window.filepicker"):
        manager.set_extension_enabled("omni.kit.window.filepicker", True)

        await app.next_update_async()
        await app.next_update_async()

    from omni.kit.widget.filebrowser import FileBrowserItem
    from omni.kit.window.filepicker import FilePickerDialog

    done = False
    choosen_path = None

    def on_click_cancel(f, d):
        nonlocal done
        done = True

    if is_export:

        def on_click_open(f, d):
            nonlocal done, choosen_path
            choosen_path = d
            done = True

        filepicker = FilePickerDialog(
            title or "Choose Folder",
            allow_multi_selection=False,
            apply_button_label=apply_button_label,
            click_apply_handler=on_click_open,
            click_cancel_handler=on_click_cancel,
            enable_filename_input=False,
        )
    else:

        def on_click_open(f, d):
            nonlocal done, choosen_path
            choosen_path = os.path.join(d, f)
            done = True

        def on_filter_zip_files(item: FileBrowserItem) -> bool:
            if not item or item.is_folder:
                return True
            return os.path.splitext(item.path)[1] == ".zip"

        filepicker = FilePickerDialog(
            title or "Choose Extension Zip Archive",
            allow_multi_selection=False,
            apply_button_label="Import",
            click_apply_handler=on_click_open,
            click_cancel_handler=on_click_cancel,
            item_filter_options=[("*.zip", ".zip Archives (*.zip)")],
            item_filter_fn=on_filter_zip_files,
        )

    recent_path = get_setting(RECENT_EXPORT_PATH_KEY, None)
    if not recent_path:
        recent_path = get_omni_documents_path()

    filepicker.show(path=recent_path)

    while not done:
        await app.next_update_async()

    filepicker.hide()
    filepicker.destroy()

    if choosen_path:
        recent_path = os.path.dirname(choosen_path) if os.path.isfile(choosen_path) else choosen_path
        carb.settings.get_settings().set(RECENT_EXPORT_PATH_KEY, recent_path)

    return choosen_path


async def _export(ext_id: str):
    output = await _ask_user_for_path(is_export=True, apply_button_label="Export")

    if output:
        app = omni.kit.app.get_app()
        manager = app.get_extension_manager()
        archive_path = manager.pack_extension(ext_id, output)
        app.print_and_log(f"Extension: '{ext_id}' was exported to: '{archive_path}'")


async def _import():
    archive_path = await _ask_user_for_path(is_export=False, apply_button_label="Import")

    # Registry Local Cache Folder
    registry_cache = get_setting("/app/extensions/registryCacheFull", None)
    if not registry_cache:
        carb.log_error("Can't import extension, registry cache path is not set.")
        return

    if archive_path:
        omni.ext.unpack_extension(archive_path, registry_cache)
        omni.kit.app.get_app().print_and_log(f"Extension: '{archive_path}' was imported to: '{registry_cache}'")


def export_ext(ext_id: str):
    asyncio.ensure_future(_export(ext_id))


def import_ext():
    asyncio.ensure_future(_import())
