<script lang="ts" setup>
import { computed, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
import { CircleAlert, Download, Eye } from '@lucide/vue'
import { AlertRoot, AlertTitle, AlertDescription, AlertCloseTrigger } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import { Box } from '@/components/ui/box'
import { Button } from '@/components/ui/button'
import {
  DialogRoot,
  DialogContent,
  DialogCloseTrigger,
} from '@/components/ui/dialog'
import {
  CarouselRoot,
  CarouselPrevTrigger,
  CarouselNextTrigger,
  CarouselIndicatorGroup,
  CarouselIndicator,
  CarouselItemGroup,
  CarouselItem,
} from '@/components/ui/carousel'
import { Lucide } from '@/components/ui/lucide'
import { usePermissions } from '@/composables/usePermissions'
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
import ActivityReportsSection from '../components/ActivityReportsSection.vue'
import { useActivityDetail } from '../composables/useActivityDetail'
import {
  deleteActivity,
  downloadActivityDocument,
  fetchActivityDocument,
} from '../services/activity.service'
import type { ActivityDocument } from '../types/activity.types'

const router = useRouter()
const { hasPermission } = usePermissions()
const { activity, loading, error, fetchActivity } = useActivityDetail()

const canEdit = computed(() => hasPermission('kemaskini aktiviti'))
const canDelete = computed(() => hasPermission('hapus aktiviti'))

const galleryImages = computed(() => activity.value?.gallery_images ?? [])

const deleteConfirmationOpen = ref(false)
const deletingActivity = ref(false)
const deleteError = ref<string | null>(null)

const documentPreviewOpen = ref(false)
const previewDocument = ref<ActivityDocument | null>(null)
const documentPreviewUrl = ref<string | null>(null)
const documentPreviewLoading = ref(false)
const downloadingDocumentId = ref<string | null>(null)

const isDocumentPreviewImage = computed(() =>
  previewDocument.value?.mime_type?.startsWith('image/') ?? false,
)

const isDocumentPreviewPdf = computed(() =>
  previewDocument.value?.mime_type === 'application/pdf',
)

function formatDateTime(value: string | null): string {
  if (!value) return '-'
  return dayjs(value).format('DD MMM YYYY, HH:mm')
}

function formatFileSize(bytes: number | null | undefined): string {
  if (!bytes) return '-'
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}

function documentLabel(document: ActivityDocument): string {
  if (document.type && document.type !== 'general') {
    return document.type
  }
  return document.name
}

function revokeUrl(url: string | null) {
  if (url) {
    window.URL.revokeObjectURL(url)
  }
}

function revokeDocumentPreviewUrl() {
  revokeUrl(documentPreviewUrl.value)
  documentPreviewUrl.value = null
}

async function handleDownloadDocument(document: ActivityDocument) {
  if (!activity.value || downloadingDocumentId.value) return

  downloadingDocumentId.value = document.id

  try {
    await downloadActivityDocument(
      activity.value.id,
      document.id,
      document.name,
      document.mime_type,
    )
  } catch (err) {
    error.value = getApiErrorMessage(err, 'Gagal memuat turun dokumen.')
  } finally {
    downloadingDocumentId.value = null
  }
}

async function handleViewDocument(document: ActivityDocument) {
  if (!activity.value) return

  previewDocument.value = document
  documentPreviewOpen.value = true
  documentPreviewLoading.value = true
  revokeDocumentPreviewUrl()

  try {
    const blob = await fetchActivityDocument(
      activity.value.id,
      document.id,
      document.mime_type,
    )
    documentPreviewUrl.value = window.URL.createObjectURL(blob)
  } catch (err) {
    closeDocumentPreview()
    error.value = getApiErrorMessage(err, 'Gagal memuatkan dokumen.')
  } finally {
    documentPreviewLoading.value = false
  }
}

function closeDocumentPreview() {
  documentPreviewOpen.value = false
  previewDocument.value = null
  revokeDocumentPreviewUrl()
}

function goBack() {
  router.push({ name: 'list-activities' })
}

function goToEdit() {
  if (!activity.value) return
  router.push({ name: 'edit-activity', params: { id: activity.value.id } })
}

function clearError() {
  error.value = null
}

function openDeleteConfirmation() {
  deleteError.value = null
  deleteConfirmationOpen.value = true
}

function handleDeleteConfirmationOpenChange(details: { open: boolean }) {
  if (deletingActivity.value && !details.open) {
    deleteConfirmationOpen.value = true
    return
  }

  deleteConfirmationOpen.value = details.open

  if (!details.open) {
    deleteError.value = null
  }
}

async function confirmDeleteActivity() {
  if (!activity.value || deletingActivity.value) return

  deletingActivity.value = true
  deleteError.value = null
  error.value = null

  try {
    await deleteActivity(activity.value.id)
    deleteConfirmationOpen.value = false
    router.push({ name: 'list-activities' })
  } catch (err) {
    deleteError.value = getApiErrorMessage(err, 'Gagal memadam aktiviti.')
  } finally {
    deletingActivity.value = false
  }
}

onUnmounted(() => {
  revokeDocumentPreviewUrl()
})
</script>

<template>
  <div class="w-full space-y-6">
    <div class="flex flex-wrap items-center gap-3">
      <div class="mr-auto">
        <h2 class="text-lg font-medium">Butiran Aktiviti</h2>
        <p v-if="activity" class="mt-1 text-sm opacity-70">
          {{ activity.reference_number ?? activity.id }} · {{ activity.title }}
        </p>
      </div>
      <Button look="outline" variant="secondary" type="button" @click="goBack">
        Kembali
      </Button>
      <Button v-if="canEdit" type="button" @click="goToEdit">
        <Lucide class="mr-2 size-4" icon="Pencil" />
        Kemaskini
      </Button>
      <Button
        v-if="canDelete"
        type="button"
        variant="danger"
        look="outline"
        @click="openDeleteConfirmation"
      >
        <Lucide class="mr-2 size-4" icon="Trash2" />
        Hapus
      </Button>
    </div>

    <AlertRoot v-if="error" variant="danger">
      <CircleAlert />
      <AlertTitle>Ralat</AlertTitle>
      <AlertDescription>{{ error }}</AlertDescription>
      <AlertCloseTrigger @click="clearError" />
    </AlertRoot>

    <div v-if="loading" class="opacity-70">Memuatkan butiran aktiviti...</div>

    <template v-else-if="activity">
      <Box class="p-5 sm:p-6">
        <div class="flex flex-wrap items-start justify-between gap-3">
          <div class="min-w-0">
            <div class="text-sm opacity-70">Tajuk Aktiviti</div>
            <div class="text-xl font-semibold">{{ activity.title }}</div>
          </div>
          <div class="flex flex-wrap items-center gap-2">
            <Badge look="outline" :variant="activity.is_active ? 'success' : 'outline'">
              {{ activity.is_active ? 'Aktif' : 'Tidak Aktif' }}
            </Badge>
            <Badge v-if="activity.activity_type" look="outline" variant="pending">
              {{ activity.activity_type.name }}
            </Badge>
          </div>
        </div>

        <div class="mt-4 grid gap-3 text-sm sm:grid-cols-2 lg:grid-cols-4">
          <div>
            <span class="opacity-70">No. Rujukan:</span>
            {{ activity.reference_number ?? '-' }}
          </div>
          <div>
            <span class="opacity-70">Penganjur:</span>
            {{ activity.organizer ?? '-' }}
          </div>
          <div>
            <span class="opacity-70">Lokasi:</span>
            {{ activity.location ?? '-' }}
          </div>
          <div>
            <span class="opacity-70">Tarikh Mula:</span>
            {{ formatDateTime(activity.start_datetime) }}
          </div>
          <div>
            <span class="opacity-70">Tarikh Tamat:</span>
            {{ formatDateTime(activity.end_datetime) }}
          </div>
          <div>
            <span class="opacity-70">Dicipta:</span>
            {{ formatDateTime(activity.created_at) }}
          </div>
          <div>
            <span class="opacity-70">Dikemaskini:</span>
            {{ formatDateTime(activity.updated_at) }}
          </div>
        </div>

        <div v-if="activity.description" class="mt-5 border-t border-foreground/10 pt-5">
          <div class="text-sm font-medium opacity-70">Penerangan</div>
          <p class="mt-2 whitespace-pre-line text-sm leading-relaxed">{{ activity.description }}</p>
        </div>
      </Box>

      <Box v-if="!galleryImages.length" class="p-5 sm:p-6">
        <div class="flex items-center justify-between gap-3">
          <div>
            <div class="font-medium">Galeri Foto</div>
            <p class="mt-1 text-sm opacity-70">0 imej</p>
          </div>
          <Lucide class="size-5 opacity-50" icon="Images" />
        </div>
        <div class="mt-5 opacity-70">Tiada imej galeri dimuat naik.</div>
      </Box>

      <Box v-else class="overflow-hidden p-0">
        <CarouselRoot
          :default-page="0"
          :slide-count="galleryImages.length"
          class="w-full border-0"
        >
          <div class="flex items-center border-b border-foreground/15 px-5 py-4">
            <div class="mr-auto min-w-0">
              <div class="font-medium">Galeri Foto</div>
              <p class="mt-1 text-sm opacity-70">{{ galleryImages.length }} imej</p>
            </div>
            <Lucide class="mr-3 size-5 opacity-50" icon="Images" />
            <template v-if="galleryImages.length > 1">
              <CarouselPrevTrigger as-child>
                <Button variant="ghost" class="mr-2 border border-foreground/15 shadow-none" type="button">
                  <Lucide class="size-4" icon="ChevronLeft" />
                </Button>
              </CarouselPrevTrigger>
              <CarouselNextTrigger as-child>
                <Button variant="ghost" class="border border-foreground/15 shadow-none" type="button">
                  <Lucide class="size-4" icon="ChevronRight" />
                </Button>
              </CarouselNextTrigger>
            </template>
          </div>

          <div class="px-5 pb-2">
            <CarouselItemGroup>
              <CarouselItem
                v-for="(image, index) in galleryImages"
                :key="image.id"
                :index="index"
                class="w-full"
              >
                <div class="flex flex-col items-center py-4">
                  <div
                    class="flex w-full items-center justify-center overflow-hidden rounded-lg border border-foreground/10 bg-foreground/5"
                    style="min-height: 16rem; max-height: 28rem"
                  >
                    <img
                      :src="image.url"
                      :alt="image.name"
                      class="block max-h-112 w-full object-contain"
                    />
                  </div>
                  <div class="mt-3 w-full text-center">
                    <div class="truncate text-sm font-medium">{{ image.name }}</div>
                    <div v-if="image.description" class="mt-1 text-xs opacity-70">
                      {{ image.description }}
                    </div>
                  </div>
                </div>
              </CarouselItem>
            </CarouselItemGroup>
          </div>

          <div
            v-if="galleryImages.length > 1"
            class="flex justify-center border-t border-foreground/10 px-5 py-4"
          >
            <CarouselIndicatorGroup>
              <CarouselIndicator
                v-for="(image, index) in galleryImages"
                :key="image.id"
                :index="index"
              />
            </CarouselIndicatorGroup>
          </div>
        </CarouselRoot>
      </Box>

      <Box class="p-5 sm:p-6">
        <div class="flex items-center justify-between gap-3">
          <div>
            <div class="font-medium">Dokumen Lampiran</div>
            <p class="mt-1 text-sm opacity-70">
              {{ activity.documents.length }} dokumen · muat turun atau lihat
            </p>
          </div>
          <Lucide class="size-5 opacity-50" icon="Paperclip" />
        </div>

        <div v-if="!activity.documents.length" class="mt-5 opacity-70">
          Tiada dokumen lampiran.
        </div>

        <div v-else class="mt-5 space-y-3">
          <div
            v-for="document in activity.documents"
            :key="document.id"
            class="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-foreground/10 p-4"
          >
            <div class="min-w-0">
              <div class="flex items-center gap-2">
                <Lucide
                  class="size-4 shrink-0 opacity-60"
                  :icon="document.mime_type?.startsWith('image/') ? 'Image' : 'FileText'"
                />
                <div class="truncate font-medium">{{ documentLabel(document) }}</div>
              </div>
              <div class="mt-1 text-sm opacity-70">
                {{ document.name }} · {{ formatFileSize(document.file_size) }}
              </div>
              <div v-if="document.description" class="mt-1 text-sm opacity-70">
                {{ document.description }}
              </div>
            </div>
            <div class="flex flex-wrap items-center gap-2">
              <Button
                type="button"
                look="outline"
                size="sm"
                :disabled="documentPreviewLoading && previewDocument?.id === document.id"
                @click="handleViewDocument(document)"
              >
                <Eye class="mr-2 size-4" />
                {{
                  documentPreviewLoading && previewDocument?.id === document.id
                    ? 'Memuatkan...'
                    : 'Lihat'
                }}
              </Button>
              <Button
                type="button"
                look="outline"
                size="sm"
                :disabled="downloadingDocumentId === document.id"
                @click="handleDownloadDocument(document)"
              >
                <Download class="mr-2 size-4" />
                {{
                  downloadingDocumentId === document.id ? 'Memuat turun...' : 'Muat Turun'
                }}
              </Button>
            </div>
          </div>
        </div>
      </Box>

      <ActivityReportsSection
        v-if="activity"
        :activity-id="activity.id"
        :reports="activity.reports ?? []"
        @changed="fetchActivity"
      />
    </template>
  </div>

  <Teleport to="body">
    <div
      v-if="documentPreviewOpen"
      class="fixed inset-0 z-70 flex items-center justify-center p-4 sm:p-6"
      role="dialog"
      aria-modal="true"
      :aria-label="previewDocument ? documentLabel(previewDocument) : 'Pratonton dokumen'"
    >
      <button
        type="button"
        class="absolute inset-0 bg-black/80"
        aria-label="Tutup pratonton dokumen"
        @click="closeDocumentPreview"
      />

      <div class="relative z-10 flex w-full max-w-5xl flex-col overflow-hidden rounded-2xl border border-foreground/10 bg-background shadow-2xl">
        <div class="border-b border-foreground/10 px-5 py-4">
          <div class="text-lg font-medium">
            {{ previewDocument ? documentLabel(previewDocument) : 'Pratonton Dokumen' }}
          </div>
          <div v-if="previewDocument" class="mt-1 text-sm opacity-70">
            {{ previewDocument.name }} · {{ formatFileSize(previewDocument.file_size) }}
          </div>
        </div>

        <div class="overflow-auto p-5">
          <div v-if="documentPreviewLoading" class="py-12 text-center opacity-70">
            Memuatkan dokumen...
          </div>

          <div v-else-if="documentPreviewUrl && isDocumentPreviewImage" class="flex justify-center">
            <img
              :src="documentPreviewUrl"
              :alt="previewDocument?.name ?? 'Pratonton dokumen'"
              class="block h-auto max-h-[calc(90vh-12rem)] w-auto max-w-full object-contain"
            />
          </div>

          <iframe
            v-else-if="documentPreviewUrl && isDocumentPreviewPdf"
            :src="documentPreviewUrl"
            class="block w-full rounded-lg border border-foreground/10"
            style="height: min(70vh, 720px)"
            :title="previewDocument?.name ?? 'Pratonton dokumen'"
          />

          <div v-else-if="documentPreviewUrl" class="py-12 text-center opacity-70">
            Pratonton tidak tersedia untuk jenis fail ini. Sila muat turun dokumen.
          </div>
        </div>

        <div class="flex justify-end gap-2 border-t border-foreground/10 px-5 py-4">
          <Button
            v-if="previewDocument"
            type="button"
            look="outline"
            :disabled="downloadingDocumentId === previewDocument.id"
            @click="handleDownloadDocument(previewDocument)"
          >
            <Download class="mr-2 size-4" />
            Muat Turun
          </Button>
          <Button type="button" look="outline" @click="closeDocumentPreview">
            Tutup
          </Button>
        </div>
      </div>
    </div>
  </Teleport>

  <DialogRoot :open="deleteConfirmationOpen" @openChange="handleDeleteConfirmationOpenChange">
    <DialogContent>
      <div class="p-5 text-center">
        <Lucide class="text-danger mx-auto mt-3 size-16 stroke-1" icon="CircleX" />
        <div class="mt-5 text-2xl font-medium">Padam Aktiviti?</div>
        <div class="mt-2 opacity-70">
          Adakah anda benar-benar mahu memadam
          <span v-if="activity" class="font-medium">{{ activity.title }}</span>?
          <br />
          Semua dokumen, galeri, dan laporan berkaitan turut akan dipadam.
        </div>
        <div v-if="deleteError" class="mt-4 text-sm text-danger">
          {{ deleteError }}
        </div>
      </div>
      <div class="px-5 pb-8 text-center">
        <DialogCloseTrigger class="mr-2 w-24" :disabled="deletingActivity">
          Batal
        </DialogCloseTrigger>
        <Button
          class="w-24"
          type="button"
          variant="danger"
          look="outline"
          :disabled="deletingActivity"
          @click="confirmDeleteActivity"
        >
          {{ deletingActivity ? 'Memadam...' : 'Hapus' }}
        </Button>
      </div>
    </DialogContent>
  </DialogRoot>
</template>
