use crate::ecs::world::World;
use nalgebra_glm::{Vec2, Vec4};

use crate::ecs::ui::components::*;

pub fn ui_canvas_hit_test(world: &World, entity: freecs::Entity, position: Vec2) -> Option<u32> {
    if let Some(data) = world.ui.get_ui_canvas(entity) {
        for &(command_id, ref rect) in data.command_bounds.iter().rev() {
            if rect.contains(position) {
                return Some(command_id);
            }
        }
    }
    None
}

pub fn ui_canvas_clear(world: &mut World, entity: freecs::Entity) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.clear();
    }
}

pub fn ui_canvas_rect(
    world: &mut World,
    entity: freecs::Entity,
    position: Vec2,
    size: Vec2,
    color: Vec4,
    corner_radius: f32,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Rect {
            position,
            size,
            color,
            corner_radius,
            id: None,
        });
    }
}

pub fn ui_canvas_circle(
    world: &mut World,
    entity: freecs::Entity,
    center: Vec2,
    radius: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Circle {
            center,
            radius,
            color,
            id: None,
        });
    }
}

pub fn ui_canvas_line(
    world: &mut World,
    entity: freecs::Entity,
    from: Vec2,
    to: Vec2,
    thickness: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Line {
            from,
            to,
            thickness,
            color,
            id: None,
        });
    }
}

pub fn ui_canvas_text(
    world: &mut World,
    entity: freecs::Entity,
    text: &str,
    position: Vec2,
    font_size: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Text {
            text: text.to_string(),
            position,
            font_size,
            color,
            id: None,
        });
    }
}

pub fn ui_canvas_polyline(
    world: &mut World,
    entity: freecs::Entity,
    points: &[Vec2],
    thickness: f32,
    color: Vec4,
    closed: bool,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Polyline {
            points: points.to_vec(),
            thickness,
            color,
            closed,
            id: None,
        });
    }
}

pub fn ui_canvas_rect_stroke(
    world: &mut World,
    entity: freecs::Entity,
    position: Vec2,
    size: Vec2,
    color: Vec4,
    thickness: f32,
    corner_radius: f32,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::RectStroke {
            position,
            size,
            color,
            thickness,
            corner_radius,
            id: None,
        });
    }
}

pub fn ui_canvas_circle_stroke(
    world: &mut World,
    entity: freecs::Entity,
    center: Vec2,
    radius: f32,
    color: Vec4,
    thickness: f32,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::CircleStroke {
            center,
            radius,
            color,
            thickness,
            id: None,
        });
    }
}

pub fn ui_canvas_arc(
    world: &mut World,
    entity: freecs::Entity,
    center: Vec2,
    radius: f32,
    angle_range: (f32, f32),
    thickness: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::Arc {
            center,
            radius,
            start_angle: angle_range.0,
            end_angle: angle_range.1,
            thickness,
            color,
            id: None,
        });
    }
}

pub fn ui_canvas_quadratic_bezier(
    world: &mut World,
    entity: freecs::Entity,
    start: Vec2,
    control: Vec2,
    end: Vec2,
    thickness: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::QuadraticBezier {
            start,
            control,
            end,
            thickness,
            color,
            id: None,
        });
    }
}

pub fn ui_canvas_cubic_bezier(
    world: &mut World,
    entity: freecs::Entity,
    start: Vec2,
    controls: (Vec2, Vec2),
    end: Vec2,
    thickness: f32,
    color: Vec4,
) {
    if let Some(data) = world.ui.get_ui_canvas_mut(entity) {
        data.commands.push(CanvasCommand::CubicBezier {
            start,
            control1: controls.0,
            control2: controls.1,
            end,
            thickness,
            color,
            id: None,
        });
    }
}
