use crate::app::{actions::Action, state::AppState};

pub fn reduce(mut state: AppState, action: &Action) -> Option<AppState> {
    match action {
        Action::SetDiffText(txt) => {
            state.last_diff = txt.clone();
        }
        Action::SetLastDiffPath(p) => {
            state.last_diff_path = p.clone();
        }
        Action::SetLastDiffTruncated(flag) => {
            state.last_diff_truncated = *flag;
        }
        Action::SetLastDiffTotal(n) => {
            state.last_diff_total = *n;
        }
        Action::SetLastDiffFetchedAt(ts) => {
            state.last_diff_fetched_at = ts.clone();
        }
        Action::SetDiff(raw) => {
            state.last_diff = raw.clone();
        }
        Action::SetDiffParsed(parsed) => {
            state.diff_parsed = parsed.clone();
        }
        Action::DetailScrollUp => {
            state.detail_scroll = state.detail_scroll.saturating_sub(5);
        }
        Action::DetailScrollDown => {
            state.detail_scroll = state.detail_scroll.saturating_add(5);
        }
        Action::DetailScrollReset => {
            state.detail_scroll = 0;
        }
        Action::DetailScrollLeft => {
            if state.detail_scroll_x > 0 {
                state.detail_scroll_x = state.detail_scroll_x.saturating_sub(4);
            }
        }
        Action::DetailScrollRight => {
            state.detail_scroll_x = state.detail_scroll_x.saturating_add(4);
        }
        Action::SetHunks(hunks) => {
            state.hunks = hunks.clone();
            state.hunk_selected = 0;
        }
        Action::HunkNext => {
            if !state.hunks.is_empty() && state.hunk_selected + 1 < state.hunks.len() {
                state.hunk_selected += 1;
            }
        }
        Action::HunkPrev => {
            if !state.hunks.is_empty() && state.hunk_selected > 0 {
                state.hunk_selected -= 1;
            }
        }
        Action::ToggleWordDiff => {
            state.word_diff = !state.word_diff;
        }
        Action::ToggleLineSelectMode => {
            state.line_select_mode = !state.line_select_mode;
            if !state.line_select_mode {
                state.selected_lines.clear();
            }
        }
        Action::ToggleLineSelect(line) => {
            if state.selected_lines.contains(line) {
                state.selected_lines.remove(line);
            } else {
                state.selected_lines.insert(*line);
            }
        }
        Action::ClearLineSelects => {
            state.selected_lines.clear();
        }
        Action::ToggleDelta => {
            if state.has_delta {
                state.use_delta = !state.use_delta;
            }
        }
        Action::SetHasDelta(has) => {
            state.has_delta = *has;
            state.use_delta = *has; // enable by default if available
        }
        Action::IncreaseContext => {
            if state.diff_context < 20 {
                state.diff_context += 1;
            }
        }
        Action::DecreaseContext => {
            if state.diff_context > 0 {
                state.diff_context -= 1;
            }
        }
        Action::ToggleWhitespace => {
            state.ignore_whitespace = !state.ignore_whitespace;
        }
        Action::ToggleSideBySide => {
            state.side_by_side = !state.side_by_side;
        }
        Action::ToggleTreeView => {
            state.tree_view = !state.tree_view;
        }
        _ => return None,
    }
    Some(state)
}
