import os
import shutil
import sys
import asyncio

from pathlib import Path
from rich.prompt import Prompt

from speedbuild.agents.config import getLLMConfig, setSpeedbuildConfig
from speedbuild.utils.cleanup.template.clear_folder import clear_folder

from .frameworks.express.deployment.deployJS import deployExpressFeature
from .frameworks.django.extraction.extract_features import createTemplate
from .frameworks.express.extraction.extractjs import startExpressExtraction
from .frameworks.django.deployment.debug_and_customize import testCustomizeAndDeployDjangoFeature 

from .utils.undo.undo import undoSBDeploy
from .utils.repo_templates.push import pushTemplate
from .utils.package_utils import getPackageNameMapping
from .utils.repo_templates.pull import pullTemplateFromHub

from .auth.sb_user import sbAuth
from .auth.auth import manageAuth
from .auth.cli_utils import get_config
from .auth.serverCall import manageServerCall, pingServer


def logUserCommand(args):
    command = "speedbuild " + " ".join(args[1:])
    manageServerCall("POST","api/log-action/",{"command":command},{},True)

def extractFeature(project_root,args,append_root=False):
    try:
        target = args[2]
        extract_from = args[3]
        framework = args[4]

        framework = framework.replace("--","").lower()

        # clear extraction output folder here
        output_folder = os.path.join(project_root,"output")
        if os.path.exists(output_folder):
            clear_folder(output_folder)
            shutil.rmtree(output_folder)

        # set run_documentation env to its default
        os.environ['run_documentation'] = "False"

        if framework == "django":
            # Extract django feature
            # logger.start_status("Extracting django feature")
            try:
                project_name = os.path.basename(project_root)
                packageToNameMapping,installedPackages = getPackageNameMapping(project_root)
                createTemplate(extract_from, target,project_name,packageToNameMapping,project_root,append_root,installedPackages)
            except ValueError as e:
                print(e)
            
        elif framework == "express":
            #Extract Express feature
            asyncio.run(startExpressExtraction(target,extract_from,project_root))

        # if framework in ['django','express']:
        #     logUserCommand(args)

    except IndexError:
        print("Usage : python final.py <what_to_extract> <extraction_entry_point> --framework")


def deployFeature(project_root,args):
    try:
        template = args[2]
        framework = args[3]
        framework = framework.replace("--","").lower()
        print(f"Deploying {template}")
        
        customization_request = Prompt.ask("[cyan bold] Will you like to customize this feature (yes/no) [/cyan bold]")
        while customization_request.lower().strip() not in ['yes','no']:
            customization_request = Prompt.ask("[cyan] Please enter a valid response (yes/no)[/cyan]")

        customization_request = customization_request.strip() == "yes"

        if framework == "django":
            # implementFeature(template)
            app_name = Prompt.ask("[cyan bold] Which django app do you want to implement feature in [/cyan bold] ")
            app_path = os.path.join(project_root,app_name)
            if os.path.exists(app_path) and os.path.isdir(app_path):
                testCustomizeAndDeployDjangoFeature(template,project_root,app_name,customization_request)
            else:
                print("Please Enter a valid app name")
        elif framework == "express":
            asyncio.run(deployExpressFeature(template,project_root,customization_request)) #true is so we customize otherwise use false

        # if framework in ['django','express']:
        #     logUserCommand(args)

    except IndexError:
        print("Usage : python final.py deploy <template_name>")

def listExtractedFeature(args):
    print("Listing All Extracted Templates")
    user_home = str(Path.home())
    templates_dir = f"{user_home}/.sb_zip"

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

    count = 1
    templates = os.listdir(templates_dir)

    for template in templates:
        # if template.startswith("speed_build"):
        #     print(f"    {count}) {template}")
        #     count += 1
        print(f"    {count}) {template}")
        count += 1
        
    print("\n")

def start():
    args = sys.argv
    setSpeedbuildConfig()
    getLLMConfig()
    current_path = os.path.abspath(".")


    try:
        # TODO : remove this
        api_key = os.environ.get("OPENAI_API_KEY",None)
        if api_key == None:
            config = get_config()
            if "openai" in config['llm_keys'].keys():
                os.environ["OPENAI_API_KEY"] = config["llm_keys"]['openai']
    except:
        pass

    try:
        command = args[1]

        if command == "extract":
            # sb.py extract / views.py --express
            extractFeature(current_path,args)

        elif command == "deploy":
            # sb.py deploy template_name
            deployFeature(current_path,args)

        elif command == "list":
            listExtractedFeature(args)

        elif command == "undo":
            print("performing undo")
            undoSBDeploy()

        elif command == "auth":
            asyncio.run(sbAuth())

        elif command == "ping":
            pingServer()
            
        elif command == "setup":
            print("Seting up speedbuild")
            asyncio.run(manageAuth("register"))

        elif command == "push":
            try:
                template = args[2]
                framework = args[3].replace("-","").strip()

                if framework not in ["express","django"]:
                    print("Please enter a valid framework")
                    return
                
                user_home = str(Path.home())
                template_dir = os.path.join(user_home,".sb_zip",template)

                if not os.path.exists(template_dir):
                    print(f"Invalid template : {template}")
                    return
                
                pushTemplate(template,framework)
                
            except IndexError:
                print("Usage : speedbuild push <template_name> --framework")

        elif command == "pull":
            try:
                template = args[2]
                if "/" not in template:
                    print("Usage : speedbuild pull <template_repo>/<template_name>")
                    return
                
                pullTemplateFromHub(template)
            except IndexError:
                print("Usage : speedbuild pull <template_repo>/<template_name>")
            except ValueError as err:
                print("Pull error :",err)

        elif command == "use":
            try:
                template = args[2]
                framework = args[3]
                framework = framework.replace("--","").lower()

                if "/" not in template:
                    print("Usage : speedbuild use <template_repo>/<template_name> --framework")
                    return
        
                template_name = pullTemplateFromHub(template)
                print("pulled template ", template_name)
                deployFeature(current_path,["speedbuild","deploy",template_name, framework])

            except IndexError:
                print("Usage : speedbuild use <template_repo>/<template_name> --framework")

            except ValueError as err:
                print("Pull error :",err)


    except IndexError as e:
        print("Available commands :\n- extract\n- deploy\n- list\n- undo\n- auth\n- ping\n- setup\n- push\n- pull")

# start() # remove this