<script lang="ts" setup>
import { computed, ref } from 'vue'
import dayjs from 'dayjs'
import { Box } from '@/components/ui/box'
import { Button } from '@/components/ui/button'
import {
  DialogRoot,
  DialogContent,
  DialogTitle,
  DialogDescription,
  DialogCloseTrigger,
} from '@/components/ui/dialog'
import { Field, FieldLabel, FieldError } from '@/components/ui/field'
import { Lucide } from '@/components/ui/lucide'
import { Textarea } from '@/components/ui/textarea'
import { usePermissions } from '@/composables/usePermissions'
import { getApiErrorMessage, getApiValidationErrors } from '@/core/utils/getApiErrorMessage'
import { createActivityReport, deleteActivityReport, updateActivityReport } from '../services/activity.service'
import type { ActivityReport } from '../types/activity.types'

type ReportModalMode = 'create' | 'edit'

const props = defineProps<{
  activityId: string
  reports: ActivityReport[]
}>()

const emit = defineEmits<{
  changed: []
}>()

const { hasPermission } = usePermissions()

const canCreateReport = computed(() => hasPermission('tambah laporan aktiviti'))
const canEditReport = computed(() => hasPermission('kemaskini laporan aktiviti'))
const canDeleteReport = computed(() => hasPermission('hapus laporan aktiviti'))

const reportModalOpen = ref(false)
const reportModalMode = ref<ReportModalMode>('create')
const editingReportId = ref<string | null>(null)
const reportText = ref('')
const reportFieldError = ref<string | null>(null)
const savingReport = ref(false)

const deleteConfirmationOpen = ref(false)
const reportToDelete = ref<ActivityReport | null>(null)
const deletingReport = ref(false)
const deleteError = ref<string | null>(null)

const isEditMode = computed(() => reportModalMode.value === 'edit')

const reportModalTitle = computed(() =>
  isEditMode.value ? 'Kemaskini Laporan Aktiviti' : 'Tambah Laporan Aktiviti',
)

const reportModalDescription = computed(() =>
  isEditMode.value
    ? 'Kemaskini kandungan laporan aktiviti ini.'
    : 'Rekod laporan untuk aktiviti ini. Laporan akan dikaitkan dengan akaun anda.',
)

const reportSubmitLabel = computed(() => {
  if (savingReport.value) return 'Menyimpan...'
  return isEditMode.value ? 'Simpan Perubahan' : 'Simpan Laporan'
})

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

function resetReportForm() {
  reportText.value = ''
  reportFieldError.value = null
  editingReportId.value = null
  reportModalMode.value = 'create'
}

function openCreateReportModal() {
  resetReportForm()
  reportModalMode.value = 'create'
  reportModalOpen.value = true
}

function openEditReportModal(report: ActivityReport) {
  reportFieldError.value = null
  reportModalMode.value = 'edit'
  editingReportId.value = report.id
  reportText.value = report.report_text
  reportModalOpen.value = true
}

function handleReportModalOpenChange(details: { open: boolean }) {
  if (savingReport.value && !details.open) {
    reportModalOpen.value = true
    return
  }

  reportModalOpen.value = details.open

  if (!details.open) {
    resetReportForm()
  }
}

async function handleSubmitReport() {
  if (savingReport.value) return

  const trimmedText = reportText.value.trim()
  if (!trimmedText) {
    reportFieldError.value = 'Laporan diperlukan.'
    return
  }

  savingReport.value = true
  reportFieldError.value = null

  try {
    if (isEditMode.value && editingReportId.value) {
      await updateActivityReport(editingReportId.value, {
        activity_id: props.activityId,
        report_text: trimmedText,
      })
    } else {
      await createActivityReport({
        activity_id: props.activityId,
        report_text: trimmedText,
      })
    }

    reportModalOpen.value = false
    resetReportForm()
    emit('changed')
  } catch (err) {
    const validationErrors = getApiValidationErrors(err)
    if (validationErrors?.report_text?.[0]) {
      reportFieldError.value = validationErrors.report_text[0]
    } else {
      reportFieldError.value = getApiErrorMessage(
        err,
        isEditMode.value
          ? 'Gagal mengemaskini laporan aktiviti.'
          : 'Gagal menambah laporan aktiviti.',
      )
    }
  } finally {
    savingReport.value = false
  }
}

function openDeleteConfirmation(report: ActivityReport) {
  reportToDelete.value = report
  deleteError.value = null
  deleteConfirmationOpen.value = true
}

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

  deleteConfirmationOpen.value = details.open

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

