@use 'sass:map';
@use '@mezzanine-ui/system/palette';
@use '@mezzanine-ui/system/radius';
@use '@mezzanine-ui/system/spacing';
@use '@mezzanine-ui/system/transition';
@use '@mezzanine-ui/system/effect';
@use '../_internal/input-check';
@use './checkbox' as *;

$indeterminate-line-width: 6px !default;
$indeterminate-line-width-small: 5px !default;
$indeterminate-line-height: 1px !default;

// Mode configurations
$mode-configs: (
  main: (
    padding-block: spacing.semantic-variable(padding, vertical, calm),
    label-color: none,
    label-color-disabled: none,
  ),
  sub: (
    padding-block: spacing.semantic-variable(padding, vertical, tight),
    label-color: none,
    label-color-disabled: none,
  ),
  chip: (
    padding-block: none,
    label-color: palette.semantic-variable(text, neutral-solid),
    label-color-disabled: palette.semantic-variable(text, neutral-light),
  ),
);

// Chip size configurations for padding
$chip-size-configs: (
  main: (
    padding-vertical: spacing.semantic-variable(padding, vertical, calm),
    padding-left-unchecked: spacing.semantic-variable(padding, horizontal, cozy),
    padding-right-unchecked: spacing.semantic-variable(padding, horizontal, cozy),
    padding-left-checked: spacing.semantic-variable(padding, horizontal, base),
    padding-right-checked: spacing.semantic-variable(padding, horizontal, cozy),
  ),
  sub: (
    padding-vertical: spacing.semantic-variable(padding, vertical, tight),
    padding-left-unchecked: spacing.semantic-variable(padding, horizontal, base),
    padding-right-unchecked: spacing.semantic-variable(padding, horizontal, base),
    padding-left-checked: spacing.semantic-variable(padding, horizontal, tight),
    padding-right-checked: spacing.semantic-variable(padding, horizontal, base),
  ),
  minor: (
    padding-vertical: spacing.semantic-variable(padding, vertical, tiny),
    padding-left-unchecked: spacing.semantic-variable(padding, horizontal, tight),
    padding-right-unchecked: spacing.semantic-variable(padding, horizontal, tight),
    padding-left-checked: spacing.semantic-variable(padding, horizontal, tiny),
    padding-right-checked: spacing.semantic-variable(padding, horizontal, tight),
  ),
);

$chip-host-states: (
  base: (
    border: 1px solid palette.semantic-variable(border, neutral-faint),
    background: palette.semantic-variable(background, base),
    gap: 0,
  ),
  checked: (
    border-color: palette.semantic-variable(border, brand),
    background-color: palette.semantic-variable(background, brand-ghost),
    gap: spacing.semantic-variable(gap, tight),
  ),
  disabled: (
    border-color: palette.semantic-variable(border, neutral-light),
    background-color: palette.semantic-variable(background, neutral-subtle),
  ),
  hover-unchecked: (
    border-color: palette.semantic-variable(border, brand),
    background: palette.semantic-variable(background, base),
  ),
  hover-checked: (
    border-color: palette.semantic-variable(border, brand),
  ),
);

// Get mode property value
@function _get-mode-property($mode-map, $property) {
  $value: map.get($mode-map, $property);

  @if $value == none {
    @return null;
  } @else {
    @return $value;
  }
}

// Apply mode styles
@mixin _apply-mode-styles($mode) {
  $mode-config: map.get($mode-configs, $mode);
  $padding-block: _get-mode-property($mode-config, padding-block);

  @if $padding-block {
    padding-block: $padding-block;
  }
}

