use std::fmt;

/// SQL Keywords supported by the parser.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Keyword {
    Select,
    Distinct,
    From,
    Where,
    Insert,
    Into,
    Replace,
    Ignore,
    Update,
    Delete,
    Duplicate,
    Create,
    Table,
    Truncate,
    Drop,
    Alter,
    And,
    Or,
    Not,
    Null,
    True,
    False,
    As,
    Join,
    Left,
    Right,
    Inner,
    Outer,
    Cross,
    Full,
    Natural,
    On,
    Group,
    By,
    // OLAP extensions for GROUP BY
    Rollup,
    Cube,
    Sets,
    Grouping,
    GroupingId,
    Having,
    Order,
    Asc,
    Desc,
    Limit,
    Offset,
    Set,
    Values,
    In,
    Between,
    Asymmetric,
    Symmetric,
    Like,
    Exists,
    If,
    All,
    Any,
    Some,
    Union,
    Intersect,
    Except,
    With,
    Recursive,
    Date,
    Time,
    Timestamp,
    Interval,
    Cast,
    // CASE expression keywords
    Case,
    When,
    Then,
    Else,
    End,
    // Window function keywords
    Over,
    Partition,
    Rows,
    Range,
    Preceding,
    Following,
    Unbounded,
    Current,
    // Note: Window function names (ROW_NUMBER, RANK, etc.) are identifiers, not keywords
    // Constraint keywords
    Primary,
    Foreign,
    Key,
    Unique,
    Check,
    References,
    // IS NULL keywords
    Is,
    // Transaction keywords
    Begin,
    Commit,
    Rollback,
    // SCHEMA keywords
    Cascade,
    Restrict,
    Schema,
    Start,
    Transaction,
    // ALTER TABLE keywords
    Add,
    Column,
    Constraint,
    Default,
    Rename,
    Modify,
    Change,
    // SAVEPOINT keywords
    Savepoint,
    Release,
    To,
    // Role management keywords
    Role,
    // TRIM function keywords
    Both,
    Leading,
    Trailing,
    // MySQL arithmetic operators
    Div,
    // Data type keywords
    Varying,
    Characters,
    Octets,
    Using,
    // SUBSTRING function keywords
    For,
    // Current date/time function keywords
    CurrentDate,
    CurrentTime,
    CurrentTimestamp,
    // GRANT keywords
    Grant,
    Privileges,
    Usage,
    Option,
    // REVOKE keywords
    Revoke,
    Granted,
    // Advanced privilege keywords
    Execute,
    Trigger,
    Under,
    // Advanced SQL object keywords
    Domain,
    Sequence,
    Type,
    Collation,
    Character,
    Translation,
    View,
    Index,
    Analyze,
    Reindex,
    Explain,
    Assertion,
    Specific,
    // Trigger-specific keywords
    Before,
    After,
    Instead,
    Of,
    Each,
    Row,
    Statement,
    Enable,
    Disable,
    // SEQUENCE specific keywords
    Increment,
    Minvalue,
    Maxvalue,
    Cycle,
    No,
    Restart,
    Next,
    // Referential action keywords
    Action,
    // Session configuration keywords (SQL:1999)
    Catalog,
    Names,
    Zone,
    Local,
    Session,
    Global,
    // Interval unit keywords
    Year,
    Quarter,
    Month,
    Week,
    Day,
    Hour,
    Minute,
    Second,
    Microsecond,
    // Callable object keywords (functions, procedures, methods)
    Function,
    Procedure,
    Call,
    Routine,
    Method,
    Constructor,
    Static,
    Instance,
    // Procedure/Function parameter modes
    Out,
    InOut,
    // Procedure/Function keywords
    Returns,
    While,
    Do,
    Loop,
    Repeat,
    Until,
    Return,
    Leave,
    Iterate,
    // Procedure/Function characteristics (Phase 6)
    Deterministic,
    Language,
    Sql,
    Security,
    Definer,
    Invoker,
    // Internationalization keywords (SQL:1999)
    Get,
    Pad,
    Space,
    Collate,
    // CURSOR keywords
    Declare,
    Cursor,
    Insensitive,
    // Prepared statement keywords
    Prepare,
    Deallocate,
    Scroll,
    Hold,
    Without,
    Read,
    Only,
    Oids,
    Open,
    Fetch,
    Close,
    Prior,
    First,
    Last,
    Absolute,
    Relative,
    Serializable,
    Isolation,
    Level,
    Write,
    Comment,
    // MySQL table option keywords
    KeyBlockSize,
    Connection,
    InsertMethod,
    RowFormat,
    DelayKeyWrite,
    TableChecksum,
    Checksum,
    StatsSamplePages,
    Password,
    AvgRowLength,
    MinRows,
    MaxRows,
    SecondaryEngine,
    // MySQL table option values
    Dynamic,
    Fixed,
    Compressed,
    Redundant,
    Compact,
    // Full-text search keywords
    Fulltext,
    Match,
    Against,
    Boolean,
    Expansion,
    Mode,
    Query,
    // Spatial index keywords
    Spatial,
    // Vector index keywords (IVFFlat, HNSW)
    Ivfflat,
    Hnsw,
    Lists,
    Probes,
    EfConstruction,
    EfSearch,
    M,
    // Database introspection keywords
    Show,
    Describe,
    Databases,
    Tables,
    Columns,
    Fields,
    Indexes,
    Keys,
    // Auto-increment keywords (MySQL and SQLite)
    AutoIncrement,
    // Temporary object keywords (SQLite)
    Temp,
    Temporary,
    // VibeSQL storage format keywords
    Storage,
    Columnar,
}

