<template>
  <q-dialog
    ref="dialogRef"
    @hide="onDialogHide"
  >
    <q-card
      class="rating-dialog-card bg-surface shadow-card"
      :flat="false"
    >
      <div class="row justify-end q-pt-sm q-pr-sm">
        <q-btn
          color="grey-6"
          dense
          flat
          icon="close"
          round
          size="sm"
          @click="onDialogCancel"
        />
      </div>

      <div class="column items-center q-pb-sm">
        <q-avatar
          class="q-mb-sm"
          size="64px"
        >
          <span
            class="full-width full-height flex flex-center"
            style="font-size: 20px; border-radius: 50%;"
            :style="avatarStyle"
          >
            {{ initials }}
          </span>
        </q-avatar>
  
        <div
          class="text-text text-center font16 fontbold q-px-lg"
          style="line-height:1.3"
        >
          {{ $t('provider.dashboard.schedule_rating.title') }}

          <span class="text-primary">
            {{ (getFirstName(schedule.client_name) || '—') + '?' }}
          </span>
        </div>
      </div>

      <div class="column items-center q-pb-xs">
        <q-rating
          v-model="stars"
          color="amber"
          icon="mdi-star-outline"
          icon-selected="mdi-star"
          size="lg"
          :max="5"
          @update:model-value="onStarsChange"
        />
      </div>

      <q-card-section
        v-if="stars > 0"
        class="q-pt-xs q-pb-xs"
      >
        <div class="text-grey-7 text-center font12 q-mb-sm">
          {{ isNegative ? $t('provider.dashboard.schedule_rating.negative_label') : $t('provider.dashboard.schedule_rating.positive_label') }}
        </div>

        <div v-if="loadingTags" class="row justify-center q-py-sm">
          <q-spinner-dots
            color="primary"
            size="24px"
          />
        </div>

        <div v-else class="row justify-center q-gutter-xs">
          <div
            v-for="tag in tags"
            :key="tag.id"
            :class="{ 'tag-pill--selected': selectedTagIds.includes(tag.id), 'fontsemibold': selectedTagIds.includes(tag.id) }"
            class="tag-pill font12"
            @click="toggleTag(tag.id)"
          >
            {{ tag.description }}
          </div>
        </div>
      </q-card-section>

      <q-card-section class="q-pt-xs q-pb-xs q-px-lg">
        <div class="text-grey-7 font12 q-mb-xs">
          {{ $t('provider.dashboard.schedule_rating.comment_placeholder') }}
        </div>

        <q-input
          v-model="comment"
          color="primary"
          dense
          hide-bottom-space
          input-class="text-black"
          outlined
          rows="3"
          type="textarea"
        />
      </q-card-section>

      <q-card-section class="q-pt-xs q-pb-xs q-px-lg">
        <input
          ref="photoInputRef"
          accept="image/jpeg,image/png,image/webp"
          class="hidden"
          multiple
          type="file"
          @change="onPhotosSelected"
        />

        <div class="row q-gutter-xs">
          <div
            v-for="(preview, idx)
            in photoPreviews"
            :key="idx"
            class="photo-thumb"
          >
            <img :src="preview" />

            <q-btn
              class="photo-thumb__remove"
              dense
              flat
              icon="close"
              round
              size="xs"
              @click="removePhoto(idx)"
            />
          </div>

          <div
            v-if="photos.length < 5"
            class="photo-add"
            @click="photoInputRef.click()"
          >
            <q-icon
              color="grey-5"
              name="mdi-camera-plus-outline"
              size="24px"
            />

            <div class="photo-add__label font9">
              {{ $t('provider.dashboard.schedule_rating.add_photo') }}
            </div>
          </div>
        </div>
      </q-card-section>

      <q-card-section
        v-if="isNegative"
        class="q-pt-xs q-pb-xs q-px-lg"
      >
        <q-checkbox
          v-model="blockClient"
          checked-icon="mdi-check-circle"
          class="text-text"
          color="primary"
          keep-color
          unchecked-icon="mdi-checkbox-blank-circle-outline"
          :label="$t('provider.dashboard.schedule_rating.block_label')"
        />
      </q-card-section>

      <q-card-section class="q-pt-sm q-pb-xs q-px-lg row">
        <q-btn
          class="submit-btn font16 fontbold col-12"
          color="primary"
          full-width
          no-caps
          rounded
          unelevated
          :disable="stars === 0"
          :label="$t('provider.dashboard.schedule_rating.submit_btn')"
          :loading="loading"
          @click="submit"
        />
      </q-card-section>

      <q-card-section class="q-pt-xs q-pb-lg text-center">
        <span
          class="text-grey-6 font12 cursor-pointer"
          @click="openHelp"
        >
          {{ $t('provider.dashboard.schedule_rating.help_link') }}
        </span>
      </q-card-section>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { avatarColors, getFirstName } from 'src/helpers/utils'
