import * as NativeUI from '../libs/NativeUI';
import InputHelper from '../inputhelper';
import moneyFormat from '../moneyformat';

const Menu = NativeUI.Menu;
const UIMenuItem = NativeUI.UIMenuItem;
const UIMenuListItem = NativeUI.UIMenuListItem;
const UIMenuCheckboxItem = NativeUI.UIMenuCheckboxItem;
const BadgeStyle = NativeUI.BadgeStyle;
const Point = NativeUI.Point;
const ItemsCollection = NativeUI.ItemsCollection;
const Color = NativeUI.Color;
let screenRes = mp.game.graphics.getScreenResolution(0, 0);
import { getStreetName, getZoneName } from '../streetnames';

export default function (globalData: IGlobalData) {

    var menuClose = false;

    var accountItem = new UIMenuItem("Account", "Account Informationen");

    var serviceItem = new UIMenuItem("Service rufen", "Rufe einen Dienstleister an");

    var factionItem = new UIMenuItem("Fraktion", "Fraktionsfahrzeug finden");

    var factionleaderItem = new UIMenuItem("Fraktion", "Verwalte deine Fraktion");

    var groupItem = new UIMenuItem("Gruppe", "Verwalte deine Gruppe");

    var paycheckItem = new UIMenuItem("Gehaltsscheck", "Schaue dir deinen Verdienst der letzten Stunde an");

    var licenseItem = new UIMenuItem("Lizenzen", "Lizenzen Informationen");

    var vehiclesItem = new UIMenuItem("Fahrzeuge", "Zeige deine Fahrzeuge an");

    var HouseItem = new UIMenuItem("Haus", "Finde dein Haus");

    var ticketItem = new UIMenuItem("Strafticket", "Strafticket annehmen/ablehnen");

    var payName: string;

    var groupRank = null;

    mp.events.add("SERVER:InteractionMenu_OpenMenu", (accountDataJson: string, factionleader: string, faction: string, group: string, factionInvite: boolean, groupInvite: boolean, ticket_boolean: boolean, ticket_amount, house: boolean) => {


        var accountData: AccountData = JSON.parse(accountDataJson);
        //var ticket_amount = JSON.parse(ticket_amountJson);

        var menu = getInteractionMenu();

        var serviceMenu = getServicesMenu(menu);
        menu.AddItem(serviceItem);
        menu.BindMenuToItem(serviceMenu, serviceItem);

        menu.AddItem(accountItem);
        menu.BindMenuToItem(getAccountMenu(accountData), accountItem);

        menu.AddItem(licenseItem);
        menu.BindMenuToItem(getLicenseMenu(accountData, accountData.licenses, menu), licenseItem);

        groupRank = accountData.groupRank;

        var vehicles = accountData.vehicles;
        if (vehicles.length > 0) {
            menu.AddItem(vehiclesItem);
            menu.BindMenuToItem(getVehiclesMenu(vehicles, "CLIENT:InteractionMenu_PlayerVehicleInteraction", true, menu), vehiclesItem);
        }

        if (faction && !factionleader) {
            factionItem.SetRightLabel(faction);
            menu.AddItem(factionItem);
            menu.BindMenuToItem(getFactionMenu(faction, accountData.factionVehicles, accountData.stateFaction, menu), factionItem);
        }
        if (faction && factionleader) {
            factionleaderItem.SetRightLabel(factionleader);
            menu.AddItem(factionleaderItem);
            menu.BindMenuToItem(getFactionLeaderMenu(faction, accountData.factionVehicles, accountData.stateFaction, menu), factionleaderItem);
        }

        if (group) {
            groupItem.SetRightLabel(group);
            menu.AddItem(groupItem);
            menu.BindMenuToItem(getGroupMenu(group, menu), groupItem);
        }
            menu.AddItem(HouseItem);

        
       

        if (accountData.paycheck) {
            var p = accountData.paycheck;
            var paycheckMenu = new Menu("Gehaltsscheck", "Dein Verdienst der letzten Stunde", new Point(0, screenRes.y / 3), null, null);
            paycheckMenu.Visible = false;

            var item: NativeUI.UIMenuItem = new UIMenuItem("Lohn");
            item.SetRightLabel("~g~+ $" + moneyFormat(p.wage));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Sonstige Einkünfte");
            item.SetRightLabel("~g~+ $" + moneyFormat(Number(p.otheramount.toFixed(2))));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Finanzhilfe");
            item.SetRightLabel("~g~+ $" + moneyFormat(Number(p.financialHelp.toFixed(2))));
            paycheckMenu.AddItem(item);

            if (p.factionMoney) {
                item = new UIMenuItem("Fraktionsgeld");
                item.SetRightLabel("~g~+ $" + moneyFormat(Number(p.factionMoney.toFixed(2))));
                paycheckMenu.AddItem(item);
            }

            item = new UIMenuItem("Fahrzeugsteuer");
            item.SetRightLabel("~r~- $" + moneyFormat(Number(p.vehicleTaxation.toFixed(2))));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Grundsteuer");
            item.SetRightLabel("~r~- $" + moneyFormat(Number(p.propertyTaxation.toFixed(2))));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Mietkosten");
            item.SetRightLabel("~r~- $" + moneyFormat(Number(p.rentalFees.toFixed(2))));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Krankenkasse");
            item.SetRightLabel("~r~- $" + moneyFormat(Number(p.healthInsurance.toFixed(2))));
            paycheckMenu.AddItem(item);

            item = new UIMenuItem("Einkommensteuer");

            item.SetRightLabel(moneyFormat(Number((p.financialInterest * 100).toFixed(3))) + "%");
            paycheckMenu.AddItem(item);

            menu.AddItem(paycheckItem);
            menu.BindMenuToItem(paycheckMenu, paycheckItem);
        }

        var payItem = new UIMenuItem("Geld geben");
        menu.AddItem(payItem);

        var nextPaydayItem = new UIMenuItem("Nächster PayDay");
        nextPaydayItem.SetRightLabel(`${accountData.nextPayday} Minuten`);
        menu.AddItem(nextPaydayItem);

        if (ticket_boolean == true) {
            menu.AddItem(ticketItem);
            menu.BindMenuToItem(getTicketMenu(ticket_amount, menu), ticketItem);
        }

        var items: Array<string> = new Array<string>();
        if (factionInvite) items.push("Fraktion");
        if (groupInvite) items.push("Gruppe");
        var acceptItem: NativeUI.UIMenuListItem;

        if (items.length !== 0) {
            acceptItem = new UIMenuListItem("Einladung annehmen", "", new ItemsCollection(items));
            menu.AddItem(acceptItem);
        }

        menu.Open();
        globalData.InMenu = true;
        mp.gui.chat.show(false);
        menu.ItemSelect.on((item: NativeUI.UIMenuItem, index: number) => {
            if (item === acceptItem) {
                mp.events.callRemote("CLIENT:InteractionMenu_AcceptInvite", acceptItem.SelectedValue);
                menu.Close(true);
                globalData.InMenu = false;
            } else if (item === payItem) {
                mp.gui.chat.activate(true);
                mp.gui.cursor.show(true, true);
                var input = new InputHelper("Welchem Spieler möchtest du Geld geben (Name / ID)?", globalData);
                input.show();
                input.getValue(name => {
                    mp.events.call("CLIENT:InteractionMenu_Pay_Name", name);
                    mp.gui.cursor.show(false, false);
                    menu.Close(true);
                    globalData.InMenu = false;
                });
            } else if (item == HouseItem) {
                mp.events.callRemote("CLIENT:InteractionMenu_FindHouse");
                mp.gui.cursor.show(false, false);
                menu.Close(true);
                globalData.InMenu = false;
            }
        });

        menu.MenuClose.on(() => {
            globalData.InMenu = false;
            mp.gui.chat.show(true);
        })
    });

    function getInteractionMenu(): NativeUI.Menu {
        return new Menu("Hauptmenü", "Interaktionen | " + mp.players.local.name, new Point(0, screenRes.y / 3), null, null);
    }

    function getAccountMenu(data: AccountData): NativeUI.Menu {
        var accountMenu = new NativeUI.Menu("Account", mp.players.local.name, new Point(0, screenRes.y / 3), null, null);

        var menuItem = new UIMenuItem("Fraktion");
        menuItem.SetRightLabel(data.faction);
        accountMenu.AddItem(menuItem);

        if (data.faction != "Zivilist") {
            menuItem = new UIMenuItem("Fraktionsrang");
            menuItem.SetRightLabel(data.factionRank);
            accountMenu.AddItem(menuItem);
        }

        menuItem = new UIMenuItem("Job");
        menuItem.SetRightLabel(data.job);
        accountMenu.AddItem(menuItem);

        if (data.group != null) {
            menuItem = new UIMenuItem("Gruppe");
            menuItem.SetRightLabel(data.group);
            accountMenu.AddItem(menuItem);               
            menuItem = new UIMenuItem("Gruppenrang");
            menuItem.SetRightLabel(data.groupRank);
            accountMenu.AddItem(menuItem);
        }

        menuItem = new UIMenuItem("Registrierungsdatum");
        menuItem.SetRightLabel(data.regDate);
        accountMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Spielzeit");
        menuItem.SetRightLabel(data.playTime + "h");
        accountMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Verwarnungen");
        menuItem.SetRightLabel("~r~" + data.userWarn);
        accountMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Adminrang");
        menuItem.SetRightLabel(data.adminLevel);
        accountMenu.AddItem(menuItem);

        accountMenu.Visible = false;
        return accountMenu;
    }

    function getLicenseMenu(accdata: AccountData, data: Licenses, parentMenu: NativeUI.Menu, ): NativeUI.Menu {
        var licenseMenu = new NativeUI.Menu("Lizenzen", mp.players.local.name, new Point(0, screenRes.y / 3), null, null);

        var menuItem = new UIMenuItem("Auto Führerschein");
        if (data.drivingLicenseCar == false) {
            menuItem.SetRightLabel("~r~nicht erhalten");
        } else if (data.drivingLicenseCar == true) {
            menuItem.SetRightLabel("~g~erhalten");
        }
        licenseMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Motorrad Führerschein");
        if (data.drivingLicenseBike == false) {
            menuItem.SetRightLabel("~r~nicht erhalten");
        } else if (data.drivingLicenseBike == true) {
            menuItem.SetRightLabel("~g~erhalten");
        }
        licenseMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Flugschein Flugzeug");
        if (data.flightLicensePlane == false) {
            menuItem.SetRightLabel("~r~nicht erhalten");
        } else if (data.flightLicensePlane == true) {
            menuItem.SetRightLabel("~g~erhalten");
        }
        licenseMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Waffenschein");
        if (data.weaponLicense == false) {
            menuItem.SetRightLabel("~r~nicht erhalten");
        } else if (data.weaponLicense == true) {
            menuItem.SetRightLabel("~g~erhalten");
        }
        licenseMenu.AddItem(menuItem);

        menuItem = new UIMenuItem("Strafpunkte");
        if (accdata.points == 0) {
            menuItem.SetRightLabel("~g~" + accdata.points);
        }
        else if (accdata.points >= 1 && accdata.points <= 5) {
            menuItem.SetRightLabel("~y~" + accdata.points);
        }
        if (accdata.points > 5) {
            menuItem.SetRightLabel("~r~" + accdata.points);
        }
        licenseMenu.AddItem(menuItem);

        var showItem = new UIMenuItem("Lizenzen an Spieler zeigen");
        licenseMenu.AddItem(showItem);

        licenseMenu.Visible = false;

        licenseMenu.ItemSelect.on((item, index) => {
            if (item === showItem) {
                globalData.InMenu = true;
                var input = new InputHelper("Welchen Spieler möchtest du deine Lizenzen zeigen (Name / ID)?", globalData);
                input.show();
                input.getValue(name => {
                    mp.events.callRemote("CLIENT:InteractionMenu_Show", "License", name);
                    parentMenu.Close(true);
                    globalData.InMenu = false;
                });
            }

        });

        return licenseMenu;
    }

    function getFactionMenu(faction: string, vehData: VehicleData[], stateFaction: boolean, parentMenu: NativeUI.Menu): NativeUI.Menu {

        var factionMenu = new NativeUI.Menu("Fraktion", faction, new Point(0, screenRes.y / 3), null, null);
 
     
        factionMenu.Visible = false;

        if (vehData.length > 0) {
            var factionVehicleItem = new UIMenuItem("Fahrzeuge Finden", "Finden");
            factionMenu.AddItem(factionVehicleItem);
            factionMenu.BindMenuToItem(getVehiclesMenuFaction(vehData, "CLIENT:InteractionMenu_FactionVehicleInteraction", !stateFaction, parentMenu), factionVehicleItem);
        }

        return factionMenu;
    }
    function getFactionLeaderMenu(faction: string, vehData: VehicleData[], stateFaction: boolean, parentMenu: NativeUI.Menu): NativeUI.Menu {

        var factionMenu = new NativeUI.Menu("Fraktion", faction, new Point(0, screenRes.y / 3), null, null);

        factionMenu.AddItem(new UIMenuItem("Spieler einladen"));
        factionMenu.AddItem(new UIMenuItem("Spieler rauswerfen"));
        factionMenu.Visible = false;
        mp.gui.chat.show(false);
        if (vehData.length > 0) {
            var factionVehicleItem = new UIMenuItem("Fahrzeuge", "Finden oder Verkaufen");
            factionMenu.AddItem(factionVehicleItem);
            factionMenu.BindMenuToItem(getVehiclesMenu(vehData, "CLIENT:InteractionMenu_FactionVehicleInteraction", !stateFaction, parentMenu), factionVehicleItem);
        }


        factionMenu.ItemSelect.on((item, index) => {
            if (index === 0) { // Inviten
                globalData.InMenu = true;
                var input = new InputHelper("Welchen Spieler möchtest du inviten (Name / ID)?", globalData);
                input.show();
                input.getValue(name => {
                    mp.events.callRemote("CLIENT:InteractionMenu_Invite", "Fraktion", name);
                    factionMenu.Close();
                    globalData.InMenu = false;
                });
            } else if (index === 1) { // Uninviten
                globalData.InMenu == true;
                var input = new InputHelper("Welchen Spieler möchtest du uninviten (Name / ID)?", globalData);
                input.show();
                input.getValue(name => {
                    mp.events.callRemote("CLIENT:InteractionMenu_Uninvite", "Fraktion", name);
                    factionMenu.Close();
                    globalData.InMenu = false;
                });
            }
        });

        return factionMenu;
    }

    function getGroupMenu(group: string, parentMenu: NativeUI.Menu): NativeUI.Menu {
        var groupMenu = new NativeUI.Menu("Gruppe", group, new Point(0, screenRes.y / 3), null, null);
        if (groupRank == "Manager" || groupRank == "Besitzer") groupMenu.AddItem(new UIMenuItem("Spieler einladen"));
        if (groupRank == "Manager" || groupRank == "Besitzer") groupMenu.AddItem(new UIMenuItem("Spieler rauswerfen"));
        //groupMenu.AddItem(new UIMenuItem("Mitglieder anzeigen"));
        if (groupRank == "Besitzer") groupMenu.AddItem(new UIMenuItem("Leiter bestimmen"));
        groupMenu.AddItem(new UIMenuItem("Gruppe verlassen"));
        if (groupRank == "Besitzer") groupMenu.AddItem(new UIMenuItem("~r~Gruppe löschen"));
        groupMenu.Visible = false;
        mp.gui.chat.show(false);
        groupMenu.ItemSelect.on((item, index) => {
            switch (index) {
                case 0: //Spieler inviten
                    globalData.InMenu = true;
                    var input = new InputHelper("Welchen Spieler möchtest du inviten (Name / ID)?", globalData);
                    input.show();
                    input.getValue(name => {
                        mp.events.callRemote("CLIENT:InteractionMenu_Invite", "Gruppe", name);
                        parentMenu.Close();
                        globalData.InMenu = false;
                    });
                    break;

                case 1: //Spieler uninviten
                    globalData.InMenu == true;
                    var input = new InputHelper("Welchen Spieler möchtest du uninviten (Name / ID)?", globalData);
                    input.show();
                    input.getValue(name => {
                        mp.events.callRemote("CLIENT:InteractionMenu_Uninvite", "Gruppe", name);
                        parentMenu.Close();
                        globalData.InMenu = false;
                    });
                    break;

                case 2: //Gruppenmitglieder anzeigen
                    mp.events.callRemote("CLIENT:InteractionMenu_MemberList", "Gruppe");
                    break;

                case 3: //Neuen (zusätzlichen) Gruppenleiter bestimmen
                    globalData.InMenu = true;
                    var input = new InputHelper("Welchen Spieler soll Manager werden (Name)? ", globalData);
                    input.show();
                    input.getValue(name => {
                        mp.events.callRemote("CLIENT:InteractionMenu_MakeLeader", "Gruppe", name);
                        parentMenu.Close();
                        globalData.InMenu = false;
                    });
                    break;

                case 4: //Gruppe verlassen (bestimmt zufällig neuen Leiter)
                    groupMenu.Close();
                    mp.gui.chat.show(true);
                    globalData.InMenu = false;
                    mp.events.callRemote("CLIENT:InteractionMenu_LeaveGroup", "Gruppe");                     
                    break;

                case 5: //Gruppe löschen (als Leiter)
                    groupMenu.Close();
                    mp.gui.chat.show(true);
                    globalData.InMenu = false;
                    mp.events.callRemote("CLIENT:InteractionMenu_DeleteGroup", "Gruppe");
                    break;
            }

        });
        return groupMenu;
    }

    function getServicesMenu(parentMenu: NativeUI.Menu): NativeUI.Menu {
        var servicesMenu = new Menu("Services", "Rufe einen Service", new Point(0, screenRes.y / 3), null, null);
        servicesMenu.AddItem(new UIMenuItem("Taxi rufen", "Rufe ein Taxi zu deiner Position"));
        var saniItem = new UIMenuItem("Sanitäter rufen", "Rufe einen Sanitäter zu deiner Position.");
        servicesMenu.AddItem(saniItem);
        servicesMenu.Visible = false;

        servicesMenu.ItemSelect.on((item, index) => {
            if (index === 0) { // Taxi
                mp.events.callRemote("CLIENT:InteractionMenu_CallService_Taxi", getStreetName(), getZoneName());

            }
            else if (index === 1) { // Sanitäter
                mp.events.callRemote("CLIENT:InteractionMenu_CallService_Sani");

            }
            parentMenu.Close(true);
        });

        return servicesMenu;
    }

    function getVehiclesMenu(vehicles: VehicleData[], eventName: string, allowSell: boolean, parentMenu: NativeUI.Menu): NativeUI.Menu {
        var desc = "Finden";
        if (allowSell) {
            desc += " oder Verkaufen";
        }

        var menu = new Menu("Fahrzeuge", desc, new Point(0, screenRes.y / 3), null, null);

        var items: string[] = ["Finden", "Verkaufen"];

        var collection = new ItemsCollection(items);

        vehicles.forEach(veh => {
            var name: string = mp.game.ui.getLabelText(mp.game.vehicle.getDisplayNameFromVehicleModel(veh.Model));

            var item = new UIMenuListItem(`${veh.Id.toString().padEnd(5)} | ${name}`, "", collection, null, { id: veh.Id });

            menu.AddItem(item);
        });

        menu.ItemSelect.on((item: NativeUI.UIMenuListItem, index: number) => {
            var id = item.Data.id;
            var selection = item.SelectedValue;

            mp.events.callRemote(eventName, id, selection);

            parentMenu.Close(true);
        });

        return menu;
    }
    function getVehiclesMenuFaction(vehicles: VehicleData[], eventName: string, allowSell: boolean, parentMenu: NativeUI.Menu): NativeUI.Menu {
        var desc = "Finden";


        var menu = new Menu("Fahrzeuge", desc, new Point(0, screenRes.y / 3), null, null);

        var items: string[] = ["Finden"];

        var collection = new ItemsCollection(items);

        vehicles.forEach(veh => {
            var name: string = mp.game.ui.getLabelText(mp.game.vehicle.getDisplayNameFromVehicleModel(veh.Model));

            var item = new UIMenuListItem(`${veh.Id.toString().padEnd(5)} | ${name}`, "", collection, null, { id: veh.Id });

            menu.AddItem(item);
        });

        menu.ItemSelect.on((item: NativeUI.UIMenuListItem, index: number) => {
            var id = item.Data.id;
            var selection = item.SelectedValue;

            mp.events.callRemote(eventName, id, selection);

            parentMenu.Close(true);
        });

        return menu;
    }
   
    function getTicketMenu(ticket_amount: number, parentMenu: NativeUI.Menu): NativeUI.Menu {
        var ticketMenu = new NativeUI.Menu("Ticket", `Ticket in Höhe von ${ticket_amount}$`, new Point(0, screenRes.y / 3), null, null);
        ticketMenu.AddItem(new UIMenuItem("Ticket annehmen"));
        ticketMenu.AddItem(new UIMenuItem("Ticket ablehnen"));
        ticketMenu.Visible = false;

        ticketMenu.ItemSelect.on((item, index) => {
            if (index === 0) // Ticket annehmen
            {
                mp.events.callRemote("CLIENT:InteractionMenu_Ticket", "Angenommen", ticket_amount);
                parentMenu.Close(true);
            }
            else if (index === 1) // Ticket ablehnen
            {
                mp.events.callRemote("CLIENT:InteractionMenu_Ticket", "Abgelehnt", ticket_amount);
                parentMenu.Close(true);
            }
        });

        return ticketMenu;
    }
    
    mp.events.add("CLIENT:InteractionMenu_Pay_Name", (name) => {
        payName = name;
        globalData.InMenu = true;
        var input = new InputHelper("Wie viel?", globalData);
        mp.gui.cursor.show(true, true);
        input.show();
        input.getValue(amount => {
            mp.events.callRemote("CLIENT:InteractionMenu_Pay", JSON.stringify(payName), amount);
            mp.gui.cursor.show(false, false);
            globalData.InMenu = false;
        });
    });
}
