package eu.mhsl.minecraft.endlessjumper.generator;

import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.title.Title;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.packet.server.play.ParticlePacket;
import net.minestom.server.particle.Particle;
import net.minestom.server.sound.SoundEvent;

import java.util.ArrayList;
import java.util.Random;

public class JumpGenerator {
    private final Player player;
    private final InstanceContainer world;
    private final ArrayList<Pos> blocks = new ArrayList<>();
    private Pos checkpoint;
    private Pos starting;

    private int combo = 0;

    private final int preview = 2;


    public JumpGenerator(Pos starting, Player player, InstanceContainer world) {
        this.player = player;
        this.world = world;
        this.starting = starting;
        generateStart(starting);
    }

    public void generateNext() {
        boolean isTenth = this.blocks.size() % 10 == 0;
        boolean standingTenth = (this.blocks.size()-this.preview-1) % 10 == 0;
        boolean isHundredth = this.blocks.size() % 100 == 0;

        float pitch = 1 + (combo * 0.025f);
        this.player.playSound(Sound.sound(SoundEvent.BLOCK_NOTE_BLOCK_PLING, Sound.Source.MASTER, 0.1f, pitch));
        this.player.showTitle(Title.title(Component.text(""), Component.text((combo)+"", TextColor.color(255, 69, 0))));
        this.player.setLevel((this.blocks.size()-this.preview-1));

        Random r = new Random();
        Pos target = blocks.get(blocks.size()-1).add(r.nextInt(-1, 2), r.nextInt(this.player.getPosition().y() < 80 ? 0 : -1, this.player.getPosition().y() > 120 ? 1 : 2), r.nextInt(3, 5));
        this.world.setBlock(target, isHundredth ? Block.DIAMOND_BLOCK : isTenth ? Block.GOLD_BLOCK : BlockPalette.getRandom((this.blocks.size() / 10)));

        if(standingTenth) {
            Pos current = this.blocks.get(this.blocks.size()-this.preview-1);
            this.checkpoint = current;
            this.player.playSound(Sound.sound(SoundEvent.ENTITY_PLAYER_LEVELUP, Sound.Source.BLOCK, 0.3f, 1f));
            this.player.showTitle(Title.title(Component.text(""), Component.text("Checkpoint", TextColor.color(0, 255, 0))));
            this.player.sendPacket(new ParticlePacket(Particle.CRIT, current, current.add(0.5), 1.5f, 50));
        }
        this.world.setBlock(target.add(0, 1 ,0), Block.LIGHT);
        this.blocks.add(target);
        this.player.sendPacket(new ParticlePacket(Particle.CRIT, target, target.add(0.5), 1, 10));
        this.player.sendPacket(new ParticlePacket(Particle.FALLING_NECTAR, target, target.add(0.5),0.3f, 10));
        this.combo++;
    }

    public Pos getNextLanding() {
        return this.blocks.get(this.blocks.size()-(preview+1));
    }


    public void generateStart(Pos start) {
        this.starting = start;
        this.checkpoint = start;
        this.blocks.add(this.starting);
        this.world.setBlock(this.starting, Block.DIAMOND_BLOCK);
        for(int i = 0; i <= preview; i++) generateNext();
    }

    public void reset() {
        /*
        for(Pos p : this.blocks) {
            this.world.setBlock(p, Block.AIR);
        }
        this.blocks.clear();
        */
        this.player.teleport(this.checkpoint.add(0.5, 1, 0.5));
        this.combo = 0;
        this.player.showTitle(Title.title(Component.text(""), Component.text("")));

        //generateStart(last);
        this.player.playSound(Sound.sound(SoundEvent.BLOCK_GLASS_BREAK, Sound.Source.BLOCK, 0.3f, 1f));

    }

    public Pos getCheckpoint() {
        return checkpoint;
    }

    public ArrayList<Pos> getBlocks() {
        return blocks;
    }

    public int getPreview() {
        return preview;
    }
}
