use std::error::Error;
use std::fmt::{Display, Formatter};

use crate::agent::{ProviderMode, TaskProfile};

/// Backend error type for application-level validation and runtime failures.
#[derive(Debug, PartialEq, Eq)]
pub enum AppError {
    EmptyPrompt,
    AgentNotConfigured,
    RemoteApiKeyMissing,
    InvalidSettings(String),
    UnknownSession(String),
    SettingsStore(String),
    ProviderInit(String),
    ProviderRequest(String),
    ProviderNotConfigured(ProviderMode),
    TaskRouteMissing(TaskProfile),
    ModelMissing(TaskProfile),
}

impl Display for AppError {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::EmptyPrompt => formatter.write_str("prompt cannot be empty"),
            Self::AgentNotConfigured => formatter.write_str(
                "AI chat is not configured yet. Open AI Settings to configure a provider and task route.",
            ),
            Self::RemoteApiKeyMissing => formatter.write_str("remote API key cannot be empty"),
            Self::InvalidSettings(message) => formatter.write_str(message),
            Self::UnknownSession(session_id) => {
                write!(formatter, "unknown session: {session_id}")
            }
            Self::SettingsStore(message) => {
                write!(formatter, "settings store error: {message}")
            }
            Self::ProviderInit(message) => {
                write!(formatter, "AI provider initialization failed: {message}")
            }
            Self::ProviderRequest(message) => {
                write!(formatter, "AI provider request failed: {message}")
            }
            Self::ProviderNotConfigured(ProviderMode::Remote) => formatter.write_str(
                "remote provider is not configured. Save a remote base URL, model, and API key.",
            ),
            Self::ProviderNotConfigured(ProviderMode::Local) => formatter.write_str(
                "local provider is not configured. Save a local base URL and local task model.",
            ),
            Self::TaskRouteMissing(task) => {
                write!(formatter, "task route is missing for {task:?}")
            }
            Self::ModelMissing(task) => {
                write!(formatter, "model is missing for task {task:?}")
            }
        }
    }
}

impl Error for AppError {}
