package data.scripts.hullmods;

import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.BaseHullMod;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.ShipAPI.HullSize;
import com.fs.starfarer.api.combat.ShipVariantAPI;
import com.fs.starfarer.api.combat.WeaponAPI;
import com.fs.starfarer.api.fleet.FleetMemberAPI;
import com.fs.starfarer.api.impl.campaign.ids.Stats;
import com.fs.starfarer.api.impl.campaign.ids.Tags;
import com.fs.starfarer.api.impl.hullmods.CompromisedStructure;
import com.fs.starfarer.api.loading.HullModSpecAPI;
import com.fs.starfarer.api.ui.LabelAPI;
import com.fs.starfarer.api.ui.TooltipMakerAPI;
import com.fs.starfarer.api.util.Misc;
import data.scripts.everyframe.II_BlockedHullmodDisplayScript;
import data.scripts.everyframe.II_TitanPlugin;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class II_TitanBombardment extends BaseHullMod {

    public static final float OBLITERATION_CR_PENALTY = 0.6f;

    public static final float GROUND_BONUS = 250;
    public static final float BOMBARD_BONUS = 3000;
    public static final float OBLITERATION_POWER = 3000;

    private static final float PARA_PAD = 10f;
    private static final String BOMBARD_BONUS_ID = "ii_titanbombardmentbonus";
    private static final String OBLITERATION_POWER_ID = "ii_titanobliterationpower";

    private static final Set<String> BLOCKED_HULLMODS = new HashSet<>(1);

    static {
        BLOCKED_HULLMODS.add("efficiency_overhaul");
    }

    public static float getCRPenalty(ShipVariantAPI variant) {
        float scale = 1f;

        Collection<String> hullMods = variant.getHullMods();
        for (String hullMod : hullMods) {
            HullModSpecAPI modSpec = Global.getSettings().getHullModSpec(hullMod);
            if (modSpec.hasTag(Tags.HULLMOD_DMOD)) {
                scale /= CompromisedStructure.DEPLOYMENT_COST_MULT;
            }
        }

        return scale * II_TitanPlugin.CR_PENALTY;
    }

    public static float getObliterationCRPenalty(ShipVariantAPI variant) {
        float scale = 1f;

        Collection<String> hullMods = variant.getHullMods();
        for (String hullMod : hullMods) {
            HullModSpecAPI modSpec = Global.getSettings().getHullModSpec(hullMod);
            if (modSpec.hasTag(Tags.HULLMOD_DMOD)) {
                scale /= CompromisedStructure.DEPLOYMENT_COST_MULT;
            }
        }

        return scale * OBLITERATION_CR_PENALTY;
    }

    @Override
    public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
        stats.getDynamic().getMod(Stats.FLEET_GROUND_SUPPORT).modifyFlat(id, GROUND_BONUS);
    }

    @Override
    public void advanceInCampaign(FleetMemberAPI member, float amount) {
        if (member.getRepairTracker().getBaseCR() >= getCRPenalty(member.getVariant())) {
            member.getStats().getDynamic().getMod(Stats.FLEET_BOMBARD_COST_REDUCTION).modifyFlat(BOMBARD_BONUS_ID, BOMBARD_BONUS);
        } else {
            member.getStats().getDynamic().getMod(Stats.FLEET_BOMBARD_COST_REDUCTION).unmodify(BOMBARD_BONUS_ID);
        }
        if (member.getRepairTracker().getBaseCR() >= getObliterationCRPenalty(member.getVariant())) {
            member.getStats().getDynamic().getMod("ii_obliteration_power").modifyFlat(OBLITERATION_POWER_ID, OBLITERATION_POWER);
        } else {
            member.getStats().getDynamic().getMod("ii_obliteration_power").unmodify(OBLITERATION_POWER_ID);
        }
    }

    @Override
    public void advanceInCombat(ShipAPI ship, float amount) {
        updateDecoWeapons(ship);
    }

    @Override
    public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
        for (String tmp : BLOCKED_HULLMODS) {
            if (ship.getVariant().getHullMods().contains(tmp)) {
                ship.getVariant().removeMod(tmp);
                II_BlockedHullmodDisplayScript.showBlocked(ship);
            }
        }

        updateDecoWeapons(ship);
    }

    @Override
    public String getDescriptionParam(int index, HullSize hullSize, ShipAPI ship) {
        switch (index) {
            case 0:
                return "" + (int) GROUND_BONUS;
            case 1:
                return "" + (int) BOMBARD_BONUS;
            case 2:
                return "" + (int) Math.round(getCRPenalty(ship.getVariant()) * 100f) + "%";
            case 3:
                return "" + (int) Math.round(getObliterationCRPenalty(ship.getVariant()) * 100f) + "%";
            default:
                break;
        }
        return null;
    }

    @Override
    public void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) {
        if (getCRPenalty(ship.getVariant()) > II_TitanPlugin.CR_PENALTY) {
            float penaltyScalePct = 100f * ((getCRPenalty(ship.getVariant()) / II_TitanPlugin.CR_PENALTY) - 1f);
            LabelAPI label = tooltip.addPara("CR cost is penalized by %s due to hull defects.", PARA_PAD, Misc.getNegativeHighlightColor(), "" + Math.round(penaltyScalePct) + "%");
        }

        float CR = ship.getCurrentCR();
        if (ship.getFleetMember() != null) {
            CR = ship.getFleetMember().getRepairTracker().getBaseCR();
        }
        if (CR < getCRPenalty(ship.getVariant())) {
            LabelAPI label = tooltip.addPara("Insufficient CR for Titan deployment!", Misc.getNegativeHighlightColor(), PARA_PAD);
        }
        if (CR < getObliterationCRPenalty(ship.getVariant())) {
            LabelAPI label = tooltip.addPara("Insufficient CR for market obliteration!", Misc.getNegativeHighlightColor(), PARA_PAD);
        }

        HullModSpecAPI efficiencyOverhaul = Global.getSettings().getHullModSpec("efficiency_overhaul");
        if (efficiencyOverhaul != null) {
            LabelAPI label = tooltip.addPara("Incompatible with " + efficiencyOverhaul.getDisplayName() + ".", PARA_PAD);
            label.setHighlightColor(Misc.getNegativeHighlightColor());
            label.setHighlight(efficiencyOverhaul.getDisplayName());
        }
    }

    private void updateDecoWeapons(ShipAPI ship) {
        boolean armor = ship.getVariant().hasHullMod(II_BasePackage.ARMOR_PACKAGE);
        boolean targeting = ship.getVariant().hasHullMod(II_BasePackage.TARGETING_PACKAGE);
        boolean elite = ship.getVariant().hasHullMod(II_BasePackage.ELITE_PACKAGE);

        if (!armor && !targeting && !elite) {
            boolean titanWeaponHasAmmo = false;
            for (WeaponAPI weapon : ship.getAllWeapons()) {
                if (weapon.getId().contentEquals("ii_titan_w")) {
                    if (weapon.getAmmo() > 0) {
                        titanWeaponHasAmmo = true;
                    }
                    break;
                }
            }
            float CR = ship.getCurrentCR();
            if (ship.getFleetMember() != null) {
                CR = ship.getFleetMember().getRepairTracker().getBaseCR();
            }
            if (CR < getCRPenalty(ship.getVariant())) {
                titanWeaponHasAmmo = false;
            }

            for (WeaponAPI weapon : ship.getAllWeapons()) {
                int frame;

                switch (weapon.getId()) {
                    case "ii_titan_deco":
                        if (!titanWeaponHasAmmo) {
                            frame = 4;
                        } else {
                            frame = 0;
                        }
                        break;
                    case "ii_titan_armor_door":
                        frame = 0;
                        break;
                    case "ii_titan_targeting_door":
                        frame = 0;
                        break;
                    default:
                        continue;
                }

                weapon.getAnimation().setFrame(frame);
            }
        }
    }
}
