<script setup lang="ts">
import AppSidebar from '@/components/AppSidebar.vue'
import SiteHeader from '@/components/SiteHeader.vue'
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'

import { ChevronDown, Loader2, Plus, X } from '@lucide/vue'
import { computed, ref, watch } from 'vue'
import { toast } from 'vue-sonner'

import DataTable from '@/components/data-table/DataTable.vue'
import { Button } from '@/components/ui/button'
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import {
  Field,
  FieldGroup,
  FieldLabel,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { type Plan, getColumns } from './columns'

const config = useRuntimeConfig()

const { data: plans, status, refresh } = useFetch<Plan[]>(`${config.public.apiBase}/plans`)

const tableRef = ref<InstanceType<typeof DataTable>>()

// --- Dialog states ---
const formOpen = ref(false)
const deleteOpen = ref(false)

// --- Form state ---
type FormMode = 'create' | 'edit'

const formMode = ref<FormMode>('create')
const selectedPlan = ref<Plan | null>(null)

interface FormData {
  name: string
  description: string
  price: string
}

const form = ref<FormData>({ name: '', description: '', price: '' })

// --- Loading states ---
const formLoading = ref(false)
const deleteLoading = ref(false)

// --- Computed ---
const formTitle = computed(() => formMode.value === 'create' ? 'Tambah Paket' : 'Edit Paket')

// --- Table callbacks ---
function openCreateForm() {
  formMode.value = 'create'
  selectedPlan.value = null
  form.value = { name: '', description: '', price: '' }
  formOpen.value = true
}

function handleEdit(plan: Plan) {
  formMode.value = 'edit'
  selectedPlan.value = plan
  form.value = {
    name: plan.name,
    description: plan.description ?? '',
    price: String(plan.price),
  }
  formOpen.value = true
}

function handleDelete(plan: Plan) {
  selectedPlan.value = plan
  deleteOpen.value = true
}

async function handleToggleStatus(plan: Plan, value: boolean) {
  try {
    await $fetch(`${config.public.apiBase}/plans/${plan.id}/active`, {
      method: 'PATCH',
      body: { is_active: value },
    })
    if (plans.value) {
      plans.value = plans.value.map(p =>
        p.id === plan.id ? { ...p, is_active: value } : p
      )
    }
    toast.success(`Paket berhasil di${value ? 'aktifkan' : 'nonaktifkan'}`)
  } catch (e: any) {
    toast.error(e?.data?.message ?? 'Gagal mengubah status')
  }
}

const columns = computed(() => getColumns({ onEdit: handleEdit, onDelete: handleDelete, onToggleStatus: handleToggleStatus }))

// --- CRUD operations ---
async function handleFormSubmit() {
  if (!form.value.name.trim()) {
    toast.error('Nama wajib diisi')
    return
  }
  if (!form.value.price.trim() || isNaN(Number(form.value.price))) {
    toast.error('Harga wajib diisi dan harus berupa angka')
    return
  }

  formLoading.value = true
  try {
    const body = {
      name: form.value.name.trim(),
      description: form.value.description.trim() || null,
      price: Number(form.value.price),
    }

    if (formMode.value === 'create') {
      await $fetch(`${config.public.apiBase}/plans`, {
        method: 'POST',
        body,
      })
      toast.success('Paket berhasil ditambahkan')
    } else {
      await $fetch(`${config.public.apiBase}/plans/${selectedPlan.value!.id}`, {
        method: 'PUT',
        body,
      })
      toast.success('Paket berhasil diperbarui')
    }

    formOpen.value = false
    await refresh()
  } catch (e: any) {
    toast.error(e?.data?.message ?? 'Gagal menyimpan paket')
  } finally {
    formLoading.value = false
  }
}

async function handleConfirmDelete() {
  if (!selectedPlan.value) return

  deleteLoading.value = true
  try {
    await $fetch(`${config.public.apiBase}/plans/${selectedPlan.value.id}`, {
      method: 'DELETE',
    })
    toast.success('Paket berhasil dihapus')
    deleteOpen.value = false
    selectedPlan.value = null
    await refresh()
  } catch (e: any) {
    toast.error(e?.data?.message ?? 'Gagal menghapus paket')
  } finally {
    deleteLoading.value = false
  }
}

// --- Filters ---
function getStatusFilter(table: any) {
  const val = table.getColumn('is_active')?.getFilterValue()
  if (val === true || val === 'true' || val === 1) return 'true'
  if (val === false || val === 'false' || val === 0) return 'false'
  return 'all'
}

function hasActiveFilter(table: any) {
  const search = table.getColumn('name_search')?.getFilterValue()
  const status = table.getColumn('is_active')?.getFilterValue()
  return (search && search !== '') || (status !== '' && status !== undefined && status !== null)
}

function resetFilters(table: any) {
  table.getColumn('name_search')?.setFilterValue('')
  table.getColumn('is_active')?.setFilterValue('')
}

// --- Reset on dialog close ---
watch(formOpen, (val) => {
  if (!val) {
    form.value = { name: '', description: '', price: '' }
    selectedPlan.value = null
  }
})

watch(deleteOpen, (val) => {
  if (!val) selectedPlan.value = null
})
</script>

<template>
  <SidebarProvider :style="{
    '--sidebar-width': 'calc(var(--spacing) * 72)',
    '--header-height': 'calc(var(--spacing) * 12)',
  }">
    <AppSidebar variant="inset" />
    <SidebarInset>
      <SiteHeader />
      <div class="flex flex-1 flex-col">
        <div class="@container/main flex flex-1 flex-col gap-2">
          <div class="flex flex-col gap-4 py-4 md:gap-6 md:py-6">
            <div class="px-4 lg:px-6">
              <div class="flex items-center justify-between">
                <h1 class="text-2xl font-bold">Paket</h1>
                <Button size="sm" @click="openCreateForm">
                  <Plus class="h-4 w-4 mr-1" />
                  Tambah
                </Button>
              </div>
            </div>
            <div class="px-4 lg:px-6">
              <DataTable ref="tableRef" :columns="columns" :data="plans ?? []" :loading="status === 'pending'">
                <template #filters="{ table }">
                  <div class="flex items-center gap-2 py-4">
                    <Input class="max-w-sm" placeholder="Cari nama..."
                      :model-value="(table.getColumn('name_search')?.getFilterValue() as string) ?? ''"
                      @update:model-value="table.getColumn('name_search')?.setFilterValue($event)" />
                    <Select :model-value="getStatusFilter(table)"
                      @update:model-value="table.getColumn('is_active')?.setFilterValue($event === 'all' ? '' : $event)">
                      <SelectTrigger class="hidden h-8 w-auto md:flex">
                        <SelectValue placeholder="Semua Status" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="all">Semua Status</SelectItem>
                        <SelectItem value="true">Aktif</SelectItem>
                        <SelectItem value="false">Nonaktif</SelectItem>
                      </SelectContent>
                    </Select>
                    <Button v-if="hasActiveFilter(table)" variant="ghost" size="sm" class="h-8"
                      @click="resetFilters(table)">
                      <X class="h-4 w-4 mr-1" />
                      Reset
                    </Button>
                    <DropdownMenu>
                      <DropdownMenuTrigger as-child>
                        <Button variant="outline" class="ml-auto md:hidden">
                          Filter
                          <ChevronDown class="ml-2 h-4 w-4" />
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end">
                        <DropdownMenuLabel>Status</DropdownMenuLabel>
                        <div class="px-2 pb-2">
                          <Select :model-value="getStatusFilter(table)"
                            @update:model-value="table.getColumn('is_active')?.setFilterValue($event === 'all' ? '' : $event)">
                            <SelectTrigger class="h-8 w-37.5">
                              <SelectValue placeholder="Semua Status" />
                            </SelectTrigger>
                            <SelectContent>
                              <SelectItem value="all">Semua Status</SelectItem>
                              <SelectItem value="true">Aktif</SelectItem>
                              <SelectItem value="false">Nonaktif</SelectItem>
                            </SelectContent>
                          </Select>
                        </div>
                        <DropdownMenuSeparator />
                        <DropdownMenuItem :disabled="!hasActiveFilter(table)" @click="resetFilters(table)">
                          Reset Filter
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </div>
                </template>
              </DataTable>
            </div>
          </div>
        </div>
      </div>
    </SidebarInset>

    <!-- ==================== FORM DIALOG (CREATE / EDIT) ==================== -->
    <Dialog v-model:open="formOpen">
      <DialogContent class="sm:max-w-[425px]">
        <DialogHeader>
          <DialogTitle>{{ formTitle }}</DialogTitle>
        </DialogHeader>
        <form id="planForm" @submit.prevent="handleFormSubmit">
          <FieldGroup class="gap-4">
            <Field>
              <FieldLabel for="form-name">Nama <span class="text-red-500">*</span></FieldLabel>
              <Input id="form-name" v-model="form.name" placeholder="Masukkan nama" :disabled="formLoading" />
            </Field>
            <Field>
              <FieldLabel for="form-price">Harga <span class="text-red-500">*</span></FieldLabel>
              <PriceDisplay v-model="form.price" placeholder="0" :disabled="formLoading" />
            </Field>
            <Field>
              <FieldLabel for="form-description">Deskripsi</FieldLabel>
              <textarea id="form-description" v-model="form.description" placeholder="Masukkan deskripsi (opsional)"
                :disabled="formLoading" rows="3"
                class="flex w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50" />
            </Field>
          </FieldGroup>
        </form>
        <DialogFooter>
          <DialogClose as-child>
            <Button variant="outline" :disabled="formLoading">Batal</Button>
          </DialogClose>
          <Button type="submit" form="planForm" :disabled="formLoading">
            <Loader2 v-if="formLoading" class="h-4 w-4 mr-1 animate-spin" />
            Simpan
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>

    <!-- ==================== DELETE DIALOG ==================== -->
    <DeleteDialog v-model:open="deleteOpen" title="Hapus Paket" :item-name="selectedPlan?.name" :loading="deleteLoading"
      @confirm="handleConfirmDelete" />
  </SidebarProvider>
</template>
