<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: {
      externalFileExist?: boolean
      fileExist?: boolean
      fileName2Long?: boolean
    }
    disableFields?: (
      | 'file'
      | 'title'
      | 'description'
      | 'keyword'
      | 'category'
      | 'author'
    )[]
    mode: 'create' | 'edit'
    fileNameLabel?: string
    title?: string
    description?: string
    keyword?: string[]
    category?: string[]
    author?: 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',
  'update:author',
  '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('update:author', '')
  emit('reset')
}

function submit() {
  if (props.mode === 'edit') {
    return emit('submit', {
      mode: props.mode,
      file: props.disableFields?.includes('file') ? undefined : file.value,
      title: props.disableFields?.includes('title') ? undefined : props.title,
      description: props.disableFields?.includes('description')
        ? undefined
        : props.description ?? '',
      keyword: props.disableFields?.includes('keyword')
        ? undefined
        : props.keyword,
      category: props.disableFields?.includes('category')
        ? undefined
        : props.category,
      author: props.disableFields?.includes('author')
        ? undefined
        : props.author,
    })
  }
  emit('submit', {
    mode: props.mode,
    file: file.value,
    title: props.title ?? '',
    description: props.description ?? '',
    keyword: props.keyword,
    category: props.category,
    author: props.author,
  })
}

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-pb-xs">
        <span class="text-weight-bold q-mb-sm block">อัปโหลดไฟล์</span>
        <q-file
          dense
          outlined
          v-model="file"
          :disable="disableFields?.includes('file')"
          @update:model-value="(v) => $emit('filechange', v.name)"
          :label="
            mode === 'edit' && fileNameLabel && !file?.name
              ? fileNameLabel
              : file?.name
                ? undefined
                : 'เลือกไฟล์'
          "
          :error="
            !!error.externalFileExist ||
            !!error.fileExist ||
            !!error.fileName2Long
          "
          :error-message="
            error.externalFileExist
              ? 'พบไฟล์ชื่อซ้ำในระบบอื่น'
              : 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-pb-xs">
        <span class="text-weight-bold">ชื่อเรื่อง</span>
        <q-input
          outlined
          dense
          class="q-mt-sm"
          placeholder="กรอกชื่อเรื่อง"
          :disable="disableFields?.includes('title')"
          :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-pb-lg">
        <span class="text-weight-bold">รายละเอียดของเอกสาร</span>
        <q-input
          outlined
          dense
          class="q-mt-sm no-resize"
          type="textarea"
          placeholder="กรอกรายละเอียด"
          :disable="disableFields?.includes('description')"
          :model-value="description"
          @update:model-value="(v) => $emit('update:description', v)"
          id="inputDescription"
        />
      </section>

      <section class="q-pb-xs">
        <span class="text-weight-bold">เจ้าของผลงาน</span>
        <q-input
          outlined
          dense
          class="q-mt-sm"
          placeholder="เจ้าของผลงาน"
          :disable="disableFields?.includes('author')"
          :model-value="author"
          :rules="[
            (v) =>
              (v != undefined && v.length > 3) || 'ชื่อต้องยาวกว่า 3 ตัวอักษร',
          ]"
          @update:model-value="(v) => $emit('update:author', v)"
          id="inputAuthor"
        />
      </section>

      <section class="q-pb-md">
        <span class="text-weight-bold">กลุ่ม/หมวดหมู่</span>
        <q-select
          outlined
          dense
          :model-value="category"
          label="กดปุ่มEnterเพื่อเพิ่ม"
          use-input
          use-chips
          hide-dropdown-icon
          multiple
          class="q-my-sm"
          input-debounce="0"
          @new-value="createCategory"
          :disable="disableFields?.includes('category')"
          :options="filterDataCategory"
          @filter="filterCategory"
          @update:model-value="(v) => $emit('update:category', v)"
          data-testid="filterDataCategory"
        >
        </q-select>
      </section>

      <section class="q-pb-lg">
        <span class="text-weight-bold">คำสำคัญ</span>
        <q-select
          outlined
          dense
          label="กดปุ่มEnterเพื่อเพิ่ม"
          use-input
          use-chips
          multiple
          hide-dropdown-icon
          class="q-my-sm"
          input-debounce="0"
          :disable="disableFields?.includes('keyword')"
          :model-value="props.keyword"
          @update:model-value="(v) => $emit('update:keyword', v)"
          @new-value="createKeyword"
          data-testid="filterDataKeyWord"
        >
        </q-select>
      </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>