async function confirmDeleteReport() {
  if (!reportToDelete.value || deletingReport.value) return

  deletingReport.value = true
  deleteError.value = null

  try {
    await deleteActivityReport(reportToDelete.value.id)
    deleteConfirmationOpen.value = false
    reportToDelete.value = null
    emit('changed')
  } catch (err) {
    deleteError.value = getApiErrorMessage(err, 'Gagal memadam laporan aktiviti.')
  } finally {
    deletingReport.value = false
  }
}
</script>

<template>
  <Box class="p-5 sm:p-6">
    <div class="flex flex-wrap items-center justify-between gap-3">
      <div>
        <div class="font-medium">Laporan Aktiviti</div>
        <p class="mt-1 text-sm opacity-70">{{ reports.length }} laporan</p>
      </div>
      <div class="flex items-center gap-2">
        <Button
          v-if="canCreateReport"
          type="button"
          look="outline"
          size="sm"
          @click="openCreateReportModal"
        >
          <Lucide class="mr-2 size-4" icon="Plus" />
          Tambah Laporan
        </Button>
        <Lucide class="size-5 opacity-50" icon="FileText" />
      </div>
    </div>

    <div v-if="!reports.length" class="mt-5 opacity-70">Tiada laporan aktiviti.</div>

    <div v-else class="mt-5 space-y-4">
      <div
        v-for="report in reports"
        :key="report.id"
        class="rounded-lg border border-foreground/10 p-4"
      >
        <div
          class="flex flex-wrap items-start justify-between gap-3 border-b border-foreground/10 pb-3"
        >
          <div class="min-w-0">
            <div class="text-sm font-medium">
              {{ report.prepared_by_user?.name ?? 'Pengguna' }}
            </div>
            <div v-if="report.prepared_by_user?.email" class="mt-0.5 text-xs opacity-70">
              {{ report.prepared_by_user.email }}
            </div>
          </div>
          <div class="flex items-center gap-2">
            <div class="text-xs opacity-70">
              {{ formatDateTime(report.created_at) }}
            </div>
            <Button
              v-if="canEditReport"
              type="button"
              variant="ghost"
              size="sm"
              class="size-8 p-0"
              title="Kemaskini laporan"
              @click="openEditReportModal(report)"
            >
              <Lucide class="size-4 opacity-70" icon="Pencil" />
            </Button>
            <Button
              v-if="canDeleteReport"
              type="button"
              variant="ghost"
              size="sm"
              class="size-8 p-0"
              title="Padam laporan"
              @click="openDeleteConfirmation(report)"
            >
              <Lucide class="size-4 text-danger opacity-80" icon="Trash2" />
            </Button>
          </div>
        </div>
        <p class="mt-3 whitespace-pre-line text-sm leading-relaxed">
          {{ report.report_text }}
        </p>
      </div>
    </div>
  </Box>

  <DialogRoot :open="reportModalOpen" @openChange="handleReportModalOpenChange">
    <DialogContent class="max-w-lg">
      <DialogTitle>{{ reportModalTitle }}</DialogTitle>
      <DialogDescription>{{ reportModalDescription }}</DialogDescription>

      <form class="mt-4 space-y-4" @submit.prevent="handleSubmitReport">
        <Field>
          <FieldLabel for="activity-report-text">Laporan</FieldLabel>
          <Textarea
            id="activity-report-text"
            v-model="reportText"
            rows="6"
            placeholder="Tulis laporan aktiviti..."
            :disabled="savingReport"
            required
          />
          <FieldError v-if="reportFieldError">{{ reportFieldError }}</FieldError>
        </Field>

        <div class="flex justify-end gap-2 pt-2">
          <DialogCloseTrigger look="outline" variant="secondary" :disabled="savingReport">
            Batal
          </DialogCloseTrigger>
          <Button type="submit" variant="primary" :disabled="savingReport">
            {{ reportSubmitLabel }}
          </Button>
        </div>
      </form>
    </DialogContent>
  </DialogRoot>

  <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 Laporan Aktiviti?</div>
        <div class="mt-2 opacity-70">
          Adakah anda benar-benar mahu memadam laporan ini?
          <br />
          Proses ini tidak boleh dibatalkan.
        </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="deletingReport">
          Batal
        </DialogCloseTrigger>
        <Button
          class="w-24"
          type="button"
          variant="danger"
          look="outline"
          :disabled="deletingReport"
          @click="confirmDeleteReport"
        >
          {{ deletingReport ? 'Memadam...' : 'Padam' }}
        </Button>
      </div>
    </DialogContent>
  </DialogRoot>
</template>
