/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_1297
 *  net.minecraft.class_1657
 *  net.minecraft.class_1937
 *  net.minecraft.class_2596
 *  net.minecraft.class_2663
 */
package meteordevelopment.meteorclient.systems.modules.misc;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineEvent;
import meteordevelopment.meteorclient.events.packets.PacketEvent;
import meteordevelopment.meteorclient.settings.DoubleSetting;
import meteordevelopment.meteorclient.settings.Setting;
import meteordevelopment.meteorclient.settings.SettingGroup;
import meteordevelopment.meteorclient.settings.StringSetting;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_1297;
import net.minecraft.class_1657;
import net.minecraft.class_1937;
import net.minecraft.class_2596;
import net.minecraft.class_2663;

public class CustomPopSound
extends Module {
    private final SettingGroup sgGeneral;
    private final Setting<String> youtubeUrl;
    private final Setting<Double> volume;
    private File soundFile;
    private final ExecutorService executor;
    private boolean downloading;

    public CustomPopSound() {
        super(Categories.Misc, "custom-pop-sound", "Plays a custom sound when someone pops a totem.");
        this.sgGeneral = this.settings.getDefaultGroup();
        this.youtubeUrl = this.sgGeneral.add(((StringSetting.Builder)((StringSetting.Builder)((StringSetting.Builder)((StringSetting.Builder)new StringSetting.Builder().name("youtube-url")).description("The YouTube link or direct audio URL (WAV/MP3).")).defaultValue("")).onChanged(s -> this.downloadSound())).build());
        this.volume = this.sgGeneral.add(((DoubleSetting.Builder)((DoubleSetting.Builder)new DoubleSetting.Builder().name("volume")).description("The volume of the pop sound.")).defaultValue(1.0).min(0.0).sliderMax(1.0).build());
        this.executor = Executors.newSingleThreadExecutor();
        this.downloading = false;
    }

    @Override
    public void onActivate() {
        this.downloadSound();
    }

    private void downloadSound() {
        String urlText = this.youtubeUrl.get();
        if (urlText.isEmpty()) {
            return;
        }
        this.executor.execute(() -> {
            this.downloading = true;
            try {
                File cacheDir;
                String videoId = this.extractVideoId(urlText);
                Object downloadUrl = urlText;
                if (videoId != null) {
                    downloadUrl = "https://api.vevioz.com/@api/button/mp3/" + videoId;
                    this.info("Resolving YouTube audio for ID: " + videoId, new Object[0]);
                }
                if (!(cacheDir = new File(this.mc.field_1697, "meteor-cache/pop-sounds")).exists()) {
                    cacheDir.mkdirs();
                }
                this.soundFile = new File(cacheDir, "custom_pop.wav");
                this.info("Downloading custom pop sound...", new Object[0]);
                HttpURLConnection conn = (HttpURLConnection)new URL((String)downloadUrl).openConnection();
                conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(30000);
                int responseCode = conn.getResponseCode();
                if (responseCode != 200) {
                    throw new Exception("Server returned HTTP " + responseCode);
                }
                try (BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
                     FileOutputStream out = new FileOutputStream(this.soundFile);){
                    int read;
                    byte[] buffer = new byte[8192];
                    while ((read = ((InputStream)in).read(buffer)) != -1) {
                        out.write(buffer, 0, read);
                    }
                }
                this.info("Custom pop sound ready.", new Object[0]);
            }
            catch (Exception e) {
                this.error("Failed to download custom pop sound: " + e.getMessage(), new Object[0]);
            }
            finally {
                this.downloading = false;
            }
        });
    }

    private String extractVideoId(String url) {
        String pattern = "(?<=watch\\?v=|/videos/|embed/|youtu.be/|/v/|/e/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%2F|youtu.be%2F|%2Fv%2F)[^#&?\\n]*";
        Pattern compiledPattern = Pattern.compile(pattern);
        Matcher matcher = compiledPattern.matcher(url);
        if (matcher.find()) {
            return matcher.group();
        }
        return null;
    }

    @EventHandler
    private void onReceivePacket(PacketEvent.Receive event) {
        if (this.soundFile == null || !this.soundFile.exists() || this.downloading) {
            return;
        }
        class_2596<?> class_25962 = event.packet;
        if (!(class_25962 instanceof class_2663)) {
            return;
        }
        class_2663 p = (class_2663)class_25962;
        if (p.method_11470() != 35) {
            return;
        }
        class_1297 entity = p.method_11469((class_1937)this.mc.field_1687);
        if (!(entity instanceof class_1657)) {
            return;
        }
        this.playSound();
    }

    private void playSound() {
        new Thread(() -> {
            try {
                AudioInputStream audioIn = AudioSystem.getAudioInputStream(this.soundFile);
                Clip clip = AudioSystem.getClip();
                clip.open(audioIn);
                if (clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
                    FloatControl gainControl = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN);
                    float dB = (float)(Math.log(this.volume.get()) / Math.log(10.0) * 20.0);
                    gainControl.setValue(dB);
                }
                clip.start();
                clip.addLineListener(event -> {
                    if (event.getType() == LineEvent.Type.STOP) {
                        clip.close();
                    }
                });
            }
            catch (Exception e) {
                this.error("Failed to play custom pop sound: " + e.getMessage(), new Object[0]);
            }
        }).start();
    }
}

