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

use crate::agent::TaskProfile;
use crate::mappings::MappingError;

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

impl AppError {
    #[must_use]
    pub const fn is_configuration_issue(&self) -> bool {
        matches!(
            self,
            Self::AgentNotConfigured
                | Self::RemoteApiKeyMissing
                | Self::ProviderNotConfigured
                | Self::TaskRouteMissing(_)
                | Self::ModelMissing(_)
        )
    }
}

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::PanelContext(message) => {
                write!(formatter, "panel context could not be prepared: {message}")
            }
            Self::AgentToolApprovalNotFound(approval_id) => {
                write!(formatter, "unknown agent tool approval: {approval_id}")
            }
            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 => formatter.write_str(
                "remote provider is not configured. Save a remote base URL, model, and API key.",
            ),
            Self::TaskRouteMissing(task) => {
                write!(formatter, "task route is missing for {task:?}")
            }
            Self::ModelMissing(task) => {
                write!(formatter, "model is missing for task {task:?}")
            }
            Self::Mappings(error) => {
                write!(formatter, "mappings error: {error}")
            }
            Self::BackgroundJobNotFound(job_id) => {
                write!(formatter, "background job not found: {job_id}")
            }
        }
    }
}

impl Error for AppError {}
