<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'

import { QSelect } from 'quasar'

const storesCategory: string[] = []
const filterDataCategory = ref<string[]>(storesCategory)

const props = withDefaults(
  defineProps<{
    open: boolean
    error: {
      fileExist?: boolean
      fileName2Long?: boolean
    }
    mode: 'create' | 'edit'
    fileNameLabel?: string
    title?: string
    description?: string
    keyword?: string[]
    category?: string[]
  }>(),
  {
    open: false,
  },
)

const inputKeyword = ref<string[]>(props.keyword || [])
const inputCategory = ref<string[]>(props.category || [])

const emit = defineEmits([
  'update:open',
  'update:title',
  'update:description',
  'update:keyword',
  'update:category',
  'filechange',
  'reset',
  'submit',
])

defineExpose({
  reset,
})

function keydown(e: KeyboardEvent) {
  if (e.key === 'Escape' && props.open === true) {
    emit('update:open', false)
    reset()
  }
}

function reset() {
  file.value = undefined
  emit('update:title', '')
  emit('update:description', '')
  emit('update:keyword', '')
  emit('update:category', '')
  emit('reset')
}

function submit() {
  emit('submit', {
    mode: props.mode,
    file: file.value,
    title: props.title ?? '',
    description: props.description ?? '',
    keyword: props.keyword,
    category: props.category,
  })
}

const createKeyword = ((val, done) => {
  if (val.length > 2) {
    if (!inputKeyword.value.includes(val)) {
      done(val, 'add-unique')
    }
  }
}) satisfies QSelect['onNewValue']

const createCategory = ((val, done) => {
  if (val.length > 2) {
    if (!inputCategory.value.includes(val)) {
      done(val, 'add-unique')
    }
  }
}) satisfies QSelect['onNewValue']

const filterCategory = ((val, update) => {
  update(() => {
    if (val === '') {
      filterDataCategory.value = storesCategory
    } else {
      const needle = val.toLowerCase()
      filterDataCategory.value = storesCategory.filter(
        (v) => v.toLowerCase().indexOf(needle) > -1,
      )
    }
  })
}) satisfies QSelect['onFilter']

onMounted(() => window.addEventListener('keydown', keydown))
onUnmounted(() => window.addEventListener('keydown', keydown))

const file = ref<File | undefined>()
</script>

<template>
  <q-drawer
    overlay
    bordered
    class="q-pa-md"
    side="right"
    tabindex="0"
    v-click-outside="
      () => ($emit('update:open', false), reset(), (file = undefined))
    "
    :width="300"
    :breakpoint="500"
    :model-value="open"
    @update:model-value="(v) => $emit('update:open', v)"
  >
    <q-form @submit.prevent="submit" v-if="open">
      <q-toolbar class="q-mb-md q-pa-none">
        <q-toolbar-title>
          <span class="text-weight-bold" v-if="mode === 'create'">
            สร้างเอกสาร
          </span>
          <span class="text-weight-bold" v-if="mode === 'edit'">
            แก้ไขเอกสาร
          </span>
        </q-toolbar-title>
        <q-btn
          v-close-popup
          flat
          round
          dense
          icon="close"
          color="red"
          @click="() => ($emit('update:open', !open), reset())"
          id="fileFormIconClose"
        />
      </q-toolbar>

      <section class="q-mb-md">
        <span class="text-weight-bold q-mb-sm block">อัปโหลดไฟล์</span>
        <q-file
          dense
          outlined
          v-model="file"
          @update:model-value="(v) => $emit('filechange', v.name)"
          :label="
            mode === 'edit' && fileNameLabel && !file?.name
              ? fileNameLabel
              : file?.name
                ? undefined
                : 'เลือกไฟล์'
          "
          :error="!!error.fileExist || !!error.fileName2Long"
          :error-message="
            error.fileExist
              ? 'พบไฟล์ชื่อซ้ำในระบบ ไฟล์ชื่อนี้ภายในระบบจะถูกเขียนทับ'
              : error.fileName2Long
                ? 'ไม่สามารถเพิ่มไฟล์ที่ชื่อยาวเกิน 85 ตัวอักษรได้'
                : ''
          "
          id="inputFile"
          :rules="[(v) => (v !== undefined || mode === 'edit' ) || ('โปรดอัปโหลดไฟล์')]"
        >
          <template v-slot:prepend>
            <q-icon name="attach_file" />
          </template>
        </q-file>
      </section>

      <section class="q-mb-md">
        <span class="text-weight-bold">ชื่อเรื่อง</span>
        <q-input
          outlined
          dense
          class="q-my-sm"
          placeholder="กรอกชื่อเรื่อง"
          :model-value="title"
          :rules="[(v) => (v != undefined && v.length > 3) || 'ชื่อต้องยาวกว่า 3 ตัวอักษร']"
          @update:model-value="(v) => $emit('update:title', v)"
          id="inputTitle"
        />
      </section>

      <section class="q-mb-md">
        <span class="text-weight-bold">รายละเอียดของเอกสาร</span>
        <q-input
          outlined
          dense
          class="q-mt-sm no-resize"
          type="textarea"
          placeholder="กรอกรายละเอียด"
          :model-value="description"
          @update:model-value="(v) => $emit('update:description', v)"
          id="inputDescription"
        />
      </section>

      <section class="q-mb-md">
        <span class="text-weight-bold">กลุ่ม/หมวดหมู่</span>
        <div class="q-mt-md">
          <q-select
            outlined
            dense
            :model-value="category"
            label="กดปุ่มEnterเพื่อเพิ่ม"
            use-input
            use-chips
            multiple
            input-debounce="0"
            @new-value="createCategory"
            :options="filterDataCategory"
            @filter="filterCategory"
            style="width: 250px"
            @update:model-value="(v) => $emit('update:category', v)"
            data-testid="filterDataCategory"
          >
            <template v-slot:no-option>
              <q-item>
                <q-item-section class="text-grey"> No results </q-item-section>
              </q-item>
            </template>
          </q-select>
        </div>
      </section>

      <section class="q-mb-md">
        <span class="text-weight-bold">คำสำคัญ</span>
        <div class="q-mt-md">
          <q-select
            outlined
            dense
            label="กดปุ่มEnterเพื่อเพิ่ม"
            use-input
            use-chips
            multiple
            hide-dropdown-icon
            input-debounce="0"
            style="width: 250px"
            :model-value="props.keyword"
            @update:model-value="(v) => $emit('update:keyword', v)"
            @new-value="createKeyword"
            data-testid="filterDataKeyWord"
          >
          </q-select>
        </div>
      </section>

      <section :style="{ display: 'flex', gap: '.5rem' }">
        <q-btn
          label="บันทึก"
          type="submit"
          color="primary"
          :disable="error.fileName2Long"
          id="submitFile"
        />
        <q-btn
          label="ยกเลิก"
          type="reset"
          color="primary"
          flat
          @click="() => ($emit('update:open', false), reset())"
          id="fileFormBtnClose"
        />
      </section>
    </q-form>
  </q-drawer>
</template>

<style scoped>
.no-resize :deep(textarea) {
  resize: none;
}
</style>
