import zipfile
import re
from datetime import datetime
from .morph_functions import get_morphs_list_from_zip


# Function for generating tags from zip structure
def generate_tags_from_zip(z):
    # Define
    tags_and_paths = {
        'Appearance' : ('Person/Appearance','Person/appearance'),
        'Legacy' : 'Saves/Person',
        'Assets' : 'Custom/Assets',
        'Clothing' : 'Custom/Clothing',
        'Hair' : 'Custom/Hair',
        'General' : 'Person/General',
        'Morphs' : 'Person/Morphs',
        'Female' : 'Morphs/female',
        'Male' : 'Morphs/male',
        'Pose' : 'Person/Pose',
        'Clothing Preset' : 'Person/Clothing',
        'Scenes' : 'Saves/scene',
        'Scripts' : 'Custom/Scripts',
        'Sounds' : 'Custom/Sounds',
        'SubScene' : 'Custom/SubScene',
        'Textures' : 'Custom/Atom/Person/Textures'
    }

    # Initialize set for storing found tags (avoid dupes)
    tags_found = set()
    # Look for tags in zip paths
    paths = {"/".join(file.split("/")[:-1]) for file in z.namelist()} # build a deduplicated set of paths, no filenames
    for tag, subpath in tags_and_paths.items():

        if isinstance(subpath, tuple):
            # If tuple, iterate on each tuple's element
            for path in paths:
                if any(s in path for s in subpath):
                    tags_found.add(tag)
                    break
        else: # itearate on each element
            for path in paths:
                if subpath in path:
                    tags_found.add(tag)
                    break
    # Join found tags in a comma separated string
    result = ', '.join(sorted(tags_found))  # alpha sort alternative
    # result = ', '.join(tags_found)
    return result

# Function for processing zip file and extract useful data
def fetch_var_data(var_path, var_name, level):
    from .image_tools import generate_thumbs_from_zip
    var_tags = ''
    var_deps = ''
    var_info = ''
    var_date = ''
    var_thumbs = ''
    var_instr = ''
    var_morphs = ''
    var_morphn = ''
    try:
        with zipfile.ZipFile(var_path, 'r') as z:

            # Generate tags
            var_tags = generate_tags_from_zip(z)

            # Generate thumbnail
            var_thumbs = generate_thumbs_from_zip(f"thumbnails/{var_name}.jpg", z)

            # Morphs names lists and total number of morphs
            if 'Morphs' in var_tags:
                morphsf = get_morphs_list_from_zip(z, 'f', 'Custom/Atom/Person/Morphs/female')
                morphsfg = get_morphs_list_from_zip(z, 'fg', 'Custom/Atom/Person/Morphs/female_genitalia')
                morphsm = get_morphs_list_from_zip(z, 'm', 'Custom/Atom/Person/Morphs/male')
                morphsmg = get_morphs_list_from_zip(z, 'mg', 'Custom/Atom/Person/Morphs/male_genitalia')

                var_morphs = ''
                # for item in enumerate(morphsf):
                var_morphs += ', '.join(morphsf)
                var_morphs += ', '.join(morphsfg)
                var_morphs += ', '.join(morphsm)
                var_morphs += ', '.join(morphsmg)
                var_morphn = len(morphsf)+len(morphsm)+len(morphsfg)+len(morphsmg)
                
            # Look for meta.json data in zip
            if 'meta.json' in z.namelist():

                # Get meta.json timestamp as YYYY/MM/DD format
                dt = z.getinfo('meta.json').date_time
                var_date = datetime(dt[0],dt[1],dt[2]).strftime('%Y/%m/%d')

                # Open and read meta.json
                f = z.open('meta.json', 'r')
                content = f.read().decode('utf-8')

                # Find regex patterns in text
                match_description = re.search(r'"description"\s*:\s*"([^"]*(?:""[^"]*)*)",', content)
                match_instructions = re.search(r'"instructions"\s*:\s*"([^"]*(?:""[^"]*)*)",', content)

                # Extract found sections and trim opening and ending quotes
                var_info = match_description.group(1).replace('\\"', '"') if match_description else ''
                var_instr = match_instructions.group(1).replace('\\"', '"') if match_instructions else ''

                # Find "dependencies" position
                deps_index = content.find('"dependencies"')
                if deps_index:
                    # Get a substring from "dependencies" until EOF
                    deps_content = content[deps_index:]
                    # RegExp for finding deps in format "creator.name.version : {"
                    pattern = r'"([^"]*\.[^"]*\.[^"]*)"\s*:\s*\{'
                    # Find all substring matches
                    var_deps = ', '.join(re.findall(pattern, deps_content))

            else:
                # If no meta.json, fill with error info
                var_info = 'Error: Package has no meta.json'
    except Exception as e:
        # If zip open fails, fill with error info
        var_info = 'ERROR: Bad or corrupted package'

    # return a tuple for record insert
    return ( var_name, var_tags, var_deps, var_date, var_info, var_instr, var_thumbs, var_morphs, var_morphn, level)