// Apply mode styles when checked
@mixin _apply-mode-styles-checked($mode, $size: null) {
  // For chip mode, use size-specific padding
  @if $mode == 'chip' and $size {
    $size-config: map.get($chip-size-configs, $size);
    $padding-vertical: _get-mode-property($size-config, padding-vertical);
    $padding-left-checked: _get-mode-property($size-config, padding-left-checked);
    $padding-right-checked: _get-mode-property($size-config, padding-right-checked);

    @if $padding-vertical {
      padding-top: $padding-vertical;
      padding-bottom: $padding-vertical;
    }
    @if $padding-left-checked {
      padding-left: $padding-left-checked;
    }
    @if $padding-right-checked {
      padding-right: $padding-right-checked;
    }
  } @else {
    // For non-chip modes, use original logic
    $mode-config: map.get($mode-configs, $mode);
    $padding-vertical: _get-mode-property($mode-config, input-padding-vertical);

    @if $padding-vertical {
      padding-top: $padding-vertical;
      padding-bottom: $padding-vertical;
    }
  }
}

// Apply mode label color styles
@mixin _apply-mode-label-colors($mode) {
  $mode-config: map.get($mode-configs, $mode);
  $label-color: _get-mode-property($mode-config, label-color);
  $label-color-disabled: _get-mode-property($mode-config, label-color-disabled);

  @if $label-color {
    --mzn-typography-color: #{$label-color};
  }

  &.#{$prefix}--disabled {
    @if $label-color-disabled {
      --mzn-typography-color: #{$label-color-disabled};
    }
  }
}

// Apply mode input content padding styles
@mixin _apply-mode-input-padding($mode, $size: null) {
  // For chip mode, use size-specific padding
  @if $mode == 'chip' and $size {
    $size-config: map.get($chip-size-configs, $size);
    $padding-vertical: _get-mode-property($size-config, padding-vertical);
    $padding-left-unchecked: _get-mode-property($size-config, padding-left-unchecked);
    $padding-right-unchecked: _get-mode-property($size-config, padding-right-unchecked);

    @if $padding-vertical and $padding-left-unchecked and $padding-right-unchecked {
      padding: $padding-vertical $padding-right-unchecked $padding-vertical $padding-left-unchecked;
    }
  } @else {
    // For non-chip modes, use original logic
    $mode-config: map.get($mode-configs, $mode);
    $padding-horizontal: _get-mode-property($mode-config, input-padding-horizontal);
    $padding-vertical: _get-mode-property($mode-config, input-padding-vertical);
    @if $padding-horizontal and $padding-vertical {
      padding: $padding-vertical $padding-horizontal;
    }
  }
}

// Apply chip host state styles
@mixin _apply-chip-host-styles($state) {
  $state-config: map.get($chip-host-states, $state);

  @if $state-config {
    @each $property, $value in $state-config {
      #{$property}: $value;
    }
  }
}

// Disabled state configurations (enable/hover are handled via CSS variables)
$unchecked-disabled: (
  background-color: palette.semantic-variable(background, neutral-subtle),
  border-color: palette.semantic-variable(border, neutral-light),
);

$checked-disabled: (
  background-color: palette.semantic-variable(background, neutral-subtle),
  border-color: palette.semantic-variable(background, neutral-subtle),
);

// Get color value from state map
@function _get-state-color($state-map, $property) {
  $value: map.get($state-map, $property);

  @if $value == none {
    @return null;
  } @else {
    @return $value;
  }
}

// Apply state colors to input
@mixin _apply-input-state-colors($state-map) {
  $bg: _get-state-color($state-map, background-color);
  $border: _get-state-color($state-map, border-color);

  @if $bg {
    background-color: $bg;
  }

  @if $border {
    border-color: $border;
  }
}

