import re
from kabaret import flow
from libreflow.baseflow.asset import AssetFamilyCollection, AssetTypeCollection
from libreflow.flows.default.flow.asset import AssetType, Assets


from . import _version
__version__ = _version.get_versions()['version']


class CreateKitsuAssets(flow.Action):

    ICON = ('icons.libreflow', 'kitsu')

    skip_existing = flow.SessionParam(False).ui(editor='bool')
    create_task_default_files = flow.SessionParam(True).ui(editor='bool')

    _assets = flow.Parent()
    _asset_family = flow.Parent(2)
    _asset_type = flow.Parent(4)

    def allow_context(self, context):
        return context

    def get_buttons(self):
        return ['Create assets', 'Cancel']
    
    def run(self, button):
        if button == 'Cancel':
            return

        session = self.root().session()

        skip_existing = self.skip_existing.get()
        assets_data = self.root().project().kitsu_api().get_assets_data(self._asset_type.name())

        # Filter assets by family
        assets_data = [
            ad
            for ad in assets_data
            if ad["data"].get("family", None) is not None
            and ad["data"].get("family", None) == self._asset_family.name()
        ]

        for data in assets_data:
            name = data['name']

            if not self._assets.has_mapped_name(name):
                session.log_info(f'[Create Kitsu Assets] Creating Asset {name}')
                a = self._assets.add(name)
            elif not skip_existing:
                a = self._assets[name]
                session.log_info(f'[Create Kitsu Assets] Updating Default Tasks {name}')
                a.ensure_tasks()
            else:
                continue

            if self.create_task_default_files.get():
                for t in a.tasks.mapped_items():
                    session.log_info(f'[Create Kitsu Assets] Updating Default Files {name} {t.name()}')
                    t.create_dft_files.files.update()
                    t.create_dft_files.run(None)

        self._assets.touch()


class CreateKitsuAssetFamilies(flow.Action):

    ICON = ('icons.libreflow', 'kitsu')

    skip_existing = flow.SessionParam(False).ui(editor='bool')
    create_assets = flow.SessionParam(False).ui(editor='bool')
    create_task_default_files = flow.SessionParam(False).ui(editor='bool')

    _asset_families = flow.Parent()
    _asset_type = flow.Parent(2)

    def allow_context(self, context):
        return context

    def get_buttons(self):
        return ['Create families', 'Cancel']
    
    def run(self, button):
        if button == 'Cancel':
            return

        session = self.root().session()

        assets_data = self.root().project().kitsu_api().get_assets_data(self._asset_type.name())
        create_assets = self.create_assets.get()
        skip_existing = self.skip_existing.get()

        asset_family_names = [ad["data"].get("family", None) for ad in assets_data]

        for i, name in enumerate(asset_family_names):
            if name is None:
                continue

            if not self._asset_families.has_mapped_name(name):
                session.log_info(f'[Create Kitsu Asset Families] Create Asset family {name} for Asset Type {self._asset_type.name()}')
                af = self._asset_families.add(name)
            elif not skip_existing:
                session.log_info(f'[Create Kitsu Asset Families] Asset family {name} exists for Asset Type {self._asset_type.name()}')
                af = self._asset_families[name]
            else:
                continue

            if create_assets:
                af.assets.create_assets.skip_existing.set(skip_existing)
                af.assets.create_assets.create_task_default_files.set(self.create_task_default_files.get())
                af.assets.create_assets.run('Create assets')

        self._asset_families.touch()


class CreateKitsuAssetTypes(flow.Action):

    ICON = ('icons.libreflow', 'kitsu')

    skip_existing = flow.SessionParam(False).ui(editor='bool')
    create_asset_families = flow.SessionParam(False).ui(editor='bool')
    create_assets = flow.SessionParam(False).ui(editor='bool')
    create_task_default_files = flow.SessionParam(False).ui(editor='bool')

    _asset_types = flow.Parent()

    def allow_context(self, context):
        return context

    def get_buttons(self):
        return ['Create asset types', 'Cancel']
    
    def run(self, button):
        if button == 'Cancel':
            return

        session = self.root().session()
        
        asset_types_data = self.root().project().kitsu_api().get_asset_types_data()
        create_asset_families = self.create_asset_families.get()
        create_assets = self.create_assets.get()
        skip_existing = self.skip_existing.get()

        for data in asset_types_data:
            name = data['name']

            if name == 'x':
                continue

            # Ensure asset type
            if not self._asset_types.has_mapped_name(name):
                session.log_info(f'[Create Kitsu Asset Types] Creating Asset Type {name}')
                at = self._asset_types.add(name)
            elif not skip_existing:
                session.log_info(f'[Create Kitsu Asset Types] Asset Type {name} exists')
                at = self._asset_types[name]
            else:
                continue

            if create_asset_families:
                at.asset_families.create_asset_families.skip_existing.set(skip_existing)
                at.asset_families.create_asset_families.create_assets.set(create_assets)
                at.asset_families.create_asset_families.create_task_default_files.set(self.create_task_default_files.get())
                at.asset_families.create_asset_families.run('Create families')

        self._asset_types.touch()


def hide_assets_map(parent):
    if isinstance(parent, AssetType):
        r = flow.Child(Assets).ui(
            expanded=True, hidden=True, default_height=600
        )
        r.name = 'assets'
        return r


def create_kitsu_assets(parent):
    if isinstance(parent, AssetTypeCollection):
        r = flow.Child(CreateKitsuAssetTypes)
        r.name = "create_asset_types" # override base action
        r.index = None
        return (r, 1)
    elif isinstance(parent, AssetFamilyCollection):
        r = flow.Child(CreateKitsuAssetFamilies)
        r.name = "create_asset_families"
        r.index = None
        return (r, 1)
    elif isinstance(parent, Assets):
        r = flow.Child(CreateKitsuAssets)
        r.name = "create_assets"
        r.index = None
        return (r, 1)


def install_extensions(session):
    return {
        "lpc": [
            create_kitsu_assets,
            hide_assets_map
        ]
    }
