<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <q-card class="q-dialog-plugin" style="width: 800px; max-width: 90vw">
      <DefaultDialogHeader :title="title" @close="onDialogCancel" />
      <q-form ref="formRef" @submit="onOKClick">
        <q-card-section class="row q-col-gutter-sm">

          <q-select
            v-if="!review"
            v-model="selectedSchedule"
            :label="$t('reviews.schedule')"
            :options="scheduleOptions"
            :rules="[inputRules.required]"
            :error="!!serverErrors?.schedule_id"
            :error-message="serverErrors?.schedule_id"
            :loading="loadingSchedules"
            option-value="value"
            option-label="label"
            emit-value
            map-options
            class="col-12"
            @update:model-value="onScheduleChange"
          />

          <q-input
            v-else
            :model-value="review.schedule_label"
            :label="$t('reviews.schedule')"
            readonly
            class="col-12"
          />

          <q-select
            v-if="!review"
            v-model="form.origin"
            :label="$t('reviews.origin')"
            :options="originOptions"
            :rules="[inputRules.required]"
            :error="!!serverErrors?.origin"
            :error-message="serverErrors?.origin"
            emit-value
            map-options
            class="col-12 col-md-6"
            @update:model-value="onOriginChange"
          />

          <q-input
            v-else
            :model-value="$t(`reviews.origins.${review.origin}`)"
            :label="$t('reviews.origin')"
            readonly
            class="col-12 col-md-6"
          />

          <template v-if="!review">
            <ProviderSelect
              v-if="form.origin === 'providers'"
              :key="'provider-select'"
              v-model="selectedOriginModel"
              :label="$t('reviews.origin_id')"
              :rules="[inputRules.required]"
              :error="!!serverErrors?.origin_id"
              :error-message="serverErrors?.origin_id"
              class="col-12 col-md-6"
              @update:model-value="onOriginIdChange"
            />
            <ClientSelect
              v-else-if="form.origin === 'clients'"
              :key="'client-select'"
              v-model="selectedOriginModel"
              :label="$t('reviews.origin_id')"
              :rules="[inputRules.required]"
              :error="!!serverErrors?.origin_id"
              :error-message="serverErrors?.origin_id"
              class="col-12 col-md-6"
              @update:model-value="onOriginIdChange"
            />
            <q-input
              v-else
              :label="$t('reviews.origin_id')"
              readonly
              :placeholder="$t('reviews.origin')"
              class="col-12 col-md-6"
              disable
            />
          </template>

          <div class="col-12">
            <div class="text-caption q-mb-xs">{{ $t('reviews.stars') }}</div>
            <q-rating
              v-model="form.stars"
              :max="5"
              size="md"
              color="amber"
              icon="star_border"
              icon-selected="star"
              class="q-mb-xs"
            />
            <div
              v-if="serverErrors?.stars"
              class="text-negative text-caption"
            >
              {{ serverErrors.stars }}
            </div>
          </div>

          <q-input
            v-model="form.comment"
            :label="$t('reviews.comment')"
            :error="!!serverErrors?.comment"
            :error-message="serverErrors?.comment"
            type="textarea"
            autogrow
            class="col-12"
            @update:model-value="serverErrors.comment = null"
          />

          <q-select
            v-if="!review"
            v-model="selectedImprovements"
            :label="$t('reviews.improvements')"
            :options="improvementOptions"
            :loading="loadingImprovements"
            option-value="value"
            option-label="label"
            emit-value
            map-options
            multiple
            use-chips
            class="col-12"
            @update:model-value="($event) => attImprovementsOnForm($event)"
          />
          <div v-else>
            <div>{{reviewsImprovements?.length > 0 ?  t('reviews.improvements_suggested') : t('reviews.no_improvements_suggested')}}</div>
            <q-chip
              v-for="improvement in reviewsImprovements"
              :key="improvement.id"
              class="q-mb-xs"
            >
              {{ improvement.description }}
            </q-chip>
          </div>

        </q-card-section>

        <q-card-actions align="right" class="q-px-md q-pb-md">
          <q-btn
            flat
            :label="$t('common.actions.cancel')"
            color="negative"
            @click="onDialogCancel"
          />
          <q-btn
            type="submit"
            :label="$t('common.actions.save')"
            :loading="loading"
            :disable="!hasUpdatedFields"
            color="primary"
            unelevated
          />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useDialogPluginComponent } from 'quasar'
