use crate::effects::star_field;
use crate::slide::Slide;
use crate::slide_show_config::Context;
use crate::text_drawer::{Justified, TextConfigBuilder};
use crate::utils::{draw_rectangle_with_border, screen_center};
use macroquad::color::{BLACK, DARKGREEN, GREEN};
use macroquad::math::Vec2;
use macroquad::prelude::{clear_background, screen_height, screen_width};
use rand::prelude::IndexedRandom;
use rand::rng;
use serde::Deserialize;
use std::f32::consts::PI;

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct GiteaRepo {
    pub id: u64,
    pub name: String,
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct GiteaResponse {
    pub ok: bool,
    pub data: Vec<GiteaRepo>,
}

#[derive(Debug)]
struct FloatingText {
    pos: Vec2,
    vel: Vec2,
    text: String,
}

#[derive(Debug)]
pub struct Projects {
    repos: Vec<FloatingText>,
}

impl Projects {
    pub fn new() -> Box<Self> {
        let resp: GiteaResponse =
            reqwest::blocking::get("https://git.ahines.net/api/v1/repos/search")
                .unwrap()
                .json()
                .unwrap();

        let repos: Vec<FloatingText> = resp
            .data
            .into_iter()
            .filter_map(|r| {
                if !r.name.starts_with("_") {
                    Some(FloatingText {
                        pos: Default::default(),
                        vel: Default::default(),
                        text: r.name,
                    })
                } else {
                    None
                }
            })
            .collect();

        Box::new(Self { repos })
    }
}

impl Slide for Projects {
    fn display(&mut self, ctx: &Context<'_>) {
        clear_background(BLACK);
        star_field();

        let text_cfg = TextConfigBuilder::new(ctx.slide_show_theme.body_config.clone())
            .font_size(75)
            .justification(Justified::Center)
            .build();

        for repo in &mut self.repos {
            if repo.pos.x <= 0.0
                || repo.pos.y <= 0.0
                || repo.pos.x > screen_width()
                || repo.pos.y > screen_height()
            {
                repo.pos = screen_center();
                let vel: f32 = rand::random_range(1.0..1.5);
                let angle: f32 = rand::random_range(0.0..2.0 * PI);

                repo.vel = Vec2::new(vel, 0.0).rotate(Vec2::from(angle.sin_cos()));

                repo.vel = Vec2::new(rand::random_range(0.1..1.5), rand::random_range(0.1..1.5));

                repo.vel.x *= [-1.0, 1.0].choose(&mut rng()).unwrap();
                repo.vel.y *= [-1.0, 1.0].choose(&mut rng()).unwrap();
            }

            text_cfg.draw_text(&repo.text, repo.pos);

            repo.pos += repo.vel
        }
        let dim = ctx
            .slide_show_theme
            .heading_config
            .measure_text("https://git.ahines.net");

        let background_rectangle_size = Vec2::new(dim.width * 1.2, dim.height * 1.2);
        let pos =
            screen_center() - background_rectangle_size * 0.5 - Vec2::new(0.0, dim.offset_y * 0.5);

        draw_rectangle_with_border(
            pos,
            background_rectangle_size,
            background_rectangle_size.x * 0.01,
            GREEN,
            DARKGREEN,
        );

        ctx.slide_show_theme
            .heading_config
            .draw_text("https://git.ahines.net", screen_center());
    }
}
