use crate::error::AppError;
use crate::models::ticket::ProcessedTicket;
use crate::models::worktree::Worktree;
use crate::AppState;
use serde::Serialize;
use tauri::State;

#[derive(Debug, Clone, Serialize)]
pub struct TicketResult {
    pub ticket: ProcessedTicket,
    pub worktree: Option<Worktree>,
}

#[tauri::command]
pub fn get_ticket_result(
    state: State<'_, AppState>,
    ticket_id: String,
) -> Result<TicketResult, AppError> {
    let conn = state.db.lock().map_err(|e| AppError::from(e.to_string()))?;
    let ticket = ProcessedTicket::get_by_id(&conn, &ticket_id)?;
    let worktree = Worktree::get_by_ticket_id(&conn, &ticket_id)?;
    Ok(TicketResult { ticket, worktree })
}

#[tauri::command]
pub fn retry_ticket(
    state: State<'_, AppState>,
    ticket_id: String,
) -> Result<(), AppError> {
    let conn = state.db.lock().map_err(|e| AppError::from(e.to_string()))?;
    let ticket = ProcessedTicket::get_by_id(&conn, &ticket_id)?;

    if ticket.status != "Error" && ticket.status != "Done" && ticket.status != "Cancelled" {
        return Err(AppError::from(format!(
            "Cannot retry ticket with status '{}'",
            ticket.status
        )));
    }

    ProcessedTicket::update_status(&conn, &ticket_id, "Pending")?;
    conn.execute(
        "UPDATE processed_tickets SET analyst_report = NULL, developer_report = NULL, \
         worktree_path = NULL, branch_name = NULL, processed_at = NULL WHERE id = ?1",
        rusqlite::params![ticket_id],
    )?;

    if let Some(wt) = Worktree::get_by_ticket_id(&conn, &ticket_id)? {
        if wt.status == "Active" {
            let project_id = {
                let tracker = crate::models::tracker::WatchedTracker::get_by_id(&conn, &ticket.tracker_id)?;
                tracker.project_id
            };
            let project = crate::models::project::Project::get_by_id(&conn, &project_id)?;
            let _ = crate::services::worktree_manager::delete_worktree(
                &project.path,
                &wt.path,
                &wt.branch_name,
            );
        }
        Worktree::delete(&conn, &wt.id)?;
    }

    Ok(())
}

#[tauri::command]
pub fn cancel_ticket(
    state: State<'_, AppState>,
    ticket_id: String,
) -> Result<(), AppError> {
    let conn = state.db.lock().map_err(|e| AppError::from(e.to_string()))?;
    let ticket = ProcessedTicket::get_by_id(&conn, &ticket_id)?;

    if ticket.status == "Done" || ticket.status == "Cancelled" {
        return Err(AppError::from(format!(
            "Cannot cancel ticket with status '{}'",
            ticket.status
        )));
    }

    ProcessedTicket::update_status(&conn, &ticket_id, "Cancelled")?;
    Ok(())
}