@mixin checkbox-indeterminate-line {
  background-color: var(--#{$prefix}-on-color);
  opacity: 1;
  top: 50%;
  left: 50%;
  width: var(--#{$prefix}-indeterminate-line-width);
  height: $indeterminate-line-height;
  transform: translate(-50%, -50%);
  border: none;
}

.#{$prefix} {
  --#{$prefix}-color: var(
    --#{input-check.$prefix}-color,
    #{palette.semantic-variable(background, brand)}
  );
  --#{$prefix}-on-color: var(
    --#{input-check.$prefix}-on-color,
    #{palette.semantic-variable(icon, fixed-light)}
  );
  --#{$prefix}-indeterminate-line-width: #{$indeterminate-line-width};

  // Severity color variables — override these to change the visual theme
  --#{$prefix}-unchecked-border: #{palette.semantic-variable(border, neutral)};
  --#{$prefix}-unchecked-border-hover: #{palette.semantic-variable(border, brand)};
  --#{$prefix}-checked-bg: #{palette.semantic-variable(background, brand)};
  --#{$prefix}-checked-bg-hover: #{palette.semantic-variable(background, brand-strong)};
  --#{$prefix}-focus-shadow: #{effect.variable(focus, primary)};

  position: relative;
  width: fit-content;
  height: fit-content;
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  gap: spacing.semantic-variable(gap, base);

  &:has(.#{$prefix}__editable-input-container) {
    align-items: center;
  }

  &--main {
    .#{$prefix}__label-container {
      gap: spacing.semantic-variable(gap, slim);
    }
  }

  &__label-container {
    display: flex;
    align-items: flex-start;
    cursor: pointer;
    gap: spacing.semantic-variable(gap, tight);
  }

  &:has(.#{$prefix}__text-container) {
    &.#{$prefix}--main {
      @include _apply-mode-styles(main);
    }

    &.#{$prefix}--sub {
      @include _apply-mode-styles(sub);
    }

    &.#{$prefix}--chip {
      @include _apply-mode-styles(chip);
      @include _apply-chip-host-styles(base);

      cursor: pointer;
      transition:
        transition.standard(border-color, fast),
        transition.standard(background-color, fast),
        transition.standard(box-shadow, fast);

      // Chip mode unchecked: no gap in label-container
      &:not(.#{$prefix}--checked) {
        .#{$prefix}__label-container {
          gap: 0;
        }
      }

      // Chip mode with different sizes - unchecked state
      &.#{$prefix}--main {
        @include _apply-mode-input-padding(chip, main);

        border-radius: radius.variable(base);
      }

      &.#{$prefix}--sub {
        @include _apply-mode-input-padding(chip, sub);

        border-radius: radius.variable(tiny);
      }

      &.#{$prefix}--minor {
        @include _apply-mode-input-padding(chip, minor);

        border-radius: radius.variable(tiny);
      }

      // Chip mode checked state
      &.#{$prefix}--checked {
        @include _apply-chip-host-styles(checked);

        &.#{$prefix}--main {
          @include _apply-mode-styles-checked(chip, main);
        }

        &.#{$prefix}--sub {
          @include _apply-mode-styles-checked(chip, sub);
        }

        &.#{$prefix}--minor {
          @include _apply-mode-styles-checked(chip, minor);
        }
      }

      // Chip mode disabled state
      &.#{$prefix}--disabled,
      .#{input-check.$prefix}--disabled & {
        @include _apply-chip-host-styles(disabled);

        cursor: not-allowed;
      }
    }
  }

  &__input-container {
    display: flex;
    align-items: center;
    height: fit-content;
  }

  &__input-content {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    cursor: pointer;
    position: relative;
    width: spacing.semantic-variable(size, element, base-fixed);
    height: spacing.semantic-variable(size, element, base-fixed);
    padding: spacing.semantic-variable(padding, horizontal, micro)
      spacing.semantic-variable(padding, horizontal, micro);

    // Chip mode: width and height should be auto
    .#{$prefix}--chip & {
      width: auto;
      height: auto;
      padding: 0;
    }

    // Chip mode checked: padding should be 0
    .#{$prefix}--chip.#{$prefix}--checked & {
      padding: 0;
    }
  }

  &__icon {
    pointer-events: none;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    // set the checkmark icon thickness
    svg {
      filter: drop-shadow(0 0 0.3px currentcolor);
    }

    path {
      stroke: currentcolor;
      stroke-width: 0.5px;
      stroke-linejoin: round;
      stroke-linecap: round;
    }

    // Chip mode checked: icon size should be 16px
    .#{$prefix}--chip.#{$prefix}--checked & {
      --mzn-icon-size: 16px;
      --mzn-icon-color: #{palette.semantic-variable(icon, brand)};

      position: relative;
      top: initial;
      left: initial;
      transform: initial;
    }

    &--chip {
      svg {
        aspect-ratio: 1 / 1;
        filter: none;
      }
    }
  }

  &__indeterminate-line {
    pointer-events: none;
    position: absolute;
    background-color: var(--#{$prefix}-on-color);
    opacity: 1;
    top: 50%;
    left: 50%;
    width: var(--#{$prefix}-indeterminate-line-width);
    height: $indeterminate-line-height;
    transform: translate(-50%, -50%);
    border: none;
    z-index: 1;
  }

  &__text-container {
    display: flex;
    flex-direction: column;
    gap: spacing.semantic-variable(gap, tight);
  }

  &__label {
    .#{$prefix}--main & {
      @include _apply-mode-label-colors(main);
    }

    .#{$prefix}--sub & {
      @include _apply-mode-label-colors(sub);
    }

    .#{$prefix}--chip & {
      @include _apply-mode-label-colors(chip);
    }
  }

  &__input {
    appearance: none;
    border: 1px solid;
    border-radius: radius.variable(tiny);
    cursor: pointer;
    height: spacing.semantic-variable(size, element, slim);
    margin: 0;
    padding: 0;
    position: relative;
    transition:
      transition.standard(border-color, fast),
      transition.standard(background-color, fast),
      transition.standard(box-shadow, fast);
    width: spacing.semantic-variable(size, element, slim);
    box-shadow: none;
    outline: none;
    z-index: 0;

    // Enable state (unchecked)
    background-color: palette.semantic-variable("background", base);
    border-color: var(--#{$prefix}-unchecked-border);

    // Checked/Indeterminate enable state
    &:checked,
    &:indeterminate {
      background-color: var(--#{$prefix}-checked-bg);
      border-color: var(--#{$prefix}-checked-bg);
    }

    &:focus-visible:not(:disabled) {
      box-shadow: var(--#{$prefix}-focus-shadow);
    }

    // Chip mode: hide native input
    .#{$prefix}--chip & {
      position: absolute;
      width: 0;
      height: 0;
      opacity: 0;
      pointer-events: none;
    }
  }
  &:has(.#{$prefix}__input:focus-visible):not(.#{$prefix}--disabled) {
    .#{$prefix}__input {
      box-shadow: var(--#{$prefix}-focus-shadow);
    }

    // Chip mode focus state
    &.#{$prefix}--chip {
      box-shadow: var(--#{$prefix}-focus-shadow);
    }
  }


  &--checked,
  &--indeterminate {
    .#{$prefix}__input {
      background-color: var(--#{$prefix}-checked-bg);
      border-color: var(--#{$prefix}-checked-bg);
    }
  }

  &--error:not(.#{$prefix}--chip) {
    --#{$prefix}-unchecked-border: #{palette.semantic-variable(border, error-subtle)};
    --#{$prefix}-unchecked-border-hover: #{palette.semantic-variable(border, error)};
    --#{$prefix}-checked-bg: #{palette.semantic-variable(background, error)};
    --#{$prefix}-checked-bg-hover: #{palette.semantic-variable(background, error-strong)};
    --#{$prefix}-focus-shadow: #{effect.variable(focus, error)};
  }

  &--disabled,
  .#{input-check.$prefix}--disabled & {
    .#{$prefix}__label-container {
      cursor: not-allowed;
    }

    .#{$prefix}__input-content {
      cursor: not-allowed;
    }

    .#{$prefix}__input {
      @include _apply-input-state-colors($unchecked-disabled);

      cursor: not-allowed;
    }

    // Chip mode disabled state (cursor only, colors handled in &:has block)
    &.#{$prefix}--chip {
      @include _apply-input-state-colors($unchecked-disabled);

      cursor: not-allowed;
    }

    &.#{$prefix}--checked,
    &.#{$prefix}--indeterminate {
      .#{$prefix}__input {
        @include _apply-input-state-colors($checked-disabled);
      }

      // Chip mode checked disabled state (colors handled in &:has block)
      &.#{$prefix}--chip {
        @include _apply-input-state-colors($checked-disabled);
      }

      .#{$prefix}__icon {
        opacity: 0.5;
      }

      .#{$prefix}__indeterminate-line {
        opacity: 0.5;
      }
    }
  }

  // Hover state
  &:hover:not(.#{$prefix}--disabled):not(.#{input-check.$prefix}--disabled &),
  .#{input-check.$prefix}:hover &:not(.#{$prefix}--disabled) {
    .#{$prefix}__input {
      &:not(:checked, :indeterminate) {
        background-color: palette.semantic-variable("background", base);
        border-color: var(--#{$prefix}-unchecked-border-hover);
      }

      &:checked,
      &:indeterminate {
        background-color: var(--#{$prefix}-checked-bg-hover);
        border-color: var(--#{$prefix}-checked-bg-hover);
      }
    }

    // Chip mode hover state (unchecked)
    &.#{$prefix}--chip {
      &:not(.#{$prefix}--checked) {
        @include _apply-chip-host-styles(hover-unchecked);
      }
    }

    &.#{$prefix}--checked,
    &.#{$prefix}--indeterminate {
      .#{$prefix}__input {
        background-color: var(--#{$prefix}-checked-bg-hover);
        border-color: var(--#{$prefix}-checked-bg-hover);
      }

      // Chip mode hover state (checked)
      &.#{$prefix}--chip {
        @include _apply-chip-host-styles(hover-checked);
      }
    }
  }

  &--disabled:hover,
  .#{input-check.$prefix}--disabled &:hover {
    .#{$prefix}__input {
      border-color: palette.semantic-variable(border, neutral-light);
    }

    &.#{$prefix}--chip {
      @include _apply-chip-host-styles(disabled);
    }
  }

  &__editable-input-container {
    width: spacing.primitive-variable(120);
  }
}

