package com.yutian.minerwar.game;

import com.io.yutian.pixelliveengine.api.PixelLiveEngineAPI;
import com.io.yutian.pixelliveplugin.PixelLiveAPI;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.math.BlockVector3;
import com.yutian.minerwar.MinerWar;
import com.yutian.minerwar.listener.KeepEntitiesOnDeath;
import com.yutian.minerwar.manager.GameManager;
import com.yutian.minerwar.util.MerchantRecipeUtil;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import tools.BossBarUtil;
import tools.RandomUtil;
import tools.StackUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Game {

    private World world;
    private BossBar bossBar1;
    private BossBar bossBar2;
    private boolean started = false;
    private Villager villagerShop;
    private Location villagerPoint;
    private Region gameRegion;
    private int completeAmount;
    private int completeGoal;
    private int excavateAmount;
    private int excavateGoal;
    private List<BukkitTask> tasks = new ArrayList<>();
    protected List<MerchantRecipe> recipes = new ArrayList<>();
    private final GameManager manager;

    public Game(GameManager gameManager) {
        manager = gameManager;
        world = Bukkit.getWorld("world");
        if (world != null) {
            world.setAutoSave(false);
            world.setGameRule(GameRule.KEEP_INVENTORY,true);
            world.setGameRule(GameRule.MOB_GRIEFING,false);
            world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE,false);
            world.setGameRule(GameRule.DO_WEATHER_CYCLE,false);
            world.setDifficulty(Difficulty.NORMAL);
            world.setTime(2000L);
            gameRegion = new Region(world,new Point(-150,60,-200),new Point(150,120,100));
            initVillagerShop();
            initGoldOreGenerate();
        }
        bossBar1 = Bukkit.createBossBar("今日挑战进度", BarColor.WHITE, BarStyle.SEGMENTED_10);
        bossBar2 = Bukkit.createBossBar("黄金采集进度", BarColor.GREEN, BarStyle.SEGMENTED_20);
        this.completeGoal = manager.getGameGoal();
        this.excavateGoal = manager.getGoldOreGoal();
        tasks.add(Bukkit.getScheduler().runTaskTimer(MinerWar.inst(),this::tickFood,0,30*20L));
    }
    private void updateCompleteGoalBossBar() {
        double d = (double) completeAmount / (double) completeGoal;
        String bossTitle = "§6今日挑战进度: §f"+completeAmount+"/"+completeGoal;
        bossBar1.setTitle(bossTitle);
        BossBarUtil.setBarColor(bossBar1,d);
        BossBarUtil.setBarProgress(bossBar1,d);
    }

    private void updateCompleteGoldGoalBossBar() {
        int cNow = excavateAmount;
        int cMax = excavateGoal;
        double d = (double) cNow / (double) cMax;
        String d2 = String.format("%.2f",d * 100);
        String bossTitle = "§6黄金矿工采集进度: §f"+cNow+"/"+cMax+" §b("+d2+"%)";
        bossBar2.setTitle(bossTitle);
        BossBarUtil.setBarColor(bossBar2,d);
        BossBarUtil.setBarProgress(bossBar2,d);
    }

    public void start() {
        if (started) {
            return;
        }
        this.started = true;
        BukkitTask task = new BukkitRunnable() {
            @Override
            public void run() {
                villagerShop.teleport(villagerPoint);
                updateCompleteGoldGoalBossBar();
                updateCompleteGoalBossBar();
            }
        }.runTaskTimer(MinerWar.inst(),0L,10L);
        tasks.add(task);
        // 启动任务，定期检查时间并切换白天和黑夜
        BukkitTask worldTimeTask = new BukkitRunnable() {
            @Override
            public void run() {
                // 获取当前世界时间
                long currentTime = world.getTime();
                // 每秒加快 2 ticks，使其加速一倍（10 分钟一个昼夜）
                world.setTime(currentTime + 3);
            }
        }.runTaskTimer(MinerWar.inst(),0L,1L);
        tasks.add(worldTimeTask);
    }


    public void stop(){
        villagerShop.remove();
        for (Player player1 : Bukkit.getOnlinePlayers()){
            player1.getInventory().clear();
        }
    }

    public boolean isStarted() {
        return started;
    }

    public void initPlayerData(Player player) {
        player.setArrowCooldown(3600);
        player.setGameMode(GameMode.SURVIVAL);
        player.setAllowFlight(true);
        bossBar1.addPlayer(player);
        bossBar2.addPlayer(player);
        initPlayerBackpack(player);
        Location location = new Location(player.getWorld(),6.5,78.0,-75.5,90,0);
        player.teleport(location);
        refreshHudMessage(player);
    }
    public void refreshHudMessage(Player player){
        PixelLiveEngineAPI.clearHudText();
        List<String> messageHud = new ArrayList<>();
        int deathAmount = KeepEntitiesOnDeath.getDeathsVaule(player);
        messageHud.add("§c§l嘎掉次数: "+ deathAmount+" 次");
        double scale = 0.1;
        if(deathAmount >= 21){
            scale = 0.5;
        }else if(deathAmount >= 16){
            scale = 0.4;
        }else if(deathAmount >= 11){
            scale = 0.3;
        }else if(deathAmount >= 6){
            scale = 0.2;
        }
        messageHud.add("§c§l当前掉率: "+ String.format("%.1f",(scale*100)) +"%");
        PixelLiveEngineAPI.setHudText(messageHud);
    }

    public void initPlayerBackpack(Player player){
        Inventory inv = player.getInventory();
        inv.setItem(0,StackUtil.diamondSword());
        inv.setItem(1,StackUtil.ironPickaxe());
        inv.setItem(2,new ItemStack(Material.WATER_BUCKET,1));
    }

    public void initVillagerShop(){
        Location location = new Location(world,-7,78,-76,-90,0);
        world.getBlockAt(location).setType(Material.SEA_LANTERN);
        villagerPoint = location.add(0.5,1,0.5);
        Villager villager = (Villager) world.spawnEntity(villagerPoint, EntityType.VILLAGER);
        villager.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.0D);
        villager.getAttribute(Attribute.GENERIC_ARMOR).setBaseValue(99999.0);
        villager.getAttribute(Attribute.GENERIC_ARMOR_TOUGHNESS).setBaseValue(99999.0);
        villager.getAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE).setBaseValue(99999.0);
        villager.setInvulnerable(true);
        villager.setGravity(false);
        villager.setProfession(Villager.Profession.CLERIC);
        villager.setVillagerType(Villager.Type.SWAMP);
        villager.setVillagerLevel(5);
        villager.setRecipes(getRecipes());
        villager.setCustomNameVisible(true);
        villager.setCustomName("§e§l商人");
        villager.setCollidable(false);
        villagerShop = villager;
    }

    private List<MerchantRecipe> getRecipes() {
        if(recipes.isEmpty()) {
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(new ItemStack(Material.COOKIE, 1), 1));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(new ItemStack(Material.BREAD, 1), 3));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(new ItemStack(Material.COOKED_BEEF, 1), 5));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(new ItemStack(Material.COOKED_CHICKEN, 1), 7));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(new ItemStack(Material.RABBIT_STEW, 1), 10));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(StackUtil.bloodBag(), 3));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(StackUtil.bigBloodBag(), 9));
            recipes.add(MerchantRecipeUtil.buildMerchantRecipe(StackUtil.extraGradeBloodPack(), 15));
        }
        return recipes;
    }

    public void initGoldOreGenerate(){
        Region region = gameRegion;
        Bukkit.getConsoleSender().sendMessage("[日志 - 矿工战争] 游戏场地:");
        // 清理这个区域中所有的非白名单方块
        for (int y = 70; y <= 120; y++) {
            for (int x = (int) Math.floor(region.getMin().getX()); x <= region.getMax().getX(); x++) {
                for (int z = (int) Math.floor(region.getMin().getZ()); z <= region.getMax().getZ(); z++) {
                    if(z != -76) {
                        Block block = region.getWorld().getBlockAt(x, y, z);
                        if (!block.getType().equals(Material.AIR)) {
                            if (block.getType() == Material.WHITE_WOOL) {
                                if (RandomUtil.getRandomInt(1, 100) >= 70) {
                                    block.setType(Material.GOLD_ORE);
                                } else {
                                    block.setType(Material.COBBLESTONE);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public void tickFood() {
        for (Player player1 : world.getPlayers()) {
            int foodLevel = player1.getFoodLevel();
            player1.setFoodLevel(Math.max(foodLevel - 1, 0));
        }
    }

    public void createRegion(String regionKey, Region region) {
        FileConfiguration config = MinerWar.inst().getConfig();
        ConfigurationSection section = config.createSection(regionKey);
        section.set("world", region.getWorld().getName());
        Point point1 = region.getMin();
        Point point2 = region.getMax();
        ConfigurationSection section1 = section.createSection("min");
        section1.set("x", point1.getX());
        section1.set("y", point1.getY());
        section1.set("z", point1.getZ());
        ConfigurationSection section2 = section.createSection("max");
        section2.set("x", point2.getX());
        section2.set("y", point2.getY());
        section2.set("z", point2.getZ());
        MinerWar.inst().saveConfig();
    }

    public void addTasks(BukkitTask task) {
        tasks.add(task);
    }

    public Location getVillagerPoint() {
        return villagerPoint;
    }
    public Villager getVillagerShop() {
        return villagerShop;
    }

    public Region getGameRegion() {
        return gameRegion;
    }

    public void effect_setComplete(int amount){
        completeAmount = amount;
    }
    public void effect_addComplete(int amount){
        effect_setComplete(completeAmount + amount);
    }
    public void effect_takeComplete(int amount){
        effect_setComplete(completeAmount - amount);
    }

    public int getExcavateAmount() {
        return excavateAmount;
    }

    public void setExcavateAmount(int excavateAmount) {
        this.excavateAmount = excavateAmount;
    }

    public void effect_RefreshExcavateAmount(Player player){
        int amount = 0;
        Inventory inv = player.getInventory();
        for (int i = 0;i < 36;i++){
            ItemStack item = inv.getItem(i);
            if(item != null && item.getType() != Material.AIR){
                if(item.getType().equals(Material.RAW_GOLD)){
                    amount = amount + item.getAmount();
                }
            }
        }
        setExcavateAmount(amount);
    }

    public int getExcavateAmount(Player player){
        int amount = 0;
        Inventory inv = player.getInventory();
        for (int i = 0;i < 36;i++){
            ItemStack item = inv.getItem(i);
            if(item != null && item.getType() != Material.AIR){
                if(item.getType().equals(Material.RAW_GOLD)){
                    amount = amount + item.getAmount();
                }
            }
        }
        return amount;
    }
}
