package com.example;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Плагин AuraPlugin добавляет анимированную золотую ауру вокруг выбранных игроков
 * с эффектами вращения по часовой стрелке и волнообразного движения.
 */
public class AuraPlugin extends JavaPlugin {

    // Набор UUID игроков, у которых включена аура
    private final Set<UUID> auraPlayers = ConcurrentHashMap.newKeySet();

    // Карта для хранения текущего состояния ауры каждого игрока
    private final Map<UUID, PlayerAura> playerAuras = new ConcurrentHashMap<>();

    // Константы для внешнего вида ауры
    private static final int PARTICLES_PER_LAYER = 10; // Количество частиц в каждом слое
    private static final double RADIUS_LAYER1 = 1.7;  // Радиус первого слоя (увеличено на 0.5)
    private static final double RADIUS_LAYER2 = 2.5;  // Радиус второго слоя (увеличено на 0.5)
    private static final double HEIGHT_LAYER1 = 2.0;  // Высота первого слоя над игроком (увеличено на 0.5)
    private static final double HEIGHT_LAYER2 = 2.5;  // Высота второго слоя над игроком (увеличено на 0.5)
    private static final double ROTATION_SPEED = Math.toRadians(2); // Скорость вращения в радианах за тик

    @Override
    public void onEnable() {
        getLogger().info("AuraPlugin включен!");
        // Регистрация команды
        Objects.requireNonNull(getCommand("aura")).setExecutor(this);
        // Запуск задачи по отображению аур
        startAuraTask();
    }

    @Override
    public void onDisable() {
        getLogger().info("AuraPlugin выключен.");
        // Остановка задачи по обновлению частиц
        if (particleTask != null) {
            particleTask.cancel();
        }
        // Очистка данных аур
        auraPlayers.clear();
        playerAuras.clear();
    }

    /**
     * Обработка команды /aura.
     * Использование: /aura <on|off> <игрок>
     */
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (command.getName().equalsIgnoreCase("aura")) {
            if (!sender.hasPermission("aura.use")) {
                sender.sendMessage(ChatColor.RED + "У вас нет прав использовать эту команду.");
                return true;
            }

            if (args.length != 2) {
                sender.sendMessage(ChatColor.RED + "Использование: /aura <on|off> <игрок>");
                return true;
            }

            String action = args[0];
            String playerName = args[1];
            Player target = Bukkit.getPlayerExact(playerName);

            if (target == null) {
                sender.sendMessage(ChatColor.RED + "Игрок не найден.");
                return true;
            }

            UUID playerUUID = target.getUniqueId();

            if (action.equalsIgnoreCase("on")) {
                if (auraPlayers.contains(playerUUID)) {
                    sender.sendMessage(ChatColor.YELLOW + "Аура уже включена для " + target.getName() + ".");
                } else {
                    auraPlayers.add(playerUUID);
                    PlayerAura aura = new PlayerAura(target);
                    playerAuras.put(playerUUID, aura);
                    sender.sendMessage(ChatColor.GREEN + "Аура включена для " + target.getName() + ".");
                }
            } else if (action.equalsIgnoreCase("off")) {
                if (!auraPlayers.contains(playerUUID)) {
                    sender.sendMessage(ChatColor.YELLOW + "У этого игрока не была включена аура.");
                } else {
                    auraPlayers.remove(playerUUID);
                    PlayerAura aura = playerAuras.remove(playerUUID);
                    if (aura != null) {
                        aura.removeAura();
                    }
                    sender.sendMessage(ChatColor.GREEN + "Аура отключена для " + target.getName() + ".");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "Неизвестное действие. Используйте 'on' или 'off'.");
            }
            return true;
        }
        return false;
    }

    // Задание для обновления и отображения частиц ауры
    private BukkitRunnable particleTask;

    /**
     * Запуск периодической задачи для отображения аур.
     */
    private void startAuraTask() {
        particleTask = new BukkitRunnable() {
            @Override
            public void run() {
                for (UUID uuid : new HashSet<>(auraPlayers)) { // Создание копии для избежания ConcurrentModification
                    Player player = Bukkit.getPlayer(uuid);
                    if (player == null || !player.isOnline()) {
                        auraPlayers.remove(uuid);
                        playerAuras.remove(uuid);
                        continue;
                    }

                    PlayerAura aura = playerAuras.get(uuid);
                    if (aura != null) {
                        aura.spawnParticles();
                    }
                }
            }
        };
        // Запуск задачи каждые 1 тик (~0.05 сек)
        particleTask.runTaskTimer(this, 0L, 1L);
    }

    /**
     * Внутренний класс для управления аурой игрока.
     */
    private class PlayerAura {
        private final Player player;
        private double angleLayer1 = 0.0;
        private double angleLayer2 = Math.PI / 15; // Смещение фазы второго слоя для разнообразия

        PlayerAura(Player player) {
            this.player = player;
        }

        /**
         * Спавн частиц для ауры данного игрока.
         */
        public void spawnParticles() {
            Location baseLocation = player.getLocation().clone().add(0, HEIGHT_LAYER1, 0);

            // Первый слой
            spawnLayer(baseLocation, RADIUS_LAYER1, HEIGHT_LAYER1, angleLayer1);
            // Второй слой
            spawnLayer(baseLocation, RADIUS_LAYER2, HEIGHT_LAYER2, angleLayer2);

            // Обновление углов для вращения по часовой стрелке
            angleLayer1 -= ROTATION_SPEED; // Уменьшаем угол для вращения по часовой стрелке
            angleLayer2 -= ROTATION_SPEED * 1.2; // Немного отличающаяся скорость для второго слоя

            // Зацикливание углов
            if (angleLayer1 < -2 * Math.PI) angleLayer1 += 2 * Math.PI;
            if (angleLayer2 < -2 * Math.PI) angleLayer2 += 2 * Math.PI;
        }

        /**
         * Спавн одного слоя частиц.
         *
         * @param base          Базовая локация (игрока).
         * @param radius        Радиус слоя.
         * @param height        Базовая высота слоя.
         * @param currentAngle  Текущий угол вращения слоя.
         */
        private void spawnLayer(Location base, double radius, double height, double currentAngle) {
            for (int i = 0; i < PARTICLES_PER_LAYER; i++) {
                double theta = currentAngle + ((2 * Math.PI) / PARTICLES_PER_LAYER) * i;
                double x = radius * Math.cos(theta);
                double z = radius * Math.sin(theta);
                // Добавим волнообразное вертикальное смещение
                double yOffset = 0.3 * Math.sin(theta * 3 + Math.PI / 2); // 3 - частота осцилляции

                Location particleLocation = base.clone().add(x, yOffset, z);

                // Спавн частицы GOLD_INGOT
                player.getWorld().spawnParticle(
                        Particle.ITEM_CRACK,
                        particleLocation,
                        1,
                        0, 0, 0,
                        0,
                        new ItemStack(Material.GOLD_INGOT)
                );
            }
        }

        /**
         * Удаление всех частиц ауры (если необходимо).
         * В данном случае, поскольку частицы спавнятся и исчезают сами,
         * нет необходимости явно их удалять.
         */
        public void removeAura() {
            // Можно добавить дополнительные эффекты при отключении ауры, если требуется
        }
    }
}

name: Aura
version: '1.0.0'
main: com.example.AuraPlugin
api-version: '1.20'
commands:
  aura:
    description: Включить или отключить ауру для игрока.
    usage: /aura <on|off> <игрок>
    permission: aura.use
permissions:
  aura.use:
    description: Позволяет использовать команду /aura
    default: op


Сделай так, чтобы аура была доступна только игрокам с никами paklonik и paklonik1