use serde::{Deserialize, Serialize};
use crate::DatabaseKind;
    
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "lowercase")]
pub enum MappType {
    Text,       // 普通文本
    LongText,   // 长文本(CLOB/MEMO)
    Int,
    Float,
    Double,
    Bool,
    Date,
    Time,
    DateTime,
    Json,
    Year,
    BLOB,
    Timestamp,
    Timestamptz,
}

impl MappType {
    /// 根据数据库原始类型映射为通用类型
    pub fn from_db_type(type_name: &str) -> Self {
        let mut t = type_name.trim().to_lowercase();
        if let Some(idx) = t.find('(') {
            t.truncate(idx);
        }

        t = t
            .replace("without time zone", "")
            .replace("with time zone", "")
            .replace("unsigned", "")
            .replace(" ", "");

        match t.as_str() {
            // --- 整数 ---
            "int" | "int2" | "int4" | "int8" | "integer" | "smallint" | "bigint" | "tinyint"
            | "mediumint" | "serial" | "bigserial" | "number" | "signed" | "unsignedbigint"
            | "unsignedint" | "identity" | "counter" => Self::Int,

            // --- 浮点/小数 ---
            "float" | "float4" | "float8" | "real" | "single" => Self::Float,
            "decimal" | "numeric" | "double" | "doubleprecision" | "money" | "dec" => Self::Double,

            // --- 布尔 ---
            "bool" | "boolean" | "bit" | "yesno" => Self::Bool,

            // --- 短文本 ---
            "text" | "varchar" | "char" | "bpchar" | "citext" | "nchar" | "nvarchar"
            | "nvarchar2" | "nationalchar" | "nationalvarchar" | "uuid" | "name"
            | "xml" | "inet" | "cidr" | "macaddr" | "character" | "charactervarying"
            | "string" => Self::Text,

            // --- 长文本 ---
            "clob" | "nclob" | "memo" | "tinytext" | "mediumtext" | "longtext" | "ntext" => Self::LongText,

            // --- 时间类 ---
            "date" => Self::Date,
            "datetime" => Self::DateTime,
            "timestamp" => Self::Timestamp,
            "timestamptz" | "timestampwithtimezone" => Self::Timestamptz,
            "time" | "timetz" => Self::Time,
            "year" => Self::Year,

            // --- JSON ---
            "json" | "jsonb" => Self::Json,

            // --- 二进制 ---
            "blob" | "tinyblob" | "mediumblob" | "longblob" | "binary" | "varbinary"
            | "bytea" | "raw" | "longraw" | "image" | "bfile" | "oleobject" => Self::BLOB,

            // --- 其他杂项 ---
            "interval" | "cursor" | "rowid" | "oid" => Self::Text,

            _ => Self::Text,
        }
    }

    /// 通用类型映射到数据库类型
    pub fn to_db_type(&self, db: &DatabaseKind) -> &'static str {
        match db {
            // MySQL
            DatabaseKind::MySql => match self {
                Self::Int => "INT",
                Self::Float => "FLOAT",
                Self::Double => "DOUBLE",
                Self::Bool => "TINYINT(1)",
                Self::Text => "TEXT",
                Self::LongText => "LONGTEXT",
                Self::Date => "DATE",
                Self::Time => "TIME",
                Self::DateTime => "DATETIME",
                Self::Timestamp => "TIMESTAMP",
                Self::Timestamptz => "TIMESTAMP",
                Self::Json => "JSON",
                Self::Year => "YEAR",
                Self::BLOB => "BLOB",
            },

            // PostgreSQL
            DatabaseKind::Postgres => match self {
                Self::Int => "INTEGER",
                Self::Float => "REAL",
                Self::Double => "DOUBLE PRECISION",
                Self::Bool => "BOOLEAN",
                Self::Text => "TEXT",
                Self::LongText => "TEXT",
                Self::Date => "DATE",
                Self::Time => "TIME",
                Self::DateTime => "TIMESTAMP",
                Self::Timestamp => "TIMESTAMP",
                Self::Timestamptz => "TIMESTAMPTZ",
                Self::Json => "JSONB",
                Self::Year => "INTEGER",
                Self::BLOB => "BYTEA",
            },

            // SQLite
            DatabaseKind::Sqlite => match self {
                Self::Int => "INTEGER",
                Self::Float => "REAL",
                Self::Double => "NUMERIC",
                Self::Bool => "INTEGER",
                Self::Text => "TEXT",
                Self::LongText => "TEXT",
                Self::Date => "TEXT",
                Self::Time => "TEXT",
                Self::DateTime => "TEXT",
                Self::Timestamp => "TEXT",
                Self::Timestamptz => "TEXT",
                Self::Json => "TEXT",
                Self::Year => "INTEGER",
                Self::BLOB => "BLOB",
            },

            // SQL Server
            DatabaseKind::SqlServer => match self {
                Self::Int => "INT",
                Self::Float => "FLOAT",
                Self::Double => "DECIMAL(18,6)",
                Self::Bool => "BIT",
                Self::Text => "NVARCHAR(255)",
                Self::LongText => "NTEXT",
                Self::Date => "DATE",
                Self::Time => "TIME",
                Self::DateTime => "DATETIME2",
                Self::Timestamp => "DATETIME",
                Self::Timestamptz => "DATETIMEOFFSET",
                Self::Json => "NVARCHAR(MAX)",
                Self::Year => "SMALLINT",
                Self::BLOB => "VARBINARY(MAX)",
            },

            // Access
            DatabaseKind::Access => match self {
                Self::Int => "LONG",
                Self::Float => "SINGLE",
                Self::Double => "DOUBLE",
                Self::Bool => "YESNO",
                Self::Text => "TEXT(255)",
                Self::LongText => "MEMO",
                Self::Date => "DATETIME",
                Self::Time => "DATETIME",
                Self::DateTime => "DATETIME",
                Self::Timestamp => "DATETIME",
                Self::Timestamptz => "DATETIME",
                Self::Json => "MEMO",
                Self::Year => "INTEGER",
                Self::BLOB => "OLEOBJECT",
            },

            _ => "TEXT",
        }
    }
}


#[test] 
fn asfd (){


}