use crate::keywords::Keyword;
use phf::phf_map;

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

/// Map an uppercase string to its corresponding Keyword using perfect hash lookup.
/// Returns None if the string is not a recognized keyword.
#[inline]
pub(super) fn map_keyword(upper_text: &str) -> Option<Keyword> {
    KEYWORDS.get(upper_text).copied()
}