import { useFormUpdateTracker } from 'src/composables/useFormUpdateTracker'
import { useSubmitHandler } from 'src/composables/useSubmitHandler'
import { createReview, updateReview, getFinishedSchedules } from 'src/api/review'
import { createReviewImprovement } from 'src/api/reviewImprovement'
import { getImprovementTypes } from 'src/api/improvementType'
import DefaultDialogHeader from 'src/components/defaults/DefaultDialogHeader.vue'
import ProviderSelect from 'src/components/provider/ProviderSelect.vue'
import ClientSelect from 'src/components/client/ClientSelect.vue'
import { useInputRules } from 'src/composables/useInputRules'
import { useI18n } from 'vue-i18n'
import { format, parseISO } from 'date-fns'

const props = defineProps({
  review: {
    type: Object,
    default: null
  },
  title: {
    type: Function,
    default: () => ''
  }
})

defineEmits([...useDialogPluginComponent.emits])
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const { inputRules } = useInputRules()
const { t } = useI18n()
const formRef = ref(null)

const selectedSchedule = ref(props.review ? props.review.schedule_id : null)
const selectedOriginModel = ref(null)
const selectedImprovements = ref([])

const scheduleOptions = ref([])
const improvementOptions = ref([])
const loadingSchedules = ref(false)
const loadingImprovements = ref(false)
const reviewsImprovements = ref([])

const originOptions = computed(() => [
  { label: t('reviews.origins.providers'), value: 'providers' },
  { label: t('reviews.origins.clients'), value: 'clients' }
])

const { form, hasUpdatedFields } = useFormUpdateTracker({
  schedule_id: props.review ? props.review.schedule_id : null,
  origin:      props.review ? props.review.origin : null,
  origin_id:   props.review ? props.review.origin_id : null,
  stars:       props.review ? Number(props.review.stars) : 0,
  comment:     props.review ? props.review.comment : null,
  improvements_ids: props.review ? props.review.improvements?.map(i => i.id) : [],
})

const {
  loading,
  serverErrors,
  execute: submitForm,
} = useSubmitHandler({
  onSuccess: () => onDialogOK(true),
  formRef: formRef,
})

const onScheduleChange = (val) => {
  form.schedule_id = val
  serverErrors.schedule_id = null
}

const onOriginChange = () => {
  selectedOriginModel.value = null
  form.origin_id = null
  serverErrors.origin = null
  serverErrors.origin_id = null
}

const onOriginIdChange = (selected) => {
  form.origin_id = selected?.value ?? null
  serverErrors.origin_id = null
}

const onOKClick = async () => {
  await submitForm(async () => {
    if (props.review) {
      return updateReview(props.review.id, {
        stars:   form.stars,
        comment: form.comment,
      })
    } else {
      const created = await createReview({ ...form })
      for (const improvementTypeId of selectedImprovements.value) {
        await createReviewImprovement({
          review_id: created.id,
          improvement_type_id: improvementTypeId,
        })
      }
      return created
    }
  })
}

const attImprovementsOnForm = (event) => {
  form.improvements_ids = event;
  serverErrors.improvements_ids = null;
}

onMounted(async () => {
  loadingSchedules.value = true
  loadingImprovements.value = true
  try {
    const [schedules, improvements] = await Promise.all([
      getFinishedSchedules(),
      getImprovementTypes(),
    ])
    scheduleOptions.value = schedules.map((s) => ({
      value: s.id,
      label: `${s.id} - ${s.client_name ?? '?'} - ${s.provider_name ?? '?'} - ${s.date ? format(parseISO(s.date), 'dd/MM/yyyy') : '?'}`,
    }))
    improvementOptions.value = improvements.map((i) => ({
      value: i.id,
      label: i.description,
    }))
    reviewsImprovements.value = props.review?.reviews_improvements;
  } catch (error) {
    console.error('Error loading data:', error)
  } finally {
    loadingSchedules.value = false
    loadingImprovements.value = false
  }
})
</script>
