<script lang="ts" setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import Swal from 'sweetalert2'
import { Button } from '@/components/ui/button'
import { Lucide } from '@/components/ui/lucide'
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
import { downloadMemberDigitalCard } from '../services/member-digital-card.service'
import { toProxiedStorageUrl } from '../utils/member-digital-card.utils'
import MemberDigitalCardFlip from './MemberDigitalCardFlip.vue'

const props = defineProps<{
  memberNumber?: string | number | null
  memberName?: string | null
  memberType?: string | null
  companyName?: string | null
  profileUrl?: string | null
  imageUrl?: string | null
  large?: boolean
}>()

const previewMaxWidthClass = computed(() =>
  props.large ? 'max-w-sm sm:max-w-md lg:max-w-lg' : 'max-w-68 sm:max-w-xs',
)

const resolvedImageUrl = computed(() => toProxiedStorageUrl(props.imageUrl))

const isFlipped = ref(false)
const expandedOpen = ref(false)
const isPortraitPhone = ref(false)
const downloading = ref(false)

let portraitQuery: MediaQueryList | null = null

function updatePortraitPhone() {
  isPortraitPhone.value = portraitQuery?.matches ?? false
}

function openExpanded() {
  expandedOpen.value = true
}

function closeExpanded() {
  expandedOpen.value = false
}

function toggleFlip() {
  isFlipped.value = !isFlipped.value
}

async function downloadCard() {
  if (downloading.value) return

  downloading.value = true
  const side = isFlipped.value ? 'belakang' : 'depan'

  try {
    await downloadMemberDigitalCard(props.memberNumber, side)

    await Swal.fire({
      toast: true,
      position: 'top-end',
      icon: 'success',
      title: `Kad ${side} berjaya disimpan.`,
      showConfirmButton: false,
      timer: 3000,
    })
  } catch (error) {
    await Swal.fire({
      icon: 'error',
      title: 'Ralat',
      text: getApiErrorMessage(error, 'Gagal menyimpan kad.'),
    })
  } finally {
    downloading.value = false
  }
}

watch(expandedOpen, (open) => {
  document.body.style.overflow = open ? 'hidden' : ''
})

onMounted(() => {
  portraitQuery = window.matchMedia('(max-width: 767px) and (orientation: portrait)')
  updatePortraitPhone()
  portraitQuery.addEventListener('change', updatePortraitPhone)
})

onUnmounted(() => {
  document.body.style.overflow = ''
  portraitQuery?.removeEventListener('change', updatePortraitPhone)
})
</script>

<template>
  <div class="flex w-full flex-col items-center gap-2">
    <button
      type="button"
      class="relative w-full cursor-pointer border-0 bg-transparent p-0 transition-transform active:scale-[0.98]"
      :class="previewMaxWidthClass"
      aria-label="Buka kad digital penuh"
      @click="openExpanded">
      <MemberDigitalCardFlip :member-number="memberNumber" :member-name="memberName"
        :member-type="memberType" :company-name="companyName" :profile-url="profileUrl"
        :image-url="resolvedImageUrl" :is-flipped="isFlipped" />
    </button>

    <p class="text-center text-[11px] text-slate-500">
      Klik kad untuk paparan penuh
    </p>

    <div class="flex flex-wrap items-center justify-center gap-2">
      <Button type="button" variant="ghost" class="border border-foreground/15 shadow-none text-xs"
        :aria-pressed="isFlipped" :disabled="downloading" @click="toggleFlip">
        <Lucide class="mr-2 size-4" icon="RotateCw" />
        {{ isFlipped ? 'Papar depan kad' : 'Imbas kod QR' }}
      </Button>

      <Button type="button" variant="ghost" class="border border-foreground/15 shadow-none text-xs"
        :disabled="downloading" @click="downloadCard">
        <Lucide class="mr-2 size-4" :icon="downloading ? 'LoaderCircle' : 'Download'"
          :class="{ 'animate-spin': downloading }" />
        {{ downloading ? 'Menyimpan...' : 'Simpan kad' }}
      </Button>
    </div>

    <Teleport to="body">
      <div
        v-if="expandedOpen"
        class="fixed inset-0 z-70 flex flex-col items-center justify-center gap-4 bg-black/90 p-5"
        role="dialog"
        aria-modal="true"
        aria-label="Kad digital anggota"
        @click.self="closeExpanded">
        <button
          type="button"
          class="absolute right-4 top-4 flex size-10 items-center justify-center rounded-full border border-white/20 bg-white/10 text-white"
          aria-label="Tutup"
          @click="closeExpanded">
          <Lucide class="size-5" icon="X" />
        </button>

        <div v-if="isPortraitPhone" class="flex items-center justify-center" @click.stop>
          <div class="w-[min(90vh,34rem)] rotate-90">
            <MemberDigitalCardFlip :member-number="memberNumber" :member-name="memberName"
              :member-type="memberType" :company-name="companyName" :profile-url="profileUrl"
              :image-url="resolvedImageUrl" :is-flipped="isFlipped" expanded />
          </div>
        </div>

        <div v-else class="w-[min(100vw-2rem,32rem)] lg:w-[min(100vw-2rem,40rem)]" @click.stop>
          <MemberDigitalCardFlip :member-number="memberNumber" :member-name="memberName"
            :member-type="memberType" :company-name="companyName" :profile-url="profileUrl"
            :image-url="resolvedImageUrl" :is-flipped="isFlipped" expanded />
        </div>

        <div class="flex flex-wrap items-center justify-center gap-2">
          <Button
            type="button"
            variant="ghost"
            class="border border-white/20 bg-white/10 text-xs text-white shadow-none hover:bg-white/15"
            :aria-pressed="isFlipped"
            :disabled="downloading"
            @click.stop="toggleFlip">
            <Lucide class="mr-2 size-4" icon="RotateCw" />
            {{ isFlipped ? 'Papar depan kad' : 'Imbas kod QR' }}
          </Button>

          <Button
            type="button"
            variant="ghost"
            class="border border-white/20 bg-white/10 text-xs text-white shadow-none hover:bg-white/15"
            :disabled="downloading"
            @click.stop="downloadCard">
            <Lucide class="mr-2 size-4" :icon="downloading ? 'LoaderCircle' : 'Download'"
              :class="{ 'animate-spin': downloading }" />
            {{ downloading ? 'Menyimpan...' : 'Simpan kad' }}
          </Button>
        </div>

        <p class="text-center text-xs text-white/60">
          Klik di luar kad untuk tutup
        </p>
      </div>
    </Teleport>
  </div>
</template>
