// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
//      Magicbane Emulator Project © 2013 - 2022
//                www.magicbane.com

package engine.net.client.handlers;

import engine.Enum;
import engine.Enum.DispatchChannel;
import engine.exception.MsgSendException;
import engine.gameManager.DbManager;
import engine.gameManager.SessionManager;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.RepairMsg;
import engine.net.client.msg.UpdateGoldMsg;
import engine.objects.*;
import engine.server.MBServerStatics;

public class RepairMsgHandler extends AbstractClientMsgHandler {

    public RepairMsgHandler() {
        super(RepairMsg.class);
    }

    @Override
    protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {

        PlayerCharacter player = SessionManager.getPlayerCharacter(origin);
        Dispatch dispatch;

        RepairMsg repairMsg = (RepairMsg) baseMsg;

        if (player == null)
            return true;

        NPC npc = NPC.getFromCache(repairMsg.getNPCID());

        if (npc == null)
            return true;

        if (repairMsg.getMsgType() == 1) { //Open RepairObject Window

            if (player.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
                ErrorPopupMsg.sendErrorPopup(player, 14);
                return true;
            }

            //send open repair window response

            repairMsg.setRepairWindowAck(npc);
            dispatch = Dispatch.borrow(player, repairMsg);
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);

        } else if (repairMsg.getMsgType() == 0) { //Request RepairObject

            CharacterItemManager itemMan = player.charItemManager;

            if (itemMan == null)
                return true;

            Item gold = itemMan.getGoldInventory();

            if (gold == null)
                return true;

            Item toRepair = Item.getFromCache(repairMsg.getItemID());

            if (toRepair == null)
                return true;

            if (toRepair.name.toUpperCase().contains("GLASS"))
                return true;

            //make sure item is in player's inventory or equipment

            if (!itemMan.inventoryContains(toRepair) && !itemMan.equippedContains(toRepair))
                return true;

            //make sure item is damaged and not destroyed

            short dur = (short) toRepair.combat_health_current;
            short max = (short) toRepair.template.item_health_full;

            //account for durability modifications

            float durMod = toRepair.getBonusPercent(Enum.ModType.Durability, Enum.SourceType.NONE);
            max *= (1 + (durMod * 0.01f));

            if (dur >= max || dur < 1) {
                //redundancy message to clear item from window in client
                toRepair.setCombat_health_current(max);
                repairMsg.setupRepairAck(max - dur);
                dispatch = Dispatch.borrow(player, repairMsg);
                DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
                return true;
            }

            //TODO get cost to repair
            int cost = (int) ((max - dur) * 80.1);
            Building building = (!npc.isStatic()) ? npc.getBuilding() : null;

            if (building != null)
                if (building.getProtectionState().equals(Enum.ProtectionState.NPC))
                    building = null;


            if (building != null && (building.getStrongboxValue() + cost) > building.getMaxGold()) {
                ErrorPopupMsg.sendErrorPopup(player, 206);
                return true;
            }

            if (player.charItemManager.getGoldInventory().getNumOfItems() - cost < 0)
                return true;

            if (player.charItemManager.getGoldInventory().getNumOfItems() - cost > MBServerStatics.PLAYER_GOLD_LIMIT)
                return true;

            if (!itemMan.buyFromNPC(building, cost, cost)) {
                ErrorPopupMsg.sendErrorPopup(player, 128);
                return true;
            }

            //update player's goldItem count

            UpdateGoldMsg ugm = new UpdateGoldMsg(player);
            ugm.configure();

            dispatch = Dispatch.borrow(player, ugm);
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);

            //update durability to database

            if (!DbManager.ItemQueries.SET_DURABILITY(toRepair, max))
                return true;

            //repair the item

            toRepair.setCombat_health_current(max);

            //send repair msg

            repairMsg.setupRepairAck(max - dur);
            dispatch = Dispatch.borrow(player, repairMsg);
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
        }

        return true;
    }
}