trackWork 0.15.0

A terminal-based time tracking application for managing work sessions
use anyhow::Result;

use crate::app::{App, InputMode, TaskEditState};

impl App {
    pub fn open_tasks(&mut self) {
        let tasks = self.db.get_all_tasks().unwrap_or_default();
        self.input_mode = InputMode::Tasks {
            selected_index: 0,
            tasks,
            editing: None,
            confirm_delete: false,
        };
    }

    pub fn refresh_tasks(&mut self) {
        if let InputMode::Tasks { tasks, selected_index, .. } = &mut self.input_mode {
            *tasks = self.db.get_all_tasks().unwrap_or_default();
            if *selected_index >= tasks.len() && !tasks.is_empty() {
                *selected_index = tasks.len() - 1;
            }
        }
    }

    pub fn tasks_start_creating(&mut self) {
        if let InputMode::Tasks { editing, .. } = &mut self.input_mode {
            *editing = Some(TaskEditState {
                task_id: None,
                issue_key: String::new(),
                name: String::new(),
                project: String::new(),
                current_field: 0,
            });
        }
    }

    pub fn tasks_start_editing(&mut self) {
        if let InputMode::Tasks { tasks, selected_index, editing, .. } = &mut self.input_mode {
            if let Some(task) = tasks.get(*selected_index) {
                *editing = Some(TaskEditState {
                    task_id: Some(task.id),
                    issue_key: task.issue_key.clone(),
                    name: task.name.clone(),
                    project: task.project.clone(),
                    current_field: 0,
                });
            }
        }
    }

    pub fn tasks_save(&mut self) -> Result<()> {
        if let InputMode::Tasks { editing, tasks, .. } = &mut self.input_mode {
            if let Some(ref edit) = editing {
                if edit.issue_key.is_empty() {
                    self.status_message = Some("Issue key cannot be empty".to_string());
                    return Ok(());
                }
                // Check for issue_key conflict with a different task
                let conflict = tasks.iter().any(|t| {
                    t.issue_key == edit.issue_key && Some(t.id) != edit.task_id
                });
                if conflict {
                    self.status_message = Some(format!(
                        "Issue key '{}' already exists",
                        edit.issue_key
                    ));
                    return Ok(());
                }
                let edit = editing.take().unwrap();
                if let Some(id) = edit.task_id {
                    self.db.update_task(id, &edit.issue_key, &edit.name, &edit.project)?;
                } else {
                    self.db.create_task(&edit.issue_key, &edit.name, &edit.project)?;
                }
                self.refresh_tasks();
            }
        }
        Ok(())
    }

    pub fn tasks_delete(&mut self) -> Result<()> {
        if let InputMode::Tasks { tasks, selected_index, confirm_delete, .. } = &mut self.input_mode {
            if let Some(task) = tasks.get(*selected_index) {
                self.db.delete_task(task.id)?;
                *confirm_delete = false;
            }
        }
        self.refresh_tasks();
        Ok(())
    }

    pub fn tasks_cancel_edit(&mut self) {
        if let InputMode::Tasks { editing, .. } = &mut self.input_mode {
            *editing = None;
        }
    }

    pub fn tasks_confirm_delete(&mut self) {
        if let InputMode::Tasks { tasks, selected_index, confirm_delete, .. } = &mut self.input_mode {
            if *selected_index < tasks.len() {
                *confirm_delete = true;
            }
        }
    }

    pub fn tasks_cancel_delete(&mut self) {
        if let InputMode::Tasks { confirm_delete, .. } = &mut self.input_mode {
            *confirm_delete = false;
        }
    }
}