<template>
  <q-dialog ref="dialogRef" persistent maximized transition-show="slide-up" transition-hide="slide-down" @hide="onDialogHide">
    <div class="bg-page full-height column">

      <div class="row items-center q-px-md q-pt-md q-pb-sm bg-surface shadow-header">
        <q-btn class="header-back-btn" icon="mdi-chevron-left" flat round dense color="primary" @click="onDialogCancel" />
        <q-space />
        <span class="font16 fontbold gradient-diarista">
          {{ $t('payment.pix_title') }}
        </span>
        <q-space />
        <div style="width: 32px" />
      </div>

      <div v-if="success" class="col column items-center justify-center q-px-xl">
        <q-btn
          flat round icon="mdi-close" color="grey-5"
          class="self-end q-mb-md"
          @click="onDialogOK"
        />
        <div class="success-icon-wrapper q-mb-lg">
          <q-icon name="mdi-check-circle" size="100px" color="primary" />
        </div>
        <div class="success-title text-primary text-center q-mb-sm">
          {{ $t('payment.success_title') }}
        </div>
        <i18n-t keypath="payment.success_message" tag="div" class="success-message text-grey-6 text-center">
          <template #nextServices>
            <strong class="text-text">{{ $t('payment.success_next_services') }}</strong>
          </template>
          <template #agenda>
            <strong class="text-text">{{ $t('payment.success_agenda') }}</strong>
          </template>
        </i18n-t>
      </div>

      <div v-else-if="processing" class="col column items-center justify-center q-px-xl">
        <q-spinner-oval color="primary" size="72px" class="q-mb-lg" />
        <div class="processing-title text-primary text-center q-mb-sm">
          {{ $t('payment.processing_title') }}
        </div>
        <div class="processing-message text-grey-6 text-center">
          {{ $t('payment.processing_message') }}
        </div>
      </div>

      <div v-else class="pix-payment-content col scroll q-px-lg q-pt-lg q-pb-xl column">

        <div class="row items-center justify-between q-mb-sm">
          <span class="pix-label font14 fontbold">{{ $t('payment.pix_total') }}</span>
          <span class="text-primary font14 fontbold">{{ formatCurrency(total) }}</span>
        </div>
        <q-separator />

        <div class="row items-center justify-between q-mt-sm q-mb-lg">
          <span class="pix-label font14 fontbold">{{ $t('payment.pix_expires') }}</span>
          <span class="text-primary font14 fontbold">{{ countdown }}</span>
        </div>

        <div class="flex flex-center q-mb-md">
          <q-icon name="mdi-cash-fast" size="48px" color="teal" />
        </div>

        <div class="flex flex-center q-mb-md">
          <q-img
            v-if="pixQrCodeUrl"
            :src="pixQrCodeUrl"
            width="180px"
            height="180px"
            fit="contain"
            class="qrcode-wrapper"
          />
          <div v-else class="qrcode-wrapper column items-center justify-center">
            <q-icon name="mdi-qrcode" size="80px" color="grey-6" />
          </div>
        </div>

        <div class="pix-code-text q-mb-md">{{ pixCode || 'Código Pix indisponível.' }}</div>

        <q-btn
          unelevated
          rounded
          no-caps
          color="primary"
          padding="4px 12px"
          class="full-width q-mb-lg"
          :label="$t('payment.pix_copy_btn')"
          :loading="processing"
          @click="copyCode"
        />

        <i18n-t keypath="payment.pix_instructions" tag="p" class="pix-instructions-text font14 q-mb-sm">
          <template #copyCode>
            <span class="fontbold">{{ $t('payment.pix_copy_code') }}</span>
          </template>
          <template #pasteCode>
            <span class="fontbold">{{ $t('payment.pix_paste_code') }}</span>
          </template>
          <template #finalize>
            <span class="fontbold">{{ $t('payment.pix_finalize') }}</span>
          </template>
        </i18n-t>
        <p class="pix-instructions-text font14">{{ $t('payment.pix_email_note') }}</p>
      </div>
    </div>
  </q-dialog>
</template>

<script setup>
import { computed, ref, onMounted, onUnmounted } from 'vue'
import { useDialogPluginComponent, useQuasar, copyToClipboard } from 'quasar'
import { formatCurrency } from 'src/helpers/utils'
import { getServicePackagePix, payServicePackage } from 'src/api/payment'
import { usePaymentStore } from 'src/stores/payment'

const props = defineProps({
  servicePackage: { type: Object, required: true },
  total: { type: Number, required: true },
})

defineEmits([...useDialogPluginComponent.emits])

const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar()
const paymentStore = usePaymentStore()

const item = computed(() => props.servicePackage)
const itemId = computed(() => item.value.id)

const payment = ref(null)
const success = ref(false)
const processing = ref(true)

