<template>
  <div
    class="input-checkbox-caption"
    :class="{ disabled, error: errors.length > 0 }"
    @click.self="onClick"
  >
    <UiBmsInputCheckbox
      v-model="inputValue"
      :value="value"
      :label="label"
      :name="name"
      :disabled="disabled"
      :error="errors.length > 0"
      :required="required"
    >
      <template #label>
        <slot name="label">{{ label }}</slot>
      </template>
    </UiBmsInputCheckbox>
    <span
      class="group-caption"
      v-for="message in concatErrors()"
      :key="message.label"
      @click="onClick"
    >
      <BmsCaption :caption="message" />
    </span>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue';
import { Caption } from '@/models/caption.model';
import BmsCaption from '@/components/feedback/BmsCaption.vue';
import { convertStringToCaption } from '@/helpers';
import UiBmsInputCheckbox from './UiBmsInputCheckbox.vue';

export interface Props {
  modelValue: any;
  value?: any;
  label?: string;
  name: string;
  disabled?: boolean;
  required?: boolean;
  errors?: (string | Caption)[];
  captions?: (string | Caption)[];
}

const props = withDefaults(defineProps<Props>(), {
  value: true,
  required: false,
  label: '',
  disabled: false,
  errors: () => [],
  captions: () => [],
});

const $emits = defineEmits<{
  (e: 'update:modelValue', value: any): void;
}>();

const inputValue = computed({
  get() {
    return props.modelValue;
  },
  set(val: any) {
    $emits('update:modelValue', val);
  },
});

const concatErrors = (): Caption[] => {
  return props.errors
    .map((e) => convertStringToCaption(e))
    .concat(props.captions.map((c) => convertStringToCaption(c)));
};

const onClick = () => {
  if (Array.isArray(props.modelValue)) {
    if (!inputValue.value.includes(props.value)) {
      inputValue.value = [...inputValue.value, props.value];
    } else {
      inputValue.value = (inputValue.value as any[]).filter(
        (val) => val !== props.value,
      );
    }
  } else if (typeof props.modelValue === 'boolean') {
    inputValue.value = !inputValue.value;
  }
};
</script>

<style lang="scss" scoped>
.input-checkbox-caption {
  --input-checkbox-caption-border-color: var(--bms-grey-25);
  --input-checkbox-caption-background-color: transparent;

  display: flex;
  flex-direction: column;
  width: fit-content;
  padding: 8px;
  gap: 8px;
  border: 1px solid var(--input-checkbox-caption-border-color);
  border-radius: 4px;
  background-color: var(--input-checkbox-caption-background-color);

  .group-caption {
    cursor: default;
    margin-left: 20px;
    font-size: 14px;
  }

  &:hover {
    --input-checkbox-caption-border-color: var(--bms-main-100);
  }

  &.disabled {
    --input-checkbox-caption-border-color: var(--bms-grey-50);
    --input-checkbox-caption-background-color: var(--bms-grey-25);
  }

  &.error {
    --input-checkbox-caption-border-color: var(--bms-red-100);
    --input-checkbox-caption-background-color: var(--bms-red-25);
  }
}
</style>
