use eframe::egui::{self, Color32, FontId, Rounding, Stroke, Vec2};

fn lerp_color(a: Color32, b: Color32, t: f32) -> Color32 {
    Color32::from_rgba_premultiplied(
        (a.r() as f32 + (b.r() as f32 - a.r() as f32) * t) as u8,
        (a.g() as f32 + (b.g() as f32 - a.g() as f32) * t) as u8,
        (a.b() as f32 + (b.b() as f32 - a.b() as f32) * t) as u8,
        (a.a() as f32 + (b.a() as f32 - a.a() as f32) * t) as u8,
    )
}

fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_color: Color32, text_color: Color32, hover_top: Color32, hover_bottom: Color32, border_color: Color32, enabled: bool) -> egui::Response {
    let rounding = Rounding::same(6.0);
    let min_size = Vec2::new(100.0, 32.0);
    let padding = Vec2::new(12.0, 6.0);

    let font_id = ui.style().text_styles.get(&egui::TextStyle::Button)
        .cloned().unwrap_or(FontId::proportional(14.0));
    let galley = ui.painter().layout_no_wrap(
        text.to_string(),
        font_id,
        text_color,
    );

    let size = Vec2::new(
        min_size.x.max(galley.size().x + 2.0 * padding.x),
        min_size.y.max(galley.size().y + 2.0 * padding.y),
    );

    let sense = if enabled { egui::Sense::click() } else { egui::Sense::hover() };
    let (rect, response) = ui.allocate_exact_size(size, sense);

    let (actual_top, actual_bottom, actual_text, actual_border) = if enabled {
        let hover_gradient = if response.hovered() {
            (hover_top, hover_bottom)
        } else {
            (top_color, bottom_color)
        };
        (hover_gradient.0, hover_gradient.1, text_color, border_color)
    } else {
        let disabled = lerp_color(top_color, Color32::from_rgb(80, 80, 80), 0.5);
        (disabled, disabled, Color32::from_gray(160), Color32::from_gray(100))
    };

    let n_strips = 16;
    for i in 0..n_strips {
        let t = i as f32 / n_strips as f32;
        let t2 = (i + 1) as f32 / n_strips as f32;
        let c = lerp_color(actual_top, actual_bottom, (t + t2) * 0.5);
        let y0 = rect.top() + rect.height() * t;
        let y1 = rect.top() + rect.height() * t2;
        let strip_rect = egui::Rect::from_min_max(
            egui::pos2(rect.left(), y0),
            egui::pos2(rect.right(), y1),
        );
        ui.painter().rect(strip_rect, Rounding::ZERO, c, Stroke::NONE);
    }

    ui.painter().rect(rect, rounding, Color32::TRANSPARENT, Stroke::new(1.0_f32, actual_border));

    ui.painter().galley(
        egui::pos2(rect.center().x - galley.size().x / 2.0, rect.center().y - galley.size().y / 2.0),
        galley,
        actual_text,
    );

    if let Some(cursor) = ui.visuals().interact_cursor {
        if response.hovered() {
            ui.ctx().set_cursor_icon(cursor);
        }
    }

    response
}

pub fn primary_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
    primary_button_enabled(ui, text, true)
}

pub fn primary_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(50, 130, 255),
        Color32::from_rgb(13, 110, 253),
        Color32::WHITE,
        Color32::from_rgb(70, 150, 255),
        Color32::from_rgb(30, 130, 255),
        Color32::from_rgb(13, 110, 253),
        enabled)
}

pub fn secondary_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
    secondary_button_enabled(ui, text, true)
}

pub fn secondary_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(130, 140, 150), // top
        Color32::from_rgb(100, 110, 120), // bottom
        Color32::from_rgb(255, 255, 255), // text color32
        Color32::from_rgb(150, 160, 170), // hover top
        Color32::from_rgb(120, 130, 140), // hover bottom
        Color32::from_rgb(100, 110, 120), // border
        enabled)
}

pub fn danger_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
    danger_button_enabled(ui, text, true)
}

pub fn danger_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(240, 83, 99),
        Color32::from_rgb(200, 40, 60),
        Color32::WHITE,
        Color32::from_rgb(255, 100, 120),
        Color32::from_rgb(220, 60, 80),
        Color32::from_rgb(200, 40, 60),
        enabled)
}

#[allow(dead_code)]
pub fn white_grd_btn(ui: &mut egui::Ui, text: &str) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(255, 255, 255),
        Color32::from_rgb(246, 246, 246),
        Color32::from_rgb(102, 102, 102),
        Color32::from_rgb(246, 246, 246),
        Color32::from_rgb(255, 255, 255),
        Color32::from_rgb(177, 177, 177),
        true)
}
#[allow(dead_code)]
pub fn btn_dark_blue(ui: &mut egui::Ui, text: &str) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(99, 184, 238),
        Color32::from_rgb(70, 140, 207),
        Color32::WHITE,
        Color32::from_rgb(70, 140, 207),
        Color32::from_rgb(99, 184, 238),
        Color32::from_rgb(56, 102, 163),
        true)
}

#[allow(dead_code)]
pub fn light_gray_btn(ui: &mut egui::Ui, text: &str) -> egui::Response {
    gradient_button(ui, text,
        Color32::from_rgb(249, 249, 249),  // üst: #f9f9f9
        Color32::from_rgb(233, 233, 233),  // alt: #e9e9e9
        Color32::from_rgb(102, 102, 102),  // metin: #666666
        Color32::from_rgb(233, 233, 233),  // hover üst (ters)
        Color32::from_rgb(249, 249, 249),  // hover alt (ters)
        Color32::from_rgb(227, 195, 227),  // border: #e3c7e3
        true)
}
