<template>
  <v-input
    :label="label"
    :error="!!errorMessage"
    :error-messages="errorMessage"
    :hide-details="readOnly ?? !!value"
    class="btn-input-file"
  >
    <template #default>
      <v-row no-gutters>
        <v-col v-if="value || readOnly" cols="12">
          <v-row no-gutters>
            <v-card
              variant="outlined"
              border="thin"
              class="px-4 text-caption font-weight-medium"
              :rounded="readOnly ? '' : '0 s'"
              height="36"
              @click="emit('click:view')"
            >
              <v-row no-gutters class="fill-height" align="center">
                {{ value ? "View attachment" : "No file attached" }}
              </v-row>
            </v-card>
            <v-card
              v-if="!readOnly"
              variant="outlined"
              border="s-0 thin"
              rounded="0 e"
              class="px-4 d-inline"
              height="36"
              @click="emit('click:close')"
            >
              <v-row no-gutters class="fill-height" align="center">
                <v-icon size="small"> mdi-close </v-icon>
              </v-row>
            </v-card>
          </v-row>
        </v-col>

        <v-col v-else cols="12">
          <v-btn
            variant="outlined"
            border="thin"
            class="text-none"
            :prepend-icon="value ? '' : 'mdi-tray-arrow-up'"
            :disabled="loading"
            :loading="loading"
            @click="selectAttachment"
          >
            Add file
          </v-btn>
        </v-col>
      </v-row>

      <v-file-input
        v-show="false"
        v-model="attachment"
        multiple
        accept="image/*"
        :class="`attachment-input-${inputClass}`"
        :name="name + 'custom-input-file'"
        @change="uploadAttachment"
      />
    </template>
  </v-input>
</template>

<script setup lang="ts">
const value = defineModel<string>({ required: true, default: "" });
const attachment = ref<File | null>(null);
const loading = ref(false);

const emit = defineEmits(["click:view", "click:close", "upload"]);

const { addFile } = useFile();
const inputClass = Date.now().toString();

function selectAttachment() {
  const input = document.querySelector(
    `.attachment-input-${inputClass} input`
  ) as HTMLInputElement;
  input.click();
}

async function uploadAttachment(e: Event) {
  loading.value = true;
  const files = (e.target as HTMLInputElement).files;

  if (files && files.length > 0) {
    const file = files[0];

    try {
      const res = await addFile(file);
      value.value = res.id as string;
      await emit("upload", res);
    } catch (error) {
      console.log(error);
    }
  } else {
    console.log("No file selected");
  }
  loading.value = false;
}

// Other props (optional)
const { label, rules, name, readOnly } = defineProps({
  label: {
    type: String,
    default: "Rating",
  },
  // Array of validation functions: (number) => true | string
  rules: {
    type: Array<Function>,
    default: () => [],
  },
  name: {
    type: String,
    required: true,
    default: "button-upload-file",
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
});

/**
 * Compute the first failed validation rule, if any.
 * Each rule returns true (if valid) or a string (if invalid).
 */
const errorMessage = computed(() => {
  for (const rule of rules) {
    const result = rule(attachment.value || value.value);
    return typeof result === "string" ? result : null;
  }
  return null;
});
</script>