const pixData = computed(() => payment.value?.pix ?? {})
const pixCode = computed(() => pixData.value?.qr_code ?? '')
const pixQrCodeUrl = computed(() => pixData.value?.qr_code_url ?? '')
const pixExpiresAt = computed(() => pixData.value?.expires_at ?? payment.value?.expires_at ?? null)

const copyCode = async () => {
  try {
    if (!pixCode.value) {
      $q.notify({ type: 'negative', message: 'Código Pix indisponível.' })
      return
    }

    await copyToClipboard(pixCode.value)
    $q.notify({ type: 'positive', message: 'Código copiado!' })
  } catch {
    $q.notify({ type: 'negative', message: 'Erro ao copiar.' })
    return
  }

}

const totalSeconds = ref(20 * 60)
const countdown = ref('')
let countdownTimer = null
let pollingTimer = null
let pollingInFlight = false

const stopPolling = () => {
  clearInterval(pollingTimer)
  pollingTimer = null
}

const applyPaymentStatus = (nextPayment) => {
  if (!nextPayment) return

  payment.value = nextPayment

  if (nextPayment.status === 'paid') {
    success.value = true
    processing.value = false
    paymentStore.clearPixPaymentForServicePackage(itemId.value)
    stopPolling()
    return
  }

  if (['failed', 'cancelled'].includes(nextPayment.status)) {
    processing.value = false
    paymentStore.clearPixPaymentForServicePackage(itemId.value)
    stopPolling()
    $q.notify({ type: 'negative', message: nextPayment.failure_message || 'Pagamento Pix não confirmado.' })
    onDialogCancel()
    return
  }

  paymentStore.setPixPaymentForServicePackage(itemId.value, nextPayment)
}

const checkPaymentStatus = async () => {
  if (pollingInFlight || success.value || totalSeconds.value <= 0) return

  pollingInFlight = true
  try {
    const result = await getServicePackagePix(itemId.value)
    applyPaymentStatus(result)
    updateCountdown()
  } catch (e) {
    console.error('Erro ao verificar pagamento Pix:', e)
  } finally {
    pollingInFlight = false
  }
}

const startPolling = () => {
  stopPolling()
  if (success.value || ['failed', 'cancelled'].includes(payment.value?.status) || totalSeconds.value <= 0) return
  checkPaymentStatus()
  pollingTimer = setInterval(checkPaymentStatus, 5000)
}

const updateCountdown = () => {
  if (pixExpiresAt.value) {
    totalSeconds.value = Math.max(0, Math.floor((new Date(pixExpiresAt.value).getTime() - Date.now()) / 1000))
  }

  const m = Math.floor(totalSeconds.value / 60)
  const s = totalSeconds.value % 60
  countdown.value = `${m} min, ${String(s).padStart(2, '0')} seg`
  if (!pixExpiresAt.value && totalSeconds.value > 0) totalSeconds.value--

  if (pixExpiresAt.value && totalSeconds.value <= 0) {
    paymentStore.clearPixPaymentForServicePackage(itemId.value)
    stopPolling()
  }
}

onMounted(async () => {
  updateCountdown()
  countdownTimer = setInterval(updateCountdown, 1000)

  try {
    const cachedPayment = paymentStore.getValidPixPaymentForServicePackage(itemId.value)

    if (cachedPayment) {
      applyPaymentStatus(cachedPayment)
      updateCountdown()
      startPolling()
      return
    }

    const paymentResult = await payServicePackage(itemId.value, { payment_method: 'pix' })

    applyPaymentStatus(paymentResult)
    updateCountdown()
    startPolling()
  } catch (e) {
    console.error('Erro ao criar pagamento Pix:', e)

    if (e.response?.data?.error !== 'missing_payment_data') {
      $q.notify({ type: 'negative', message: e?.response?.data?.message ?? 'Erro ao criar pagamento Pix.' })
    }

    onDialogCancel()
  } finally {
    processing.value = false
  }
})

onUnmounted(() => {
  clearInterval(countdownTimer)
  stopPolling()
})
</script>

<style scoped lang="scss">
.shadow-header {
  box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
}

.pix-label {
  color: #3a3a4a;
}

.qrcode-wrapper {
  background: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  padding: 12px;
}

.pix-code-text {
  color: #5a5a6a;
  text-align: center;
  word-break: break-all;
  line-height: 1.5;
  background: #f5f5f8;
  border-radius: 8px;
  padding: 10px;
}


.pix-instructions-text {
  align-self: stretch;
  line-height: 1.5;
  color: #3a3a4a;
  margin-left: 0;
  margin-right: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  text-align: left;
  width: 100%;
}

.success-icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
}

.success-title {
  line-height: 1.3;
  max-width: 280px;
}

.success-message {
  line-height: 1.6;
  max-width: 280px;
}
</style>