impl Keyword {
    /// Returns true if this keyword can be used as an unquoted column or table name.
    /// These are "unreserved" keywords that are only treated as keywords in specific contexts.
    ///
    /// This follows SQLite's behavior where temporal type keywords (TIMESTAMP, DATE, TIME, INTERVAL)
    /// and interval unit keywords (YEAR, MONTH, DAY, etc.) can be used as identifiers without quoting.
    pub fn can_be_identifier(&self) -> bool {
        matches!(
            self,
            // Temporal type keywords
            Keyword::Timestamp | Keyword::Date | Keyword::Time | Keyword::Interval |
            // Interval unit keywords (used in EXTRACT, DATE_ADD, etc. but also valid as identifiers)
            Keyword::Year | Keyword::Quarter | Keyword::Month | Keyword::Week |
            Keyword::Day | Keyword::Hour | Keyword::Minute | Keyword::Second |
            Keyword::Microsecond
        )
    }
}

impl fmt::Display for Keyword {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let keyword_str = match self {
            Keyword::Select => "SELECT",
            Keyword::Distinct => "DISTINCT",
            Keyword::From => "FROM",
            Keyword::Where => "WHERE",
            Keyword::Insert => "INSERT",
            Keyword::Into => "INTO",
            Keyword::Replace => "REPLACE",
            Keyword::Ignore => "IGNORE",
            Keyword::Update => "UPDATE",
            Keyword::Delete => "DELETE",
            Keyword::Duplicate => "DUPLICATE",
            Keyword::Create => "CREATE",
            Keyword::Table => "TABLE",
            Keyword::Truncate => "TRUNCATE",
            Keyword::Drop => "DROP",
            Keyword::Alter => "ALTER",
            Keyword::And => "AND",
            Keyword::Or => "OR",
            Keyword::Not => "NOT",
            Keyword::Null => "NULL",
            Keyword::True => "TRUE",
            Keyword::False => "FALSE",
            Keyword::As => "AS",
            Keyword::Join => "JOIN",
            Keyword::Left => "LEFT",
            Keyword::Right => "RIGHT",
            Keyword::Inner => "INNER",
            Keyword::Outer => "OUTER",
            Keyword::Cross => "CROSS",
            Keyword::Full => "FULL",
            Keyword::Natural => "NATURAL",
            Keyword::On => "ON",
            Keyword::Group => "GROUP",
            Keyword::By => "BY",
            Keyword::Rollup => "ROLLUP",
            Keyword::Cube => "CUBE",
            Keyword::Sets => "SETS",
            Keyword::Grouping => "GROUPING",
            Keyword::GroupingId => "GROUPING_ID",
            Keyword::Having => "HAVING",
            Keyword::Order => "ORDER",
            Keyword::Asc => "ASC",
            Keyword::Desc => "DESC",
            Keyword::Limit => "LIMIT",
            Keyword::Offset => "OFFSET",
            Keyword::Set => "SET",
            Keyword::Values => "VALUES",
            Keyword::In => "IN",
            Keyword::Between => "BETWEEN",
            Keyword::Asymmetric => "ASYMMETRIC",
            Keyword::Symmetric => "SYMMETRIC",
            Keyword::Like => "LIKE",
            Keyword::Exists => "EXISTS",
            Keyword::If => "IF",
            Keyword::All => "ALL",
            Keyword::Any => "ANY",
            Keyword::Some => "SOME",
            Keyword::Union => "UNION",
            Keyword::Intersect => "INTERSECT",
            Keyword::Except => "EXCEPT",
            Keyword::With => "WITH",
            Keyword::Recursive => "RECURSIVE",
            Keyword::Date => "DATE",
            Keyword::Time => "TIME",
            Keyword::Timestamp => "TIMESTAMP",
            Keyword::Interval => "INTERVAL",
            Keyword::Cast => "CAST",
            Keyword::Case => "CASE",
            Keyword::When => "WHEN",
            Keyword::Then => "THEN",
            Keyword::Else => "ELSE",
            Keyword::End => "END",
            Keyword::Over => "OVER",
            Keyword::Partition => "PARTITION",
            Keyword::Rows => "ROWS",
            Keyword::Range => "RANGE",
            Keyword::Preceding => "PRECEDING",
            Keyword::Following => "FOLLOWING",
            Keyword::Unbounded => "UNBOUNDED",
            Keyword::Current => "CURRENT",
            Keyword::Primary => "PRIMARY",
            Keyword::Foreign => "FOREIGN",
            Keyword::Key => "KEY",
            Keyword::Unique => "UNIQUE",
            Keyword::Check => "CHECK",
            Keyword::References => "REFERENCES",
            Keyword::Is => "IS",
            Keyword::Begin => "BEGIN",
            Keyword::Commit => "COMMIT",
            Keyword::Rollback => "ROLLBACK",
            Keyword::Cascade => "CASCADE",
            Keyword::Restrict => "RESTRICT",
            Keyword::Schema => "SCHEMA",
            Keyword::Start => "START",
            Keyword::Transaction => "TRANSACTION",
            Keyword::Add => "ADD",
            Keyword::Column => "COLUMN",
            Keyword::Constraint => "CONSTRAINT",
            Keyword::Default => "DEFAULT",
            Keyword::Rename => "RENAME",
            Keyword::Modify => "MODIFY",
            Keyword::Change => "CHANGE",
            Keyword::Savepoint => "SAVEPOINT",
            Keyword::Release => "RELEASE",
            Keyword::To => "TO",
            Keyword::Role => "ROLE",
            Keyword::Both => "BOTH",
            Keyword::Leading => "LEADING",
            Keyword::Trailing => "TRAILING",
            Keyword::Div => "DIV",
            Keyword::Varying => "VARYING",
            Keyword::Characters => "CHARACTERS",
            Keyword::Octets => "OCTETS",
            Keyword::Using => "USING",
            Keyword::For => "FOR",
            Keyword::CurrentDate => "CURRENT_DATE",
            Keyword::CurrentTime => "CURRENT_TIME",
            Keyword::CurrentTimestamp => "CURRENT_TIMESTAMP",
            Keyword::Grant => "GRANT",
            Keyword::Privileges => "PRIVILEGES",
            Keyword::Usage => "USAGE",
            Keyword::Option => "OPTION",
            Keyword::Revoke => "REVOKE",
            Keyword::Granted => "GRANTED",
            Keyword::Execute => "EXECUTE",
            Keyword::Trigger => "TRIGGER",
            Keyword::Under => "UNDER",
            Keyword::Domain => "DOMAIN",
            Keyword::Sequence => "SEQUENCE",
            Keyword::Type => "TYPE",
            Keyword::Collation => "COLLATION",
            Keyword::Character => "CHARACTER",
            Keyword::Translation => "TRANSLATION",
            Keyword::View => "VIEW",
            Keyword::Index => "INDEX",
            Keyword::Analyze => "ANALYZE",
            Keyword::Reindex => "REINDEX",
            Keyword::Explain => "EXPLAIN",
            Keyword::Assertion => "ASSERTION",
            Keyword::Specific => "SPECIFIC",
            Keyword::Before => "BEFORE",
            Keyword::After => "AFTER",
            Keyword::Instead => "INSTEAD",
            Keyword::Of => "OF",
            Keyword::Each => "EACH",
            Keyword::Row => "ROW",
            Keyword::Statement => "STATEMENT",
            Keyword::Enable => "ENABLE",
            Keyword::Disable => "DISABLE",
            Keyword::Increment => "INCREMENT",
            Keyword::Minvalue => "MINVALUE",
            Keyword::Maxvalue => "MAXVALUE",
            Keyword::Cycle => "CYCLE",
            Keyword::No => "NO",
            Keyword::Restart => "RESTART",
            Keyword::Next => "NEXT",
            Keyword::Action => "ACTION",
            Keyword::Catalog => "CATALOG",
            Keyword::Names => "NAMES",
            Keyword::Zone => "ZONE",
            Keyword::Local => "LOCAL",
            Keyword::Session => "SESSION",
            Keyword::Global => "GLOBAL",
            Keyword::Year => "YEAR",
            Keyword::Quarter => "QUARTER",
            Keyword::Month => "MONTH",
            Keyword::Week => "WEEK",
            Keyword::Day => "DAY",
            Keyword::Hour => "HOUR",
            Keyword::Minute => "MINUTE",
            Keyword::Second => "SECOND",
            Keyword::Microsecond => "MICROSECOND",
            Keyword::Function => "FUNCTION",
            Keyword::Procedure => "PROCEDURE",
            Keyword::Call => "CALL",
            Keyword::Routine => "ROUTINE",
            Keyword::Method => "METHOD",
            Keyword::Constructor => "CONSTRUCTOR",
            Keyword::Static => "STATIC",
            Keyword::Instance => "INSTANCE",
            Keyword::Out => "OUT",
            Keyword::InOut => "INOUT",
            Keyword::Returns => "RETURNS",
            Keyword::While => "WHILE",
            Keyword::Do => "DO",
            Keyword::Loop => "LOOP",
            Keyword::Repeat => "REPEAT",
            Keyword::Until => "UNTIL",
            Keyword::Return => "RETURN",
            Keyword::Leave => "LEAVE",
            Keyword::Iterate => "ITERATE",
            Keyword::Deterministic => "DETERMINISTIC",
            Keyword::Language => "LANGUAGE",
            Keyword::Sql => "SQL",
            Keyword::Security => "SECURITY",
            Keyword::Definer => "DEFINER",
            Keyword::Invoker => "INVOKER",
            Keyword::Comment => "COMMENT",
            Keyword::Get => "GET",
            Keyword::Pad => "PAD",
            Keyword::Space => "SPACE",
            Keyword::Collate => "COLLATE",
            Keyword::Declare => "DECLARE",
            Keyword::Cursor => "CURSOR",
            Keyword::Insensitive => "INSENSITIVE",
            Keyword::Prepare => "PREPARE",
            Keyword::Deallocate => "DEALLOCATE",
            Keyword::Scroll => "SCROLL",
            Keyword::Hold => "HOLD",
            Keyword::Without => "WITHOUT",
            Keyword::Read => "READ",
            Keyword::Only => "ONLY",
            Keyword::Oids => "OIDS",
            Keyword::Open => "OPEN",
            Keyword::Fetch => "FETCH",
            Keyword::Close => "CLOSE",
            Keyword::Prior => "PRIOR",
            Keyword::First => "FIRST",
            Keyword::Last => "LAST",
            Keyword::Absolute => "ABSOLUTE",
            Keyword::Relative => "RELATIVE",
            Keyword::Serializable => "SERIALIZABLE",
            Keyword::Isolation => "ISOLATION",
            Keyword::Level => "LEVEL",
            Keyword::Write => "WRITE",
            // MySQL table option keywords
            Keyword::KeyBlockSize => "KEY_BLOCK_SIZE",
            Keyword::Connection => "CONNECTION",
            Keyword::InsertMethod => "INSERT_METHOD",
            Keyword::RowFormat => "ROW_FORMAT",
            Keyword::DelayKeyWrite => "DELAY_KEY_WRITE",
            Keyword::TableChecksum => "TABLE_CHECKSUM",
            Keyword::Checksum => "CHECKSUM",
            Keyword::StatsSamplePages => "STATS_SAMPLE_PAGES",
            Keyword::Password => "PASSWORD",
            Keyword::AvgRowLength => "AVG_ROW_LENGTH",
            Keyword::MinRows => "MIN_ROWS",
            Keyword::MaxRows => "MAX_ROWS",
            Keyword::SecondaryEngine => "SECONDARY_ENGINE",
            // MySQL table option values
            Keyword::Dynamic => "DYNAMIC",
            Keyword::Fixed => "FIXED",
            Keyword::Compressed => "COMPRESSED",
            Keyword::Redundant => "REDUNDANT",
            Keyword::Compact => "COMPACT",
            // Full-text search keywords
            Keyword::Fulltext => "FULLTEXT",
            Keyword::Match => "MATCH",
            Keyword::Against => "AGAINST",
            Keyword::Boolean => "BOOLEAN",
            Keyword::Expansion => "EXPANSION",
            Keyword::Mode => "MODE",
            Keyword::Query => "QUERY",
            // Spatial index keywords
            Keyword::Spatial => "SPATIAL",
            // Vector index keywords (IVFFlat, HNSW)
            Keyword::Ivfflat => "IVFFLAT",
            Keyword::Hnsw => "HNSW",
            Keyword::Lists => "LISTS",
            Keyword::Probes => "PROBES",
            Keyword::EfConstruction => "EF_CONSTRUCTION",
            Keyword::EfSearch => "EF_SEARCH",
            Keyword::M => "M",
            // Database introspection keywords
            Keyword::Show => "SHOW",
            Keyword::Describe => "DESCRIBE",
            Keyword::Databases => "DATABASES",
            Keyword::Tables => "TABLES",
            Keyword::Columns => "COLUMNS",
            Keyword::Fields => "FIELDS",
            Keyword::Indexes => "INDEXES",
            Keyword::Keys => "KEYS",
            // Auto-increment keywords
            Keyword::AutoIncrement => "AUTO_INCREMENT",
            // Temporary object keywords
            Keyword::Temp => "TEMP",
            Keyword::Temporary => "TEMPORARY",
            // VibeSQL storage format keywords
            Keyword::Storage => "STORAGE",
            Keyword::Columnar => "COLUMNAR",
        };
        write!(f, "{}", keyword_str)
    }
}
