<script setup lang="ts">
import { computed, PropType } from 'vue'
import { SizeTypes } from '../../types'
import { LabelColorTypes } from '../../types/Color/Color.types'

const props = defineProps({
  /**
   * 値
   * @example true | false
   */
  modelValue: { type: Boolean, default: false },
  /**
   * 制御
   * @example true | false
   */
  disabled: { type: Boolean, default: false },
  /**
   * ラベル
   * @example '利用規約'
   */
  label: { type: String, default: '' },
  /**
   * ラベルカラー
   * @example 'black' | 'gray'
   */
  labelColor: { type: String as PropType<LabelColorTypes>, default: '' },
  /**
   * サイズ
   * @example 's' | 'S' | 'l' | 'L'
   */
  size: { type: String as PropType<SizeTypes>, default: 'L' },
  /**
   * エラーパターン1
   * @example true | false
   */
  error1: { type: Boolean, default: false },
  /**
   * エラーパターン2
   * @example true | false
   */
  error2: { type: Boolean, default: false },
  /**
   * エラーパターン3
   * 表示はエラーパターン2と同じだが、チェックボックスがついていなくてもエラー表示にできるもの
   * 無効化したければerror3に明示的にfalseを渡すか、そもそもpropsでerror3を設定しなければよい
   * @example true | false
   */
  error3: { type: Boolean, default: false },
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
}>()

const model = computed({
  get: () => props.modelValue,
  set: value => {
    emit('update:modelValue', value)
  },
})

// チェックボックスをクリックした場合、以下の処理を実行する
const clickCheckBox = () => {
  if (props.disabled) return

  model.value = !model.value
}
</script>

<template>
  <div
    class="_cc_checkbox"
    :class="{
      _active: !props.disabled,
      _passive: props.disabled,
      _cc_checkbox_size_l: props.size === 'L' || props.size === 'l',
    }"
    @click="clickCheckBox"
  >
    <div v-if="props.size === 'L' || props.size === 'l'" class="_hover_circle_container">
      <div v-show="!props.disabled" class="_hover_circle" />
    </div>

    <div
      class="_checkbox"
      :class="{
        _size_s: props.size === 'S' || props.size === 's',
        _size_l: props.size === 'L' || props.size === 'l',
        _checkbox_active: model,
        _checkbox_passive: !model,
        _checkbox_disabled: props.disabled,
        _checkbox_error1: props.error1 && !model,
        _checkbox_error2: (props.error2 && !model) || props.error3,
      }"
    >
      <div
        class="_check_container_position"
        :class="{
          _check_container_position_size_s_label:
            props.label && (props.size === 'S' || props.size === 's'),
        }"
      >
        <div class="_check_container">
          <div
            :class="{
              _long_border_active: model,
              _long_border_passive: !model,
            }"
            class="_long_border"
          />
          <div
            :class="{
              _short_border_active: model,
              _short_border_passive: !model,
            }"
            class="_short_border"
          />
        </div>
      </div>
    </div>

    <div
      v-show="label"
      class="_label"
      :class="{
        _label_size_l: props.size === 'L' || props.size === 'l',
        _label_size_s: props.size === 'S' || props.size === 's',
        _label_color_main: !labelColor,
        _label_color_black: labelColor === 'black',
        _label_color_gray: labelColor === 'gray',
      }"
    >
      {{ label }}
    </div>
  </div>
</template>

<style lang="sass" scoped>
._cc_checkbox
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
  position: relative
  width: fit-content
  display: flex
  font-family: 'Roboto', sans-serif

._cc_checkbox_size_l
  min-height: 48px

._cc_checkbox:hover ._hover_circle
  height: 48px
  width: 48px
._active
  cursor: pointer
._passive
  cursor: not-allowed

._hover_circle_container
  position: absolute
  height: 48px
  width: 48px
  display: flex
  justify-content: center
  align-items: center

._hover_circle
  background: var(--c-primary)
  height: 0px
  width: 0px
  opacity: 0.1
  border-radius: 50%
  transition: 0.3s

._checkbox
  border-radius: 5px

._size_s
  height: 15px
  width: 15px

._size_l
  flex-shrink: 0
  position: relative
  top: 11px
  left: 11px
  height: 20px
  width: 20px

._checkbox_active
  background: var(--c-primary)
  border: solid 3px var(--c-primary)

._checkbox_passive
  background: #fff
  border: solid 3px #9E9E9E
  transition-property: background, border
  transition-delay: 0.3s

._checkbox_disabled
  opacity: 0.7

._checkbox_error1
  border: solid 3px #D20000

._checkbox_error2
  border: solid 3px #D20000
  background: rgb(210, 0 , 0, 0.2)

._check_container_position
  position: absolute
  top: 40%
  left: 50%
  transform: translate(-50%, -50%)
  -webkit-transform: translate(-50%, -50%)
  -ms-transform: translate(-50%, -50%)

._check_container_position_size_s_label
  left: 17%

._check_container
  position: relative
  width: 9px
  height: 14px
  transform: rotate( 45deg )

._short_border
  position: absolute
  bottom: 0
  border-bottom: solid 3px #fff
  transition: 0.1s
._short_border_active
  width: 100%
._short_border_passive
  width: 0%
  transition-property: width
  transition-delay: 0.1s

._long_border
  position: absolute
  bottom: 0
  right: 0
  border-right: solid 3px #fff
  width: 0%
  transition: 0.1s
._long_border_active
  height: 100%
  transition-property: height
  transition-delay: 0.1s
._long_border_passive
  height: 0%

._label
  text-align: justify
  text-justify: inter-ideograph

._label_size_l
  padding: 11px 0 0 24px

._label_size_s
  padding-left: 12px
  font-size: 14px

._label_color_main
  color: var(--c-primary)
._label_color_black
  color: #333
._label_color_gray
  color: #707070
</style>
