<template>
  <BasicModal
    title="ارسال تیکت جدید"
    title-en="New ticket"
    width="95%"
    max-width="58rem"
    min-width="auto"
    :show-close-button="true"
  >
    <template #default="{ close }">
      <form class="ctm" @submit.prevent="onSubmit(close)">
        <div class="ctm__row ctm__row--two">
          <TextField
            v-model="form.subject"
            name="subject"
            label="موضوع را وارد کنید"
            placeholder="موضوع تیکت"
            :error="errors.subject"
            @blur="validateAt('subject', form.subject)"
          />
          <SelectField
            v-model="form.priority"
            name="priority"
            label="اولویت تیکت"
            placeholder="انتخاب کنید"
            :options="priorityOptions"
            option-label="label"
            option-value="value"
            :error="errors.priority"
          />
        </div>

        <div class="ctm__row">
          <TextareaField
            v-model="form.message"
            name="message"
            label="توضیحات خودتان را وارد کنید"
            :row="4"
            :error="errors.message"
          />
        </div>

        <div class="ctm__upload">
          <FileUploader
            v-model="files"
            accept="image/*,application/pdf"
            :max-files="5"
            @select="onFilesSelect"
            @error="onFileError"
          />
        </div>

        <div class="ctm__divider" />

        <footer class="ctm__footer">
          <button type="button" class="ctm__cancel" @click="close">
            <SvgIcon name="caret-right" :size="16" color="currentColor" />
            <span>منصرف شدم</span>
          </button>
          <BaseButton
            type="submit"
            text="ارسال تیکت"
            custom-class="ctm__submit"
            :loading="createMutation.isPending.value"
            :disabled="uploadMutation.isPending.value"
          >
            <template #appendIcon>
              <SvgIcon name="arrow-left" :size="18" color="#fff" />
            </template>
          </BaseButton>
        </footer>
      </form>
    </template>
  </BasicModal>
</template>

<script setup>
import { ref } from 'vue'
import * as yup from 'yup'
import { toast } from 'vue3-toastify'
import { TICKET_PRIORITY } from '@/enums'
import useYup from '@/composables/useYup'
import BasicModal from '@/components/BasicModal.vue'
import BaseButton from '@/components/BaseButton.vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import { useQueryClient } from '@tanstack/vue-query'
import TextField from '@/components/form/TextField.vue'
import SelectField from '@/components/form/SelectField.vue'
import FileUploader from '@/components/form/FileUploader.vue'
import { objectToFormData } from '@/utils/object-to-formdata'
import { useUploadMediaMutation } from '@/services/query/auth'
import TextareaField from '@/components/form/TextareaField.vue'
import {
  studentTicketsKeys,
  useCreateStudentTicketMutation,
} from '@/services/query/student-tickets'

defineOptions({ name: 'CreateTicketModal' })

const queryClient = useQueryClient()

const priorityOptions = Object.entries(TICKET_PRIORITY).map(([value, label]) => ({
  value,
  label,
}))

const form = ref({
  subject: '',
  priority: 'normal',
  message: '',
})

// Uploaded-media descriptors { id, name, size, url }, populated as files are
// picked. Submit just collects the IDs (same pattern as CreateServiceForm /
// AddAssignmentModal).
const files = ref([])

const schema = yup.object({
  subject: yup.string().trim().required('موضوع تیکت را وارد کنید'),
  priority: yup.string().required('اولویت را انتخاب کنید'),
  message: yup
    .string()
    .trim()
    .min(5, 'توضیحات حداقل ۵ کاراکتر باشد')
    .required('توضیحات را وارد کنید'),
})

const { validate, validateAt, errors, resetErrors } = useYup(schema)

const uploadMutation = useUploadMediaMutation()
const createMutation = useCreateStudentTicketMutation()

// FileUploader emits `select` on add (we upload + push the result) and
// `update:modelValue` on remove (handled by v-model directly).
const onFilesSelect = async (picked) => {
  for (const file of picked) {
    try {
      const fd = objectToFormData({ file, purpose: 'attachment', context: 'ticket' })
      const response = await uploadMutation.mutateAsync(fd)
      const payload = response?.data ?? response
      const id = payload?.id ?? payload?.uploadId
      if (id == null) continue
      files.value = [
        ...files.value,
        { id, name: file.name, size: file.size, url: payload?.url ?? '' },
      ]
    } catch {
      toast.error(`بارگذاری فایل "${file.name}" با خطا مواجه شد.`)
    }
  }
}

const onFileError = (msg) => toast.warning(msg)

const onSubmit = async (close) => {
  const { isValid, payload } = await validate(form.value)
  if (!isValid) return

  try {
    await createMutation.mutateAsync({
      type: 'ticket',
      priority: payload.priority,
      subject: payload.subject,
      message: payload.message,
      mediaIds: files.value.map((f) => f.id).filter((id) => id != null),
    })
    await queryClient.invalidateQueries({ queryKey: studentTicketsKeys.all })
    toast.success('تیکت با موفقیت ثبت شد.')
    resetErrors()
    form.value = { subject: '', priority: 'normal', message: '' }
    files.value = []
    close?.()
  } catch {
    toast.error('ارسال تیکت با خطا مواجه شد.')
  }
}
</script>

<style lang="scss" scoped>
.ctm {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  text-align: start;
  padding-block: 0.25rem 0.5rem;

  &__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.875rem;

    &--two {
      @media (min-width: 640px) {
        grid-template-columns: 1fr 1fr;
      }
    }
  }

  &__upload {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  &__divider {
    border-block-end: 1px solid #ddd;
    margin-block: 0.25rem;
  }

  &__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    flex-wrap: wrap;

    @media (min-width: 640px) {
      justify-content: space-between;
    }
  }

  &__cancel {
    display: none;
    align-items: center;
    gap: 0.375rem;
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    font-family: var(--font-family-fa);
    font-size: 0.875rem;
    font-weight: 500;
    color: #969696;

    @media (min-width: 640px) {
      display: inline-flex;
    }

    &:hover {
      color: #6b6b6b;
    }
  }

  &__submit {
    min-width: 16rem;
    padding: 0 1.5rem;
  }
}
</style>
