use crate::css_values::types::{
    color::Color, custom::VarReference, display::*, font::*, length::*,
    transform::TransformFunction,
};

/// Identifies a CSS property by name.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PropertyId {
    Display,
    Position,
    Width,
    Height,
    MinWidth,
    MinHeight,
    MaxWidth,
    MaxHeight,
    MarginTop,
    MarginRight,
    MarginBottom,
    MarginLeft,
    PaddingTop,
    PaddingRight,
    PaddingBottom,
    PaddingLeft,
    BorderTopWidth,
    BorderRightWidth,
    BorderBottomWidth,
    BorderLeftWidth,
    BoxSizing,
    OverflowX,
    OverflowY,
    Float,
    Clear,
    FlexDirection,
    FlexWrap,
    FlexGrow,
    FlexShrink,
    FlexBasis,
    AlignItems,
    AlignSelf,
    AlignContent,
    JustifyContent,
    JustifyItems,
    JustifySelf,
    Gap,
    RowGap,
    ColumnGap,
    FontSize,
    FontFamily,
    FontWeight,
    FontStyle,
    LineHeight,
    TextAlign,
    WhiteSpace,
    Color,
    BackgroundColor,
    Visibility,
    Opacity,
    ZIndex,
    ContentVisibility,
    Transform,
    Custom(String),
}

impl PropertyId {
    pub fn from_name(name: &str) -> Self {
        match name.to_ascii_lowercase().as_str() {
            "display" => Self::Display,
            "position" => Self::Position,
            "width" => Self::Width,
            "height" => Self::Height,
            "min-width" => Self::MinWidth,
            "min-height" => Self::MinHeight,
            "max-width" => Self::MaxWidth,
            "max-height" => Self::MaxHeight,
            "margin-top" => Self::MarginTop,
            "margin-right" => Self::MarginRight,
            "margin-bottom" => Self::MarginBottom,
            "margin-left" => Self::MarginLeft,
            "padding-top" => Self::PaddingTop,
            "padding-right" => Self::PaddingRight,
            "padding-bottom" => Self::PaddingBottom,
            "padding-left" => Self::PaddingLeft,
            "border-top-width" => Self::BorderTopWidth,
            "border-right-width" => Self::BorderRightWidth,
            "border-bottom-width" => Self::BorderBottomWidth,
            "border-left-width" => Self::BorderLeftWidth,
            "box-sizing" => Self::BoxSizing,
            "overflow-x" => Self::OverflowX,
            "overflow-y" => Self::OverflowY,
            "float" => Self::Float,
            "clear" => Self::Clear,
            "flex-direction" => Self::FlexDirection,
            "flex-wrap" => Self::FlexWrap,
            "flex-grow" => Self::FlexGrow,
            "flex-shrink" => Self::FlexShrink,
            "flex-basis" => Self::FlexBasis,
            "align-items" => Self::AlignItems,
            "align-self" => Self::AlignSelf,
            "align-content" => Self::AlignContent,
            "justify-content" => Self::JustifyContent,
            "justify-items" => Self::JustifyItems,
            "justify-self" => Self::JustifySelf,
            "gap" => Self::Gap,
            "row-gap" => Self::RowGap,
            "column-gap" => Self::ColumnGap,
            "font-size" => Self::FontSize,
            "font-family" => Self::FontFamily,
            "font-weight" => Self::FontWeight,
            "font-style" => Self::FontStyle,
            "line-height" => Self::LineHeight,
            "text-align" => Self::TextAlign,
            "white-space" => Self::WhiteSpace,
            "color" => Self::Color,
            "background-color" => Self::BackgroundColor,
            "visibility" => Self::Visibility,
            "opacity" => Self::Opacity,
            "z-index" => Self::ZIndex,
            "content-visibility" => Self::ContentVisibility,
            "transform" => Self::Transform,
            name if name.starts_with("--") => Self::Custom(name.to_string()),
            _ => Self::Custom(name.to_string()),
        }
    }
}

/// A typed CSS property value.
#[derive(Debug, Clone, PartialEq)]
pub enum CssValue {
    Initial,
    Inherit,
    Unset,
    Revert,
    RevertLayer,
    Display(Display),
    Position(Position),
    BoxSizing(BoxSizing),
    Overflow(Overflow),
    Float(Float),
    Clear(Clear),
    Visibility(Visibility),
    ContentVisibility(ContentVisibility),
    Length(Length),
    LengthPercentage(LengthPercentage),
    LengthPercentageAuto(LengthPercentageAuto),
    Number(f64),
    Integer(i32),
    Color(Color),
    FlexDirection(FlexDirection),
    FlexWrap(FlexWrap),
    Alignment(AlignmentValue),
    FontFamily(Vec<FontFamily>),
    FontWeight(FontWeight),
    FontStyle(FontStyle),
    TextAlign(TextAlign),
    WhiteSpace(WhiteSpace),
    LineHeight(LineHeight),
    Transform(Vec<TransformFunction>),
    CustomValue(String),
    Var(VarReference),
}

#[derive(Debug, Clone, PartialEq)]
pub enum LineHeight {
    Normal,
    Number(f64),
    Length(Length),
    Percentage(f64),
}

#[derive(Debug, Clone, PartialEq)]
pub struct PropertyDeclaration {
    pub property: PropertyId,
    pub value: CssValue,
    pub important: bool,
}
