<template>
  <FormWrapper
    class="single-upload"
    :class="states"
    :label="label"
    :error="error"
    :tooltip="tooltip"
  >
    <input
      :id="id"
      ref="file"
      type="file"
      :accept="acceptTypes"
      @input="handleFileChange"
    />

    <div class="wrapper">
      <label v-if="!upload" :for="id">
        <SpaceButton class="primary">
          <span class="icon">
            <SpIcon name="sp-upload" />
          </span>
          <span>{{ $t("common.choose") }}</span>
        </SpaceButton>

        <span class="instruction h600">
          {{ instruction }}
        </span>
      </label>
      <div v-else class="upload-info">
        <UploadSlot :file="upload" @remove="remove" />
        <span class="h600">{{ upload.name }}</span>
      </div>
    </div>
  </FormWrapper>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  onMounted,
  PropType,
  reactive,
  toRefs,
} from "vue";
import FormWrapper from "../FormWrapper.vue";
import FormMixin from "@/mixins/FormMixin";

export default defineComponent({
  mixins: [FormMixin],
  components: { FormWrapper },
  props: {
    id: {
      type: String,
      default: "document-upload",
    },
    instruction: {
      type: String,
      default: "Instruction",
    },
    accept: {
      type: Array as PropType<Array<string>>,
      required: true,
    },
  },
  emits: ["update:modelValue"],
  setup(props, { emit }) {
    const state: {
      upload: File;
    } = reactive({
      upload: null,
    });

    const refs = reactive({
      file: null,
    });

    const acceptTypes = computed(() => {
      return props.accept.join(", ");
    });

    const remove = (): void => {
      state.upload = null;
      refs.file.value = null;
      emit("update:modelValue", null);
    };

    const handleFileChange = (): void => {
      const file = refs.file.files[0];

      if (!props.accept.find((item) => item === file.type)) {
        return;
      }

      state.upload = file;
      refs.file.value = null;
      emit("update:modelValue", file);
    };

    return {
      ...toRefs(state),
      ...toRefs(refs),
      acceptTypes,
      remove,
      handleFileChange,
    };
  },
});
</script>

<style scoped lang="scss">
.single-upload {
  .wrapper {
    padding: 8px;
    background-color: var(--grey-6);
    border-radius: 16px;
    transition: border-color 0.3s ease;
    border: 1px solid transparent;

    label {
      display: flex;
      align-items: center;
      cursor: pointer;

      .instruction {
        flex-grow: 1;
        margin-left: 16px;
        color: var(--text-color-tertiary);
      }

      .button {
        min-width: 135px;

        @include screen-md() {
          min-width: 160px;
        }
      }
    }

    .upload-info {
      display: flex;
      align-items: center;
      color: var(--text-color-secondary);

      .upload-slot {
        --image-size: var(--form-item-height);
        margin-right: 16px;
      }

      span {
        flex-grow: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }

  &.error {
    .wrapper {
      border-color: var(--red);
    }
  }
}
</style>
