import logging
import os
from typing import Any, List, Optional

from .agregations import adds
from zpy.cli.scaffolding import creator, place_holders
from zpy.cli.scaffolding.boilerplates import basic
from zpy.cli.utils import exist_folder, join_path, if_exist_move, camel_case


def get_last_import(lines):
    index = 0
    for i in range(0, len(lines)):
        if "import" in lines[i] or "from" in lines[i]:
            index = i
    return index + 1


def add_context(name: str, use_case: str, force: bool):
    current_directory = os.getcwd()
    initial_dir = os.getcwd()
    exist, current_directory = if_exist_move(current_directory, 'src')
    exist, current_directory = if_exist_move(current_directory, 'contexts')
    if exist is False and force is False:
        print("Oops!! It seems you are not in a project generated by zpy...")
        print("Can't find the src or contexts directory")
        print("\nIf you want generate the context outside of project use the -f flag when add the context.\n")
        print(f'\nzpy add context -n {name} -uc {use_case} -f\n')
        return
    in_data = [{"value": "", "title": "Project name:"},
               {"value": "", "title": "Project description:"},
               {"value": "", "title": "Author:"},
               {"value": "", "title": "Url Author:"},
               {"value": name.lower(), "title": "Context:"},
               {"value": use_case, "title": "Use Case:"},
               {"value": name.title(), "title": "Repository"},
               {"value": "", "title": "Open Project?:"},
               {"value": "", "title": "Only Content?:"},
               current_directory
               ]
    try:
        creator(current_directory, basic['src']['child']['contexts']['child'], in_data, False, force)
    except Exception as e:
        print(e.args)
        print("Can't create context...")
        return
    try:
        file_writer(join_path(initial_dir, "src/di.py"), adds.get("context_imports").get("code"), in_data)
    except:
        print("Can't update dependencies file... Not Found!")
    print(f"\nContext with name: {name} created successfully!\n")


def add_use_case(name: str, context: str):
    current_directory = os.getcwd()
    initial_dir = os.getcwd()
    exist, current_directory = if_exist_move(current_directory, 'src')
    exist, current_directory = if_exist_move(current_directory, 'contexts')
    exist, current_directory = if_exist_move(current_directory, context)
    exist, current_directory = if_exist_move(current_directory, 'application')
    if exist is False:
        print("Oops!! It seems you are not in a project generated by zpy...")
        print(f"Can't find the src/contexts/{context}/application directory")
        print("\nRemember that you need execute command in the root path of the project.")
        return
    in_data = [{"value": "", "title": "Project name:"},
               {"value": "", "title": "Project description:"},
               {"value": "", "title": "Author:"},
               {"value": "", "title": "Url Author:"},
               {"value": context.lower(), "title": "Context:"},
               {"value": camel_case(name), "title": "Use Case:"},
               {"value": context.title(), "title": "Repository"},
               {"value": "", "title": "Open Project?:"},
               {"value": "", "title": "Only Content?:"},
               current_directory
               ]
    try:
        creator(current_directory,
                basic['src']['child']['contexts']['child']['@context_name']['child']['application']['child'], in_data,
                False, False)
    except Exception as e:
        print(e.args)
        print("Can't create the use case...")
    try:
        file_writer(join_path(initial_dir, "src/di.py"), adds.get("use-cases").get("code"), in_data)
    except:
        print("Can't update dependencies file... Not Found!")
    print(f"\nUseCase with name: {name} created successfully!\n")


def add_config(db):
    print("Add database configuration...")
    di_path = "./src/di.py"
    codes = adds.get("di.py").get("code")
    file_writer(di_path, codes, None)
    print(
        "Execute: \n\n\tvirtualenv venv\n\t./venv/Scripts/activate\n\tpip install -r requirements.txt\n\tConfigure environment variables\n\tpython ./src/local_deploy.py")


def file_writer(di_path: str, codes: dict, data: Optional[List[Any]]):
    print("Searching for dependencies file...")
    try:
        with open(di_path, "r+", encoding="utf-8") as f:
            lines = f.readlines()
            imports_to_add = []
            for line_toad in codes["imports"]:
                to_add = True
                for line in lines:
                    if line.strip("\n\r\t") == line_toad.strip("\n\r\t"):
                        to_add = False
                        break
                if to_add is True:
                    imports_to_add.append(place_holders(line_toad, data))
            final_lines = [place_holders(line, data) for line in codes.get("blocks")]
            index = get_last_import(lines)
            old1 = lines[:index]
            old = lines[index + 1:]
            f.seek(0)
            f.truncate(0)
            f.writelines(old1)
            f.writelines(imports_to_add)
            f.writelines(old)
            f.writelines(final_lines)
        print("Configuration added into di.py...")
    except Exception as e:
        logging.exception(e)