.#{input-check.$prefix} {
  &--small {
    .#{$prefix} {
      --#{$prefix}-indeterminate-line-width: #{$indeterminate-line-width-small};
    }
  }
}

.#{$group-prefix} {
  width: fit-content;
  display: flex;
  flex-direction: column;

  &--content-wrapper {
    display: flex;
    padding-left: spacing.semantic-variable(gap, comfort);
  }

  &--horizontal {
    gap: spacing.semantic-variable(gap, none) spacing.semantic-variable(gap, comfort);
    align-items: center;
    flex-wrap: wrap;
    transition:
      transition.entrance(height, fast),
      transition.entrance(min-height, fast);
    will-change: height, min-height;
  }

  &--vertical {
    flex-direction: column;
    gap: spacing.semantic-variable(gap, none);
  }

  &--chip {
    gap: spacing.semantic-variable(gap, slim);
    transition:
      transition.entrance(height, fast),
      transition.entrance(min-height, fast);
    will-change: height, min-height;
  }

  &--level-control-separator {
    width: 1px;
    height: spacing.semantic-variable(size, element, gentle);
    margin-inline: 1px;
    background-color: palette.semantic-variable(separator, neutral-faint);
  }

  &--nested {
    .#{$group-prefix}--content-wrapper.#{$group-prefix}--vertical.#{$group-prefix}--chip {
      .#{$prefix}.#{$prefix}--chip:first-child {
        margin-bottom: spacing.semantic-variable(padding, vertical, tiny);
      }
    }
  }
}