import os
import zipfile
from pathlib import Path

from speedbuild.utils.cleanup.template.clear_folder import clear_folder
from speedbuild.utils.template.file import getCurrentDjangoFiles 
from speedbuild.utils.parsers.python.parser import PythonBlockParser 

from ..extraction.extract import getTemplateFileNames
from ..extraction.feature_dependencies import removeDuplicates
from ..extraction.write_dependency import sortFile, writeToFile

user_home = str(Path.home())


def getAppFileContent(appName,fileName,project_path):
    """
    Reads a Python file, separates import statements from the rest of the code, and returns them as two lists.

    Args:
        appName (str): The name of the application (used to construct the file path).
        fileName (str): The path to the file to be read.
        project_path (str): The root path of the project.

    Returns:
        list: A list containing two elements:
            - imports (list): A list of import statements found in the file.
            - code (list): A list of code blocks that are not import statements.

    Note:
        This function uses PythonBlockParser().parse_code to split the file content into code chunks.
    """
    imports = []
    code = []

    # fileToUpdate = fileName.split("/")[-1]
    # filePath = f"{project_path}/{appName}/{fileToUpdate}"

    with open(fileName, "r") as file:
        data = file.read()
        data = PythonBlockParser().parse_code(data)
        for chunk in data:
            if chunk.startswith("import ") or chunk.startswith("from "):
                # individualImports = getIndividualImports(chunk)
                imports.append(chunk)
            else:
                code.append(chunk)

    return [imports,code]


def processFile(fileName,appName,project_path,template_path,django_root=None,processed_file_path={}):
    imports = []
    code = []

    #get new feature code
    with open(fileName,"r") as file:
        data = file.read()
        data = PythonBlockParser().parse_code(data)

        for chunk in data:
            if chunk.startswith("import ") or chunk.startswith("from "):
                # individualImports = getIndividualImports(chunk)
                imports.append(chunk)
            else:
                code.append(chunk)
    
    #get existing file content
    fileImports, fileCode = getAppFileContent(appName,fileName,project_path)

    # old implementation
    fileCode.extend(code)
    fileImports.extend(imports)
    fileCode = removeDuplicates(fileCode)
    fileImports = removeDuplicates(fileImports)

    fileToUpdate = os.path.basename(fileName)
    filePath = os.path.join(project_path,appName)

    "get all files in filePath"

    # make this dynamic, get all python file in app folder
    django_files = getCurrentDjangoFiles(filePath)#["models.py","urls.py","views.py","admin.py"]

    if "sb_app" not in fileName: # also check if filename is custom django names else write file in sb_utils folder

        new_file_path = fileName.replace(template_path,"").rstrip("/")
        if new_file_path.startswith("/"):
            new_file_path = new_file_path[1:]

        write_to_project_root = len(new_file_path.split("/")) > 1

        if write_to_project_root:

            if fileToUpdate not in django_files:
                filePath = os.path.join(filePath,"sb_utils") 
                #  update import here
                # writing to sb utils
                new_imports = []
                for line in fileImports:
                    path,dependency = line.split("import ")
                    path = path.replace("from","").replace(".sb_utils","").strip()
                    if path.startswith("."):
                        path = path[1:]


                    if f"{path}.py" in django_files:
                        new_imports.append(f"from {appName}.{path} import {dependency}")
                        continue

                    if "sb_utils" in filePath:
                        line = line.replace(".sb_utils","")

                    new_imports.append(line)

                fileImports = new_imports
        else:
            if django_root:
                filePath = os.path.join(project_path,django_root)
            # settings files
            # TODO files to add to the main django folder

        if not os.path.exists(filePath):
            os.makedirs(filePath)

    
    # update imports to remove unnecessary imports
    new_imports = []
    for line in fileImports:
        if ".sb_utils" in line:
            path,dependency = line.split("import")
            path = path.replace("from","").strip()
            path = path.replace(".sb_utils.","").strip()
            # print("sb_utils path is ", path)

            if f"{path}.py" in django_files:
                if f"{path}.py" != fileToUpdate:
                    new_imports.append(f"from .{path} import {dependency}")
                continue

            elif path in processed_file_path.keys():
                main_path = processed_file_path[path]
                new_imports.append(f"from {main_path}.{path} import {dependency}")
                continue

        new_imports.append(line)
    fileImports = new_imports

    importAsString = "\n".join(fileImports)
    codeAsString = "\n".join(fileCode)
    fileContent = importAsString + "\n\n" + codeAsString

    writeToFile(filePath,fileContent,fileToUpdate)
    if fileToUpdate == "models.py":
        sortFile(os.path.join(filePath,fileToUpdate))


def getTemplateFilteredFiles(template_unpack_path,feature_name):
    root_files = []
    filtered_files = []
    files = getTemplateFileNames(template_unpack_path)
 
    for i in files:
        if i not in ["settings.py", f"sb_{feature_name}.yaml"] and i.endswith("md") == False:
            if len(i.split("/")) == 1:
                # add to root_files also add to filtered_files
                root_files.append(i)
                filtered_files.append(i)

            elif len(i.split("/")) > 1:
                filtered_files.append(i)

    filtered_files = sorted(filtered_files, key=lambda x: not x.startswith('.sb_utils')) 
    return [filtered_files,root_files]

        
def getFeatureFromTemplate(template_path,project_root,template_name,django_root,app_name):
    """
    1) Ask for which app to implement feature. -- done
    2) Ask for Customization prompt and customize code. -- done
    3) Copy code and save in the right files (do proper refrencing).
    """
    feature_name = [word for word in template_path.split("/") if ".zip" not in word][-1]
    path_to_template = os.path.join(user_home,".sb","sb_extracted")
    
    if not os.path.exists(path_to_template):
        os.makedirs(path_to_template, exist_ok=True)

    processed_file_path = {}

    # print("\n\n------- Generating Feature -------\n\n")

    # print(f"Getting template from {template_path}")

    template_unpack_path = os.path.join(path_to_template,feature_name)
    os.makedirs(template_unpack_path, exist_ok=True)

    # unpack
    # TODO : clear previous zip content, before unzipping again
    clear_folder(template_unpack_path)
    
    # print("Unpacking template")
    with zipfile.ZipFile(template_path, 'r') as zip_ref:
        zip_ref.extractall(template_unpack_path)

    # Get and read template configuration file
    feature_name = feature_name.replace("speed_build_","")
    template_root = os.path.join(path_to_template,template_name)

    filtered_files = []
    root_files = []

    files = getTemplateFileNames(template_unpack_path)

    for i in files:
        if i not in ["settings.py", f"sb_{feature_name}.yaml"] and i.endswith("md") == False:
            if len(i.split("/")) == 1:
                root_files.append(i)

            elif len(i.split("/")) > 1:
                filtered_files.append(i)

    filtered_files = sorted(filtered_files, key=lambda x: not x.startswith('.sb_utils')) 

    for root_file in root_files:
        path_name = root_file.replace(".py","").strip()
        processed_file_path[path_name] = django_root 

    root_files.extend(filtered_files) # merge files NB, made sure root files appear first
    filtered_files = root_files

    # TODO: print feature description, along with dependencies and fields

    # TODO : get filtered files again so u get new files llm created
    filtered_files,root_files = getTemplateFilteredFiles(template_unpack_path,feature_name)

    for file in filtered_files:
        file_path = os.path.join(template_root,file)
        # print(file_path)
        processFile(file_path,app_name,project_root,template_root,django_root,processed_file_path)
    
    return [app_name,template_root]
