package classicMod.content;

import arc.Core;
import arc.func.Boolf;
import arc.graphics.Color;
import arc.graphics.g2d.TextureRegion;
import arc.math.Mathf;
import arc.scene.ui.layout.Table;
import arc.struct.*;
import arc.util.*;
import mindustry.ctype.UnlockableContent;
import mindustry.entities.bullet.BulletType;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.Block;
import mindustry.world.blocks.defense.turrets.Turret;
import mindustry.world.meta.*;
import mindustry.core.*;

import static mindustry.Vars.*;
import static mindustry.type.ItemStack.with;
import static mindustry.world.meta.StatValues.*;

public class ExtendedStat {
    public static final Stat
            StatusOutput = new Stat("status-give", StatCat.function),
            empDuration = new Stat("emp-duration", StatCat.function),
            cooldown = new Stat("cooldown", StatCat.function),

            fuel = new Stat("fuel", StatCat.crafting),
            inbetweenTeleport = new Stat("inbetween-teleport", StatCat.items),
            burnTime = new Stat("burn-time", StatCat.crafting),
            canEMP = new Stat("can-emp", StatCat.function),
            launchSector = new Stat("launch-sector", StatCat.function),
            itemsMovedBase = new Stat("itemsmoved-base", StatCat.items),
            itemsMovedBoost = new Stat("itemsmoved-boost", StatCat.optional),
            tierLevel = new Stat("unit-level")
    ;

    public static StatValue drillablesStack(float drillTime, int outputAmount, ObjectFloatMap<Item> multipliers, Boolf<Block> filter){
        return table -> {
            table.row();
            table.table(c -> {
                int i = 0;
                for(Block block : content.blocks()){
                    if(!filter.get(block)) continue;

                    c.table(Styles.grayPanel, b -> {
                        b.image(block.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit);
                        b.table(info -> {
                            info.left();
                            info.add(block.localizedName).left().row();
                            info.add(block.itemDrop.emoji()).left();
                        }).grow();
                        if(multipliers != null){
                            b.add(Strings.autoFixed(drillTime, 2) + StatUnit.perSecond.localized())
                                    .right().pad(10f).padRight(15f).color(Color.lightGray);
                        }
                    }).growX().pad(5);
                    if(++i % 2 == 0) c.row();
                }
            }).growX().colspan(table.getColumns());
        };
    }

    public static StatValue squaredRange(float value, StatUnit unit){
        return table -> {
            String fixed = fixValue(value);
            table.add(fixed);
            table.add((unit.space ? " " : "") + unit.localized());
        };
    }

    public static StatValue ammo(ObjectMap<ItemStack, BulletType> map){
        return ammo(map, 0);
    }

    //for AmmoListValue
    private static void sep(Table table, String text){
        table.row();
        table.add(text);
    }

    //for AmmoListValue
    private static String ammoStat(float val){
        return (val > 0 ? "[stat]+" : "[negstat]") + Strings.autoFixed(val, 1);
    }

    public static StatValue ammo(ObjectMap<ItemStack, BulletType> map, int indent) {
        return table -> {

            table.row();

            var orderedKeys = map.keys().toSeq();
            orderedKeys.sort();

            for(var t : orderedKeys){
                boolean compact = indent > 0;

                BulletType type = map.get(t);

                table.table(Styles.grayPanel, bt -> {
                    bt.left().top().defaults().padRight(3).left();
                    bt.table(title -> {
                        float padOffset = 10;
                        //title.add(new ItemsDisplay()).padRight(4).right();
                        title.image(t.item.uiIcon).size(3 * 8).padRight(4).right().scaling(Scaling.fit).top();
                        title.add(t.item.localizedName).padRight(4 + t.amount > 99 ? padOffset + 4 : padOffset + 0).left().center();
                        //title.add(String.valueOf(t.amount));
                    });

                    bt.row();

                    if(type.damage > 0 && (type.collides || type.splashDamage <= 0)){
                        if(type.continuousDamage() > 0){
                            bt.add(Core.bundle.format("bullet.damage", type.continuousDamage()) + StatUnit.perSecond.localized());
                        }else{
                            bt.add(Core.bundle.format("bullet.damage", type.damage));
                        }
                    }

                    if(type.buildingDamageMultiplier != 1){
                        int val = (int)(type.buildingDamageMultiplier * 100 - 100);
                        sep(bt, Core.bundle.format("bullet.buildingdamage", ammoStat(val)));
                    }

                    if(type.rangeChange != 0 && !compact){
                        sep(bt, Core.bundle.format("bullet.range", ammoStat(type.rangeChange / tilesize)));
                    }

                    if(type.splashDamage > 0){
                        sep(bt, Core.bundle.format("bullet.splashdamage", (int)type.splashDamage, Strings.fixed(type.splashDamageRadius / tilesize, 1)));
                    }

                    if(!compact && !Mathf.equal(type.ammoMultiplier, 1f) && type.displayAmmoMultiplier){
                        sep(bt, Core.bundle.format("bullet.multiplier", (int)type.ammoMultiplier));
                    }
                }).padLeft(indent * 5).padTop(5).padBottom(compact ? 0 : 5).growX().margin(compact ? 0 : 10);

                table.row();
            }
        };
    }

    public static boolean hasItem(Item item, Seq<ItemStack> stacks){
        boolean yes = false;
        for (ItemStack itemStack : stacks)
        {
            yes = itemStack.item == item;
            if (yes) break;
        }
        return yes;
    }

    public static StatValue items(float timePeriod, Seq<ItemStack> stacks){
        return table -> {
            Seq<Item> list = content.items().select(i -> hasItem(i, stacks) && i.unlockedNow() && !i.isHidden());

            for(int i = 0; i < list.size; i++){
                table.row();
                int finalI = i;
                table.table(Styles.grayPanel, bt -> {
                    Item item = list.get(finalI);
                    bt.table(title -> title.left().add(timePeriod <= 0 ? displayItem(item) : displayItem(item, 1, timePeriod, true)).padRight(5)).grow().left();
                    bt.table(stata -> stata.right().add(Core.bundle.format("stat.efficiency", (item.flammability) * 100))).grow().right();
                }).padLeft(5).padTop(5).padBottom(5).growX().margin(10);

                table.row();
            }
        };
    }
}
