<script lang="ts" setup>
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
import * as select from '@zag-js/select'
import { CircleAlert, Eye } from '@lucide/vue'
import { AlertRoot, AlertTitle, AlertDescription, AlertCloseTrigger } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
  SelectRoot,
  SelectControl,
  SelectTrigger,
  SelectValueText,
  SelectContent,
  SelectItemGroup,
  SelectItemGroupLabel,
  SelectItem,
  SelectItemText,
} from '@/components/ui/select'
import DataTable from '@/components/ui/usage/DataTable.vue'
import type { TableHeader } from '@/components/ui/usage/DataTable.vue'
import { usePermissions } from '@/composables/usePermissions'
import type { BadgeVariants } from '@/components/ui/styles/badge.styles'
import { useFeedbackList } from '../composables/useFeedbackList'
import {
  FEEDBACK_PRIORITY_OPTIONS,
  FEEDBACK_STATUS_OPTIONS,
  FEEDBACK_TYPE_OPTIONS,
  feedbackPriorityLabel,
  feedbackStatusLabel,
  feedbackTypeLabel,
  type FeedbackListItem,
  type FeedbackPriority,
  type FeedbackStatus,
  type FeedbackType,
} from '../types/feedback.types'

type SelectOption = { label: string; value: string }

const TYPE_FILTER_OPTIONS: SelectOption[] = [
  { label: 'Semua Jenis', value: '' },
  ...FEEDBACK_TYPE_OPTIONS,
]

const STATUS_FILTER_OPTIONS: SelectOption[] = [
  { label: 'Semua Status', value: '' },
  ...FEEDBACK_STATUS_OPTIONS,
]

const PRIORITY_FILTER_OPTIONS: SelectOption[] = [
  { label: 'Semua Keutamaan', value: '' },
  ...FEEDBACK_PRIORITY_OPTIONS,
]

function createSelectCollection(options: SelectOption[]) {
  return select.collection({
    items: options,
    itemToValue: (item) => item.label,
  })
}

function labelToValue(options: SelectOption[], label: string | undefined): string {
  if (!label) return ''
  return options.find((option) => option.label === label)?.value ?? ''
}

function valueToLabel(options: SelectOption[], value: string): string[] {
  const option = options.find((item) => item.value === value)
  return option ? [option.label] : [options[0]?.label ?? '']
}

function statusVariant(status: FeedbackStatus): BadgeVariants['variant'] {
  switch (status) {
    case 'resolved':
    case 'closed':
      return 'success'
    case 'in_progress':
      return 'primary'
    case 'rejected':
      return 'danger'
    case 'open':
      return 'warning'
    default:
      return 'secondary'
  }
}

function priorityVariant(priority: FeedbackPriority): BadgeVariants['variant'] {
  switch (priority) {
    case 'critical':
    case 'high':
      return 'danger'
    case 'medium':
      return 'warning'
    default:
      return 'secondary'
  }
}

const headers: TableHeader[] = [
  { title: 'Tajuk', key: 'title', sortable: true },
  { title: 'Jenis', key: 'type', sortable: true },
  { title: 'Keutamaan', key: 'priority', sortable: true },
  { title: 'Status', key: 'status', sortable: true },
  { title: 'Penghantar', key: 'user' },
  { title: 'Dihantar', key: 'created_at', sortable: true },
  { title: 'Tindakan', key: 'actions', sortable: false },
]

const typeCollection = createSelectCollection(TYPE_FILTER_OPTIONS)
const statusCollection = createSelectCollection(STATUS_FILTER_OPTIONS)
const priorityCollection = createSelectCollection(PRIORITY_FILTER_OPTIONS)

const router = useRouter()
const { hasPermission } = usePermissions()

const {
  items,
  loading,
  error,
  search,
  typeFilter,
  statusFilter,
  priorityFilter,
  sortBy,
  page,
  itemsPerPage,
  pagination,
  handleSortUpdate,
} = useFeedbackList()

const canView = computed(() => hasPermission('lihat maklum balas'))

const typeInitial = computed(() => valueToLabel(TYPE_FILTER_OPTIONS, typeFilter.value))
const statusInitial = computed(() => valueToLabel(STATUS_FILTER_OPTIONS, statusFilter.value))
const priorityInitial = computed(() => valueToLabel(PRIORITY_FILTER_OPTIONS, priorityFilter.value))

function setTypeFilter(details: { value: string[] }) {
  typeFilter.value = labelToValue(TYPE_FILTER_OPTIONS, details.value[0]) as FeedbackType | ''
}

function setStatusFilter(details: { value: string[] }) {
  statusFilter.value = labelToValue(STATUS_FILTER_OPTIONS, details.value[0]) as FeedbackStatus | ''
}

function setPriorityFilter(details: { value: string[] }) {
  priorityFilter.value = labelToValue(PRIORITY_FILTER_OPTIONS, details.value[0]) as FeedbackPriority | ''
}

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

function goToDetail(id: string) {
  router.push({ name: 'view-feedback', params: { id } })
}

