import argparse
import sys
import os
import json
import uuid
import subprocess
import bpy
from pathlib import Path
from asset_library.common.functions import create_catalog_file
from asset_library.common.file_utils import get_last_files
from asset_library.constants import ASSETLIB_FILENAME


"""
### Create asset collection

## create_collection_library: generate all category blend from json
## if source_directory is set, call create_collection_json

##    # create_collection_json:
##    # scan marked blend, create json and call create_catalog_file

##         # create_catalog_file
##         # create catalog file from json file

###  Json Structure 
[
    {
    'name': 'chars/main',
    'id': '013562-56315-4563156-123',
    'children':
            [
                {
                'filepath' : '/z/...',
                'name' : 'collection name',
                'tags' : ['variation', 'machin', 'chose'],
                'metadata' : {'filepath': '$PROJECT/...', 'version' : 'mushable'}
                },
                {
                'filepath' : '/z/...',
                },
            ],
    },
] 
"""

def create_collection_json(path, source_directory):
    '''Create a Json from every marked collection in blends
    contained in folderpath (respect hierachy)
    '''

    json_path = Path(path) / ASSETLIB_FILENAME
    
    # scan all last version of the assets ?
    # get last version files ?
    # or open all blends and look only for marked collection ? (if versionned, get still get only last)

    # get all blend in dir and subdirs (only last when versionned _v???)
    blends = get_last_files(source_directory, pattern=r'(_v\d{3})?\.blend$', only_matching=True)

    root_path = Path(source_directory).as_posix().rstrip('/') + '/'
    print('root_path: ', root_path)
    # open and check data block marked as asset

    category_datas = []
    for i, blend in enumerate(blends):
        fp = Path(blend)
        print(f'{i+1}/{len(blends)}')
        
        ## What is considered a grouping category ? top level folders ? parents[1] ?

        ## Remove root path and extension
        ## top level folder ('chars'), problem if blends at root 
        category = fp.as_posix().replace(root_path, '').split('/')[0]
        
        ## full blend path (chars/perso/perso)
        # category = fp.as_posix().replace(root_path, '').rsplit('.', 1)[0]
        
        print(category)

        with bpy.data.libraries.load(blend, link=True, assets_only=True) as (data_from, data_to):
            ## just listing
            col_name_list = [c for c in data_from.collections]

        if not col_name_list:
            continue

        col_list = next((c['children'] for c in category_datas if c['name'] == category), None)
        if col_list is None:
            col_list = []
            category_data = {
                'name': category,
                'id': str(uuid.uuid4()),
                'children': col_list,
                }
            category_datas.append(category_data)


        blend_source_path = blend.as_posix()
        if (project_root := os.environ.get('PROJECT_ROOT')):
            blend_source_path = blend_source_path.replace(project_root, '$PROJECT_ROOT')


        for name in col_name_list:
            data = {
                'filepath' : blend,
                'name' : name,
                # 'tags' : [],
                'metadata' : {'filepath': blend_source_path},
            }

            col_list.append(data)

    json_path.write_text(json.dumps(category_datas, indent='\t'))
    ## create text catalog from json (keep_existing_category ?)
    create_catalog_file(json_path, keep_existing_category=True)


def create_collection_library(path, source_directory=None):
    '''
    path: store collection library (json and blends database)
    source_directory: if a source is set, rebuild json and library
    '''

    if source_directory:
        if not Path(source_directory).exists():
            print(f'Source directory not exists: {source_directory}')
            return

        ## scan source and build json in assetlib dir root
        create_collection_json(path, source_directory)

    json_path = Path(path) / ASSETLIB_FILENAME
    if not json_path.exists():
        print(f'No json found at: {json_path}')
        return

    file_datas = json.loads(json_path.read())

    ## For each category in json, execute build_assets_blend script
    script = Path(__file__).parent / 'build_collection_blends.py'
    #empty_blend = Path(__file__).parent / 'empty_scene.blend'
    
    # for category, asset_datas in file_datas.items():
    for category_data in file_datas:
        ## add an empty blend as second arg
        cmd = [bpy.app.binary_path, '--python', str(script), '--', '--path', path, '--category', category_data['name']]
        print('cmd: ', cmd)
        subprocess.call(cmd)


if __name__ == '__main__' :
    parser = argparse.ArgumentParser(description='Create Collection Library',
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--path') # trouve/créer le json assetlib.json en sous-dossier de libdir 

    if '--' in sys.argv :
        index = sys.argv.index('--')
        sys.argv = [sys.argv[index-1], *sys.argv[index+1:]]

    args = parser.parse_args()
    create_collection_library(**vars(args))