<template>
  <div class="f-input" :class="classObject" v-bind="rootAttrs">
    <div class="f-input-label subheader2">
      <label v-if="props.label" :for="inputId">{{ props.label }}</label>
      <Icon>
        <template v-slot:text v-if="slots.info">
          <slot name="info"></slot>
        </template>
      </Icon>
    </div>
    <div class="f-input__wrapper" ref="inputWrapper" @click="setFocus">
      <input
        :disabled="props.disabled"
        :readonly="props.readonly"
        :type="props.type"
        :name="inputName"
        :id="inputId"
        @input="updateModelValue"
        :value="props.modelValue"
        v-bind="inputAttrs"
      />
      <div class="f-input--suffix" v-if="slots.suffix">
        <slot name="suffix">test </slot>
      </div>
    </div>

    <div class="f-input--details" v-if="slots.details">
      <slot name="details"> </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, useSlots, ref, useAttrs } from 'vue';
import useClickOutside from '@/composables/useClickOutside';

import Icon from '@/components/icons/IconInfo.vue';
interface Props {
  size?: string;
  info?: string;
  label?: string;
  disabled?: boolean;
  modelValue?: string | number;
  type?: string;
  readonly?: boolean;
}

const slots = useSlots();

const inputWrapper = ref();

const instance = getCurrentInstance();
defineOptions({ inheritAttrs: false });
const attrs = useAttrs();

const generatedId = `f-input-${instance!.uid}`;

const inputId = computed(() => {
  const attrId = (attrs as Record<string, unknown>).id;
  return typeof attrId === 'string' && attrId.length > 0 ? attrId : generatedId;
});

const inputName = computed(() => {
  const attrName = (attrs as Record<string, unknown>).name;
  if (typeof attrName === 'string' && attrName.length > 0) {
    return attrName;
  }
  return inputId.value;
});

const rootAttrs = computed(() => {
  const attrRecord = attrs as Record<string, unknown>;
  const root: Record<string, unknown> = {};
  if (typeof attrRecord.class === 'string') {
    root.class = attrRecord.class;
  }
  if (attrRecord.style) {
    root.style = attrRecord.style;
  }
  for (const [key, value] of Object.entries(attrRecord)) {
    if (key.startsWith('data-')) {
      root[key] = value;
    }
  }
  return root;
});

const inputAttrs = computed(() => {
  const attrRecord = attrs as Record<string, unknown>;
  const input: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(attrRecord)) {
    if (key === 'class' || key === 'style' || key.startsWith('data-') || key === 'id' || key === 'name') {
      continue;
    }
    input[key] = value;
  }
  return input;
});

const props = withDefaults(defineProps<Props>(), {
  size: 'normal',
  disabled: false,
  readonly: false,
  type: 'string',
  info: '',
  label: '',
  modelValue: '',
});

useClickOutside(inputWrapper, () => {
  removeFocus();
});

interface Emits {
  (e: 'update:modelValue', value: string): void;
}
const emit = defineEmits<Emits>();

function updateModelValue($event: Event) {
  const target = $event.target as HTMLInputElement;
  emit('update:modelValue', target.value);
}

const classObject = computed(() => ({
  'f-input--normal': props.size === 'normal',
  'f-input--big': props.size === 'big',
  'f-input--disabled': props.disabled,
}));

function removeFocus() {
  const target = inputWrapper.value as HTMLElement;
  target.classList.remove('f-input__wrapper--focused');
}

function setFocus(_event: MouseEvent) {
  if (props.disabled) {
    return;
  }
  const target = inputWrapper.value as HTMLElement;
  target.classList.add('f-input__wrapper--focused');
}
</script>
<style lang="sass">
.f-input
    display: flex
    flex-direction: column
    .info-icon
        position: static
        @media (min-width: 768px)
            position: relative
    .f-input-label
        display: flex
        align-items: center
        gap: 8px
    .f-input__wrapper
        display: flex
        border: 1px solid black
        border-radius: 12px
        width: 100%
        background-color: #2D2D2D
        &.f-input__wrapper--focused
            outline: none
            border: 1px solid #7550AE
            box-shadow: 0 0 5px #7550AE
        input
            border: 0
            border-radius: 12px
            padding: 8px 12px
            width: 100%
            background-color: #2D2D2D
            color: #FFFFFF
            outline: none
            &.f-input--big
                font-size: 18px
            &.f-input--normal
                font-size: 16px
    &.f-input--disabled
        input
            background-color: #202020
            color: #F0F0F0
    .f-input--suffix
        display: flex
        align-items: center
        margin-right: 10px
</style>