import { createReview, getImprovementTypes } from 'src/api/review'
import { computed, onMounted, ref } from 'vue'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { useI18n } from 'vue-i18n'
import { userStore } from 'src/stores/user'

import ProfileHelpDialog from 'src/components/profile/ProfileHelpDialog.vue'

const props = defineProps({
  schedule: {
    type: Object,
    required: true
  }
})

defineEmits([...useDialogPluginComponent.emits])

const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const { t } = useI18n()

const $q = useQuasar()
const store = userStore()

const stars = ref(0)
const selectedTagIds = ref([])
const comment = ref(null)
const blockClient = ref(false)
const tags = ref([])
const loadingTags = ref(false)
const loading = ref(false)
const photos = ref([])
const photoPreviews = ref([])
const photoInputRef = ref(null)

const avatarStyle = computed(() => {
  const c = avatarColors[props.schedule.client_id % avatarColors.length]
  return { background: c.background, color: c.color }
})

const isNegative = computed(() => stars.value > 0 && stars.value <= 2)

const initials = computed(() =>
  getFirstName(props.schedule.client_name)?.slice(0, 2).toUpperCase() ?? '??'
)

const onPhotosSelected = (event) => {
  const files = Array.from(event.target.files)

  const remaining = 5 - photos.value.length

  files.slice(0, remaining).forEach(file => {
    photos.value.push(file)
    photoPreviews.value.push(URL.createObjectURL(file))
  })

  event.target.value = ''
}

const onStarsChange = () => {
  selectedTagIds.value = []

  blockClient.value = false
}

const removePhoto = (idx) => {
  URL.revokeObjectURL(photoPreviews.value[idx])

  photos.value.splice(idx, 1)

  photoPreviews.value.splice(idx, 1)
}

const toggleTag = (id) => {
  const idx = selectedTagIds.value.indexOf(id)

  if (idx === -1) selectedTagIds.value.push(id)

  else selectedTagIds.value.splice(idx, 1)
}

//

const submit = async () => {
  if (stars.value === 0) return

  loading.value = true

  try {
    await createReview({
      schedule_id: props.schedule.id,
      origin: 'provider',
      origin_id: store.user.provider_id,
      stars: stars.value,
      comment: comment.value || null,
      improvements_ids: selectedTagIds.value,
      block_provider: false,
      block_client: isNegative.value && blockClient.value,
      favorite_provider: false,
      photos: photos.value,
    })

    onDialogOK(true)
  } catch (error) {
    const status = error?.response?.status

    if (status === 422) {
      $q.notify({ message: t('provider.dashboard.schedule_rating.already_reviewed'), color: 'negative', icon: 'mdi-alert-circle-outline' })
    } else {
      $q.notify({ message: t('http.errors.failed'), color: 'negative' })
    }
  } finally {
    loading.value = false
  }
}

//

const openHelp = () => {
  $q.dialog({ component: ProfileHelpDialog })
}

//

onMounted(async () => {
  loadingTags.value = true
  try {
    const result = await getImprovementTypes('provider')

    tags.value = result ?? []
  } catch {
    tags.value = []
  } finally {
    loadingTags.value = false
  }
})
</script>

<style scoped lang="scss">
.rating-dialog-card {
  width: 320px;
  max-width: 96vw;
  border-radius: 20px !important;
  overflow: hidden;
}

.tag-pill {
  border: 1.5px solid #d1d5db;
  border-radius: 20px;
  padding: 5px 14px;
  color: #6b7280;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
  user-select: none;

  &--selected {
    border-color: #8B5CF6;
    color: #8B5CF6;
  }
}

.submit-btn {
  padding: 10px 0;
}

.photo-thumb {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  &__remove {
    position: absolute !important;
    top: 2px;
    right: 2px;
    background: rgba(0, 0, 0, 0.5) !important;
    color: white !important;
    min-height: unset !important;
  }
}

.photo-add {
  width: 64px;
  height: 64px;
  border-radius: 8px;
  border: 1.5px dashed #d1d5db;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;

  &__label {
    color: #9ca3af;
    text-align: center;
    margin-top: 2px;
    line-height: 1.2;
  }

  &:active { background: rgba(0, 0, 0, 0.03); }
}

.hidden { display: none; }
</style>