function goToSubmit() {
  router.push({ name: 'feedback-submit' })
}
</script>

<template>
  <div>
    <div class="flex flex-col items-center sm:flex-row">
      <div class="mr-auto">
        <h2 class="text-lg font-medium">Senarai Maklum Balas</h2>
        <p class="mt-1 text-sm opacity-70">Urus laporan ralat, cadangan dan isu pengguna.</p>
      </div>
      <div class="mt-4 flex w-full sm:mt-0 sm:w-auto">
        <Button look="outline" variant="primary" class="shadow-sm" @click="goToSubmit">
          Hantar Maklum Balas
        </Button>
      </div>
    </div>

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

    <div class="mt-5">
      <DataTable :headers="headers" :items="items" :loading="loading" :pagination="pagination" :current-sort="sortBy"
        show-pagination exportable export-file-name="maklum-balas" v-model:page="page"
        v-model:items-per-page="itemsPerPage" @update:sort-by="handleSortUpdate">
        <template #toolbar>
          <div class="flex w-full flex-wrap items-center gap-3">
            <Input v-model="search" class="w-full max-w-md" type="search" placeholder="Cari tajuk atau penerangan..."
              aria-label="Cari maklum balas" />

            <SelectRoot class="w-full sm:w-52" :collection="typeCollection" :default-value="typeInitial"
              @value-change="setTypeFilter">
              <SelectControl>
                <SelectTrigger aria-label="Tapis jenis">
                  <SelectValueText placeholder="Semua Jenis" />
                </SelectTrigger>
              </SelectControl>
              <SelectContent>
                <SelectItemGroup>
                  <SelectItemGroupLabel>Jenis</SelectItemGroupLabel>
                  <SelectItem v-for="item in typeCollection.items" :key="item.label" :item="item">
                    <SelectItemText>{{ item.label }}</SelectItemText>
                  </SelectItem>
                </SelectItemGroup>
              </SelectContent>
            </SelectRoot>

            <SelectRoot class="w-full sm:w-52" :collection="statusCollection" :default-value="statusInitial"
              @value-change="setStatusFilter">
              <SelectControl>
                <SelectTrigger aria-label="Tapis status">
                  <SelectValueText placeholder="Semua Status" />
                </SelectTrigger>
              </SelectControl>
              <SelectContent>
                <SelectItemGroup>
                  <SelectItemGroupLabel>Status</SelectItemGroupLabel>
                  <SelectItem v-for="item in statusCollection.items" :key="item.label" :item="item">
                    <SelectItemText>{{ item.label }}</SelectItemText>
                  </SelectItem>
                </SelectItemGroup>
              </SelectContent>
            </SelectRoot>

            <SelectRoot class="w-full sm:w-52" :collection="priorityCollection" :default-value="priorityInitial"
              @value-change="setPriorityFilter">
              <SelectControl>
                <SelectTrigger aria-label="Tapis keutamaan">
                  <SelectValueText placeholder="Semua Keutamaan" />
                </SelectTrigger>
              </SelectControl>
              <SelectContent>
                <SelectItemGroup>
                  <SelectItemGroupLabel>Keutamaan</SelectItemGroupLabel>
                  <SelectItem v-for="item in priorityCollection.items" :key="item.label" :item="item">
                    <SelectItemText>{{ item.label }}</SelectItemText>
                  </SelectItem>
                </SelectItemGroup>
              </SelectContent>
            </SelectRoot>
          </div>
        </template>

        <template #item.title="{ item }">
          <div class="font-medium">{{ (item as FeedbackListItem).title }}</div>
          <div class="mt-0.5 line-clamp-1 text-xs opacity-60">
            {{ (item as FeedbackListItem).description }}
          </div>
        </template>

        <template #item.type="{ item }">
          {{ feedbackTypeLabel((item as FeedbackListItem).type) }}
        </template>

        <template #item.priority="{ item }">
          <Badge look="outline" :variant="priorityVariant((item as FeedbackListItem).priority)">
            {{ feedbackPriorityLabel((item as FeedbackListItem).priority) }}
          </Badge>
        </template>

        <template #item.status="{ item }">
          <Badge look="outline" :variant="statusVariant((item as FeedbackListItem).status)">
            {{ feedbackStatusLabel((item as FeedbackListItem).status) }}
          </Badge>
        </template>

        <template #item.user="{ item }">
          {{ (item as FeedbackListItem).user?.name ?? 'Tetamu' }}
        </template>

        <template #item.created_at="{ item }">
          {{ formatDate((item as FeedbackListItem).created_at) }}
        </template>

        <template #item.actions="{ item }">
          <Button v-if="canView" type="button" variant="ghost" size="sm" class="bg-green-600 text-white"
            title="Lihat butiran" @click="goToDetail((item as FeedbackListItem).id)">
            <Eye class="size-4" aria-hidden="true" />
          </Button>
        </template>
      </DataTable>
    </div>
  </div>
</template>
