/*
 * Copyright (c) 2026 YimRakhee
 * Licensed under the GNU General Public License v3.0 (or later).
 * See the LICENSE file in the project root for more information.
 */

use nih_plug::prelude::*;
use nih_plug_egui::{create_egui_editor, egui, EguiState};
use std::sync::Arc;

use crate::LetsDistParams;

pub fn create(params: Arc<LetsDistParams>) -> Option<Box<dyn Editor>> {
    let egui_state = EguiState::from_size(600, 130);

    create_egui_editor(
        egui_state,
        (),
        |cx, _| {
            egui_extras::install_image_loaders(cx);
        },
        move |cx, setter, _state| {
            egui::CentralPanel::default()
            .frame(egui::Frame::NONE)
            .show(cx, |ui| {
                let bg_rect = egui::Rect::from_min_size(egui::pos2(0.0, 0.0), egui::vec2(600.0, 130.0));
                let bg_image = egui::Image::new(egui::include_image!("../assets/bg.png"))
                .fit_to_exact_size(bg_rect.size());
                ui.put(bg_rect, bg_image);

                draw_switch(ui, setter, &params.fx_bypass, 14.0, 56.0);
                draw_knob(ui, setter, &params.distortion, 144.0, 34.0);
                draw_knob(ui, setter, &params.filter, 234.0, 34.0);
                draw_knob(ui, setter, &params.slew, 324.0, 34.0);
                draw_knob(ui, setter, &params.dry, 414.0, 34.0);
                draw_knob(ui, setter, &params.wet, 504.0, 34.0);
            });
        },
    )
}

fn draw_knob(ui: &mut egui::Ui, setter: &ParamSetter, param: &FloatParam, x: f32, y: f32) {
    let size = 70.0;
    let rect = egui::Rect::from_min_size(egui::pos2(x, y), egui::vec2(size, size));

    let response = ui.allocate_rect(rect, egui::Sense::click_and_drag());

    let mut val = param.unmodulated_normalized_value();

    if response.double_clicked() {
        val = param.default_normalized_value();
        setter.begin_set_parameter(param);
        setter.set_parameter_normalized(param, val);
        setter.end_set_parameter(param);
    } else if response.drag_started() {
        setter.begin_set_parameter(param);
    } else if response.dragged() {
        let delta = response.drag_delta().y;
        let sensitivity = if ui.input(|i| i.modifiers.shift) { 0.001 } else { 0.005 };

        val = (val - delta * sensitivity).clamp(0.0, 1.0);
        setter.set_parameter_normalized(param, val);
    } else if response.drag_stopped() {
        setter.end_set_parameter(param);
    } else if response.hovered() {

        let scroll_delta = ui.input(|i| i.smooth_scroll_delta.x + i.smooth_scroll_delta.y);

        if scroll_delta != 0.0 {
            let sensitivity = 0.0005;
            val = (val + scroll_delta * sensitivity).clamp(0.0, 1.0);

            setter.begin_set_parameter(param);
            setter.set_parameter_normalized(param, val);
            setter.end_set_parameter(param);
        }
    }

    let angle_deg = val * 300.0 - 150.0;
    let angle_rad = angle_deg.to_radians();

    let image = egui::Image::new(egui::include_image!("../assets/knob.png"))
    .fit_to_exact_size(egui::vec2(size, size))
    .rotate(angle_rad, egui::vec2(0.5, 0.5));

    ui.put(rect, image);
}


fn draw_switch(ui: &mut egui::Ui, setter: &ParamSetter, param: &BoolParam, x: f32, y: f32) {
    let size = 62.0;
    let rect = egui::Rect::from_min_size(egui::pos2(x, y), egui::vec2(size, size));

    let response = ui.allocate_rect(rect, egui::Sense::click());

    if response.clicked() {
        setter.begin_set_parameter(param);
        setter.set_parameter(param, !param.value());
        setter.end_set_parameter(param);
    }

    let image_source = if param.value() {
        egui::include_image!("../assets/on.png")
    } else {
        egui::include_image!("../assets/off.png")
    };

    let image = egui::Image::new(image_source).fit_to_exact_size(egui::vec2(size, size));
    ui.put(rect, image);
}
