//! Types for the business glossary module.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// A glossary containing business term definitions.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Glossary {
    /// Business term definitions keyed by canonical term name.
    #[serde(default)]
    pub terms: HashMap<String, GlossaryTerm>,
}

/// A single business term definition.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GlossaryTerm {
    /// The canonical business name (e.g., "revenue", "active customers").
    pub term: String,

    /// SQL expression or column reference that defines this term.
    pub definition: String,

    /// Direct column reference (for simple column mappings).
    #[serde(default)]
    pub column_ref: Option<ColumnReference>,

    /// Synonyms for this term (e.g., ["sales", "amount"] for "revenue").
    #[serde(default)]
    pub synonyms: Vec<String>,

    /// Human-readable description of what this term means.
    #[serde(default)]
    pub description: Option<String>,
}

/// A reference to a specific table.column in the schema.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ColumnReference {
    /// Table name.
    pub table: String,
    /// Column name.
    pub column: String,
}

/// A match result from resolving a business term against the schema.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GlossaryMatch {
    /// The business term that was matched.
    pub term: String,

    /// The matched column reference, if applicable.
    pub matched_column: Option<ColumnReference>,

    /// The matched SQL definition, if applicable.
    pub matched_definition: Option<String>,

    /// Confidence score (0.0 to 1.0).
    pub confidence: f64,

    /// How the match was found.
    pub source: MatchSource,
}

/// How a glossary match was found.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum MatchSource {
    /// Exact match on the canonical term name.
    ExactTerm,
    /// Matched via a synonym.
    Synonym,
    /// Matched via description text.
    Description,
    /// Matched via fuzzy name similarity.
    FuzzyName,
    /// Matched via column synonym on ColumnDef.
    ColumnSynonym,
}

/// Result of resolving multiple business terms in batch.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TermResolutionResult {
    /// Successfully resolved terms.
    pub resolved: Vec<GlossaryMatch>,
    /// Terms that could not be resolved.
    pub unresolved: Vec<String>,
}

/// A suggestion mapping a SQL element to a business term.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TermSuggestion {
    /// The SQL element (table or column name) found in the query.
    pub sql_element: String,
    /// The suggested business term.
    pub suggested_term: String,
    /// Confidence score (0.0 to 1.0).
    pub confidence: f64,
}

impl std::fmt::Display for MatchSource {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            MatchSource::ExactTerm => write!(f, "exact_term"),
            MatchSource::Synonym => write!(f, "synonym"),
            MatchSource::Description => write!(f, "description"),
            MatchSource::FuzzyName => write!(f, "fuzzy_name"),
            MatchSource::ColumnSynonym => write!(f, "column_synonym"),
        }
    }
}

impl std::fmt::Display for ColumnReference {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}.{}", self.table, self.column)
    }
}
