package ui

// Size is the canonical component size enum. Phase 1 only renders SizeMD via
// CSS, but every component normalizes Size so future phases can drop in
// `.ui-button-...-sm` / `.ui-button-...-lg` rules without changing call sites.
type Size string

const (
	SizeSM Size = "sm"
	SizeMD Size = "md"
	SizeLG Size = "lg"
)

// ButtonVariant is the semantic-color enum for Button.
type ButtonVariant string

const (
	ButtonVariantDefault ButtonVariant = "default"
	ButtonVariantNeutral ButtonVariant = "neutral"
	ButtonVariantWarning ButtonVariant = "warning"
	ButtonVariantSuccess ButtonVariant = "success"
	ButtonVariantDanger  ButtonVariant = "danger"
	ButtonVariantGhost   ButtonVariant = "ghost"
)

// ButtonTone is the visual-weight enum for Button (solid vs. soft).
type ButtonTone string

const (
	ButtonToneSolid ButtonTone = "solid"
	ButtonToneSoft  ButtonTone = "soft"
)

// BadgeVariant is the semantic-color enum for Badge.
type BadgeVariant string

const (
	BadgeVariantInfo    BadgeVariant = "info"
	BadgeVariantWarning BadgeVariant = "warning"
	BadgeVariantSuccess BadgeVariant = "success"
	BadgeVariantDanger  BadgeVariant = "danger"
	BadgeVariantPrimary BadgeVariant = "primary"
)

// IconButtonVariant is the semantic-color enum for IconButton.
type IconButtonVariant string

const (
	IconButtonVariantNeutral IconButtonVariant = "neutral"
	IconButtonVariantWarning IconButtonVariant = "warning"
	IconButtonVariantSuccess IconButtonVariant = "success"
	IconButtonVariantDanger  IconButtonVariant = "danger"
)

// IconButtonTone is the visual-weight enum for IconButton (solid vs. ghost).
type IconButtonTone string

const (
	IconButtonToneSolid IconButtonTone = "solid"
	IconButtonToneGhost IconButtonTone = "ghost"
)

// SpacingStep is the spacing size enum for space components.
type SpacingStep string

const (
	SpacingStepXS SpacingStep = "xs"
	SpacingStepSM SpacingStep = "sm"
	SpacingStepMD SpacingStep = "md"
	SpacingStepLG SpacingStep = "lg"
	SpacingStepXL SpacingStep = "xl"
)

// NormalizedSize returns the safe default (SizeMD) for the zero value and any
// value not in the declared set.
func NormalizedSize(size Size) Size {
	switch size {
	case SizeSM, SizeLG:
		return size
	default:
		return SizeMD
	}
}

// NormalizedButtonVariant returns the safe default (ButtonVariantDefault) for
// the zero value and any value not in the declared set.
func NormalizedButtonVariant(variant ButtonVariant) ButtonVariant {
	switch variant {
	case ButtonVariantNeutral, ButtonVariantWarning, ButtonVariantSuccess, ButtonVariantDanger, ButtonVariantGhost:
		return variant
	default:
		return ButtonVariantDefault
	}
}

// NormalizedButtonTone returns the safe default (ButtonToneSolid) for the zero
// value and any value not in the declared set.
func NormalizedButtonTone(tone ButtonTone) ButtonTone {
	switch tone {
	case ButtonToneSoft:
		return tone
	default:
		return ButtonToneSolid
	}
}

// NormalizedBadgeVariant returns the safe default (BadgeVariantInfo) for the
// zero value and any value not in the declared set.
func NormalizedBadgeVariant(variant BadgeVariant) BadgeVariant {
	switch variant {
	case BadgeVariantWarning, BadgeVariantSuccess, BadgeVariantDanger, BadgeVariantPrimary:
		return variant
	default:
		return BadgeVariantInfo
	}
}

// NormalizedIconButtonVariant returns the safe default (IconButtonVariantNeutral)
// for the zero value and any value not in the declared set.
func NormalizedIconButtonVariant(variant IconButtonVariant) IconButtonVariant {
	switch variant {
	case IconButtonVariantWarning, IconButtonVariantSuccess, IconButtonVariantDanger:
		return variant
	default:
		return IconButtonVariantNeutral
	}
}

// NormalizedIconButtonTone returns the safe default (IconButtonToneSolid) for
// the zero value and any value not in the declared set.
func NormalizedIconButtonTone(tone IconButtonTone) IconButtonTone {
	switch tone {
	case IconButtonToneGhost:
		return tone
	default:
		return IconButtonToneSolid
	}
}

// NormalizedSpacingStep returns the safe default (SpacingStepMD) for the zero
// value and any value not in the declared set.
func NormalizedSpacingStep(step SpacingStep) SpacingStep {
	switch step {
	case SpacingStepXS, SpacingStepSM, SpacingStepLG, SpacingStepXL:
		return step
	default:
		return SpacingStepMD
	}
}

// ButtonClass assembles the deterministic class string for a Button. Inputs
// are normalized before assembly so callers can pass zero values safely.
//
// Example: ButtonClass(ButtonVariantDefault, ButtonToneSolid, SizeMD) ==
// "ui-button ui-button-solid ui-button-default ui-button-md".
//
// Ghost variant is a special case: the tone class is omitted and "ui-button-ghost"
// is emitted as a standalone modifier.
func ButtonClass(variant ButtonVariant, tone ButtonTone, size Size) string {
	v := NormalizedButtonVariant(variant)
	s := NormalizedSize(size)
	if v == ButtonVariantGhost {
		return "ui-button ui-button-ghost ui-button-" + string(s)
	}
	t := NormalizedButtonTone(tone)
	return "ui-button ui-button-" + string(t) + " ui-button-" + string(v) + " ui-button-" + string(s)
}

// BadgeClass assembles the deterministic class string for a Badge.
//
// Example: BadgeClass(BadgeVariantInfo) == "ui-badge ui-badge-info".
func BadgeClass(variant BadgeVariant) string {
	v := NormalizedBadgeVariant(variant)
	return "ui-badge ui-badge-" + string(v)
}

// IconButtonClass assembles the deterministic class string for an IconButton.
// Ghost tone uses the borderless pattern; solid tone uses the filled pattern.
func IconButtonClass(variant IconButtonVariant, tone IconButtonTone) string {
	normalizedVariant := NormalizedIconButtonVariant(variant)
	switch NormalizedIconButtonTone(tone) {
	case IconButtonToneGhost:
		return "borderless-icon-button ui-icon-button-ghost ui-icon-button-" + string(normalizedVariant)
	default:
		return "ui-icon-button ui-icon-button-solid ui-icon-button-" + string(normalizedVariant)
	}
}

// SpaceXClass assembles the deterministic class string for a horizontal spacer.
//
// Example: SpaceXClass(SpacingStepMD) == "ui-space-x ui-space-x-md".
func SpaceXClass(step SpacingStep) string {
	return "ui-space-x ui-space-x-" + string(NormalizedSpacingStep(step))
}

// SpaceYClass assembles the deterministic class string for a vertical spacer.
//
// Example: SpaceYClass(SpacingStepLG) == "ui-space-y ui-space-y-lg".
func SpaceYClass(step SpacingStep) string {
	return "ui-space-y ui-space-y-" + string(NormalizedSpacingStep(step))
}
