use tachyonfx::{fx, Interpolation, Motion};

use crate::page::Page;
use crate::state::ui::UiState;
use crate::state::Modal;
use crate::theme;

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum FxId {
    #[default]
    PageTransition,
    NavSwitch,
}

pub fn tick_effects(ui: &mut UiState, page: Page) {
    if !ui.show_title && ui.prev_show_title {
        ui.effects.borrow_mut().add_unique_effect(
            FxId::PageTransition,
            fx::coalesce((200, Interpolation::QuadOut)),
        );
    }
    ui.prev_show_title = ui.show_title;

    let modal_open = !matches!(ui.modal, Modal::None);

    if modal_open && !ui.prev_modal_open {
        let bg = theme::get().ui.bg;
        *ui.modal_fx.borrow_mut() = Some(fx::fade_from_fg(bg, (50, Interpolation::QuadOut)));
    }
    ui.prev_modal_open = modal_open;

    if page != ui.prev_page {
        let direction = page_direction(ui.prev_page, page);
        let bg = theme::get().ui.bg;
        ui.effects.borrow_mut().add_unique_effect(
            FxId::PageTransition,
            fx::sweep_in(direction, 10, 0, bg, (200, Interpolation::QuadOut)),
        );
        ui.prev_page = page;
    }
}

pub fn nav_sweep(ui: &UiState, direction: Motion) {
    let bg = theme::get().ui.bg;
    ui.effects.borrow_mut().add_unique_effect(
        FxId::NavSwitch,
        fx::sweep_in(direction, 10, 0, bg, (300, Interpolation::QuadOut)),
    );
}

fn page_direction(from: Page, to: Page) -> Motion {
    let (fc, fr) = from.grid_pos();
    let (tc, tr) = to.grid_pos();
    if tc > fc {
        Motion::LeftToRight
    } else if tc < fc {
        Motion::RightToLeft
    } else if tr > fr {
        Motion::UpToDown
    } else {
        Motion::DownToUp
    }
}
