import os
import math
from LL_API import LL_API
from Button import Button
from WindowDisplay import the_header
from WindowDisplay import list_window
from Employee import Employee
from Object_Branch_UI import Object_Branch_UI
from Plane_UI import Plane_UI

INDEX_OF_NAME_IN_EMPLOYEE = 0
WIDTH = 120

class UI_API():

    def header(name, right="|B| Back"):
        the_header(WIDTH, "#", left = "Nan Air", middle = name, right = right )

    def display_list(header_row, data_list):
        list_window(WIDTH, "#", header_row, data_list)

    def display_buttons(buttons):
        print("#"*WIDTH)
        print("## ", end="")
        for button in buttons:
            print(button, end=" ## ")
        print()
        print("#"*WIDTH)

    #Plane branch 1
    def plane_list():
        pass

    def plane_info():
        pass

    def plane_edit():
        pass

    def plane_add():
        pass

    #Destination branch 2 ================
    def destination_list():
        pass

    def destination_info():
        pass

    def destination_edit():
        pass

    def destination_add():
        pass

    #Employee branch 3    ================
    #Main employee window ---------------- XC
    def employee_list():
        items_per_page = 9
        max_pages = 1
        page = 1
        search = None
        search_filter = "All"
        employee_list = []

        def set_search():
            nonlocal search
            search = input("Search keyword: ")

        def page_up():
            nonlocal page
            nonlocal max_pages
            if page < max_pages:
                page += 1

        def page_down():
            nonlocal page
            if page > 1:
                page -= 1

        def set_filter_pilot():
            nonlocal search_filter
            search_filter = "Pilot"

        def set_filter_flight_attendant():
            nonlocal search_filter
            search_filter = "Cabincrew"

        def set_all():
            nonlocal search_filter
            search_filter = "All"

        # Setting all available buttons in employee list screen and mapping corresponding functions
        buttons = [Button("Add employee", "e", UI_API.employee_add),
                   Button("Search", "s", set_search),
                   Button("Page up", "u", page_up),
                   Button("Page down", "d", page_down),
                   Button("All", "a", set_all),
                   Button("Pilots", "p", set_filter_pilot),
                   Button("Flight attendants", "f", set_filter_flight_attendant)]

        def get_employee_list(page, search_filter, search=None):
            nonlocal items_per_page
            nonlocal max_pages
            max_pages = math.ceil(LL_API.get_number_of_employees(search_filter, search)/items_per_page)
            return LL_API.get_employee_list(page, search_filter, search, items_per_page)

        def display():
            nonlocal page
            nonlocal max_pages
            nonlocal search
            nonlocal employee_list
            nonlocal buttons
            # Displaying window
            UI_API.header("Employee")
            string_list = []
            for employee in employee_list:
                string_list += [str(employee).split("#")]
            header = ["name", "job",  "email"]
            UI_API.display_list(header, string_list)
            UI_API.display_buttons(buttons)
            print("Page: ", page, "/", max_pages)
            print("Search: ", search)

        def get_input():
            return input("Choice: ").lower()

        def main():
            while True:
                nonlocal employee_list
                employee_list
                employee_list = get_employee_list(page, search_filter, search)
                os.system("cls")
                display()
                user_input = get_input()

                # If user pressed the back key
                if user_input == "b":
                    return 0

                # Checking if user selected info screen
                if user_input.isdigit():
                    if 1 <= int(user_input) <= len(employee_list):
                        employee = employee_list[int(user_input)-1]
                        UI_API.employee_info(employee)

                # Checking if user selected any button
                for button in buttons:
                    if user_input == button.trigger_key:
                        button.mapping_func()
        main()

    #Employee info window ---------------- XC
    def employee_info(employee):
        # Setting all available buttons in employee info screen and mapping corresponding functions
        buttons = [Button("Edit Employee", "e", UI_API.employee_edit),
                   Button("Employee history", "h", UI_API.employee_history)]

        def display():
            # Displaying screen for argument employee
            nonlocal buttons
            nonlocal employee
            UI_API.header(employee.name + " info window")
            UI_API.display_buttons(buttons)
            for info in employee.detailed_info():
                print(info[0], info[1])

        def get_input():
            return input("Choice: ").lower()

        def main():
            nonlocal employee
            while True:
                os.system("cls")
                display()
                user_input = get_input()
                # If user pressed the back key
                if user_input == "b":
                    return 0

                # If user selected edit button update employee info when user comes back
                if user_input == "e":
                    new_employee = UI_API.employee_edit(employee)
                    # If edit employee is canceled the function returns zero
                    if new_employee != 0:
                        employee = new_employee
                # Else if user selected any buttons
                else:
                    for button in buttons:
                        if user_input == button.trigger_key:
                            button.mapping_func(employee)

        main()

    #Employee edit window ---------------- XC
    def employee_edit(employee):
        running = True
        new_employee = None
        edit_index = 0
        edited_info = []

        def up():
            nonlocal edit_index
            if edit_index > 0:
                edit_index -= 1

        def down():
            nonlocal edit_index
            nonlocal edited_info
            if edit_index < len(edited_info) - 1:
                edit_index += 1

        def edit_info(user_input):
            nonlocal edit_index
            nonlocal edited_info
            edited_info[edit_index][1] = user_input

        def confirm_employee():
            nonlocal edited_info
            nonlocal new_employee
            new_employee = Employee(edited_info[0][1],
                                    edited_info[1][1],
                                    edited_info[2][1],
                                    edited_info[3][1],
                                    edited_info[4][1],
                                    edited_info[5][1],
                                    edited_info[6][1],
                                    flight_history=[])

            # Making sure python creates a new list
            all_employee_list = [] + LL_API.get_employee_list()

            # Finding employee in that list and replacing it
            for i, employee_i in enumerate(all_employee_list):
                if employee_i == employee:
                    all_employee_list[i] = new_employee

            # Writing new list
            LL_API.write_employee_list(all_employee_list)

            # Killing function
            nonlocal running
            running = False

        # Setting all available buttons in employee edit screen and mapping corresponding functions
        buttons = [Button("Confirm", "c", confirm_employee),
                   Button("Up", "u", up),
                   Button("Down", "d", down)]

        def display():
            # Displaying window
            nonlocal buttons
            nonlocal edited_info
            nonlocal edit_index
            UI_API.header("Edit " + edited_info[INDEX_OF_NAME_IN_EMPLOYEE][1])
            UI_API.display_buttons(buttons)
            for i, info in enumerate(edited_info):
                if i == edit_index:
                    print(info[0], info[1], "<---")
                else:
                    print(info[0], info[1])

        def get_input():
            return input("Choice: ").lower()

        def main():
            nonlocal employee
            nonlocal edited_info
            # Appending info so it creates a independent object from employee
            edited_info += employee.detailed_info()

            while running:
                key_hit = False
                os.system("cls")
                display()
                user_input = get_input()

                # If back key was pressed
                if user_input == "b":
                    return 0

                # If buttons was pressed
                for button in buttons:
                    if user_input == button.trigger_key:
                        key_hit = True
                        button.mapping_func()

                # Else edit the current info with argument provided by user
                if not key_hit:
                    edit_info(user_input)

        main()
        return new_employee

    # Employee add window ---------------- XC
    def employee_add():
        running = True
        edit_index = 0
        # Creating new empty user
        new_employee_data = Employee(name="", ssn="", job="", address="", home_nr="",
                                     mobile_nr="", email="", flight_history=[])
        # Turning the new empty user to string list of data to manipulate
        new_employee_data = new_employee_data.detailed_info()

        def up():
            nonlocal edit_index
            if edit_index > 0:
                edit_index -= 1

        def down():
            nonlocal edit_index
            nonlocal new_employee_data
            if edit_index < len(new_employee_data) - 1:
                edit_index += 1

        def edit_info(user_input):
            nonlocal new_employee_data
            nonlocal edit_index
            new_employee_data[edit_index][1] = user_input
            # When user enters data automatically enter next field
            down()

        def confirm_employee():
            nonlocal new_employee_data
            # Turning the string list back to employee object
            new_employee = [Employee(new_employee_data[0][1],
                                     new_employee_data[1][1],
                                     new_employee_data[2][1],
                                     new_employee_data[3][1],
                                     new_employee_data[4][1],
                                     new_employee_data[5][1],
                                     new_employee_data[6][1],
                                     flight_history=[])]
            LL_API.append_employee_list(new_employee)
            nonlocal running
            running = False

        buttons = [Button("Confirm", "c", confirm_employee),
                   Button("Up", "u", up),
                   Button("Down", "d", down)]

        def display():
            # Displaying window
            nonlocal new_employee_data
            nonlocal edit_index
            nonlocal buttons
            UI_API.header("New employee")
            UI_API.display_buttons(buttons)
            for i, info in enumerate(new_employee_data):
                if i == edit_index:
                    print(info[0], info[1], "<---")
                else:
                    print(info[0], info[1])

        def get_input():
            return input("Choice: ").lower()

        def main():
            while running:
                key_hit = False
                os.system("cls")
                display()
                user_input = get_input()

                # If user presses back button
                if user_input == "b":
                    return 0

                # If user presses other buttons
                for button in buttons:
                    if user_input == button.trigger_key:
                        key_hit = True
                        button.mapping_func()

                # Else write user input to current info
                if not key_hit:
                    edit_info(user_input)

        main()

    #Employee history window -------------
    def employee_history():
        pass

    #Flight branch 4 ====================
    def flight_list():
        pass

    def flight_info():
        pass

    #Voyage branch 5 ===================
    def voyage_list():
        pass

    def voyage_info():
        pass

    def voyage_edit():
        pass

    def voyage_add():
        pass
    #Main_Menu ========================
    def main_menu():
        buttons = [Button("Employees", "e", UI_API.employee_list),
                   Button("Planes", "p", Plane_UI.object_list),
                   Button("Voyages", "v", UI_API.voyage_list),
                   Button("Flights", "f", UI_API.flight_list),
                   Button("Destinations", "d", UI_API.destination_list),
                   Button("Object", "o", Object_Branch_UI.object_list)]

        def display():
            UI_API.header("Main Menu", right="|Q| Quit")
            UI_API.display_buttons(buttons)

        def get_input():
            return input("Choice: ").lower()

        def main():
            while True:
                os.system("cls")
                display()
                user_input = get_input()
                if user_input == "q":
                    return 0
                for button in buttons:
                    if user_input == button.trigger_key:
                        button.mapping_func()
        main()


UI_API.main_menu()