<script lang="ts" setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { Box } from '@/components/ui/box'
import {
    PaginationContext,
    PaginationRoot,
    PaginationItem,
    PaginationPrevTrigger,
    PaginationNextTrigger,
    PaginationEllipsis,
} from '@/components/ui/pagination'
import { DialogRoot, DialogContent, DialogCloseTrigger } from '@/components/ui/dialog'
import { Lucide } from '@/components/ui/lucide'
import { AlertRoot, AlertTitle, AlertDescription } from '@/components/ui/alert'
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
import { useRoleList } from '../composables/useRoleList'
import { deleteRole as deleteRoleService } from '../services/role.service'

const deleteConfirmationOpen = ref(false)
const roleToDelete = ref<string | null>(null)
const deleting = ref(false)
const deleteError = ref<string | null>(null)
const router = useRouter()

const { roles, loading, error, search, page, pagination, fetchRoles } = useRoleList()

function handlePageChange(details: { page: number }) {
    page.value = details.page
}

function contextBadgeVariant(context: string) {
    if (context === 'admin') return 'success'
    if (context === 'member') return 'pending'
    return 'danger'
}

function goToCreateRole() {
    router.push({ name: 'create-role' })
}

function goToEditRole(roleId: string) {
    router.push({ name: 'edit-role', params: { id: roleId } })
}

function openDeleteConfirmation(roleId: string) {
    roleToDelete.value = roleId
    deleteError.value = null
    deleteConfirmationOpen.value = true
}

async function confirmDelete() {
    if (!roleToDelete.value || deleting.value) {
        return
    }

    deleting.value = true
    deleteError.value = null

    try {
        await deleteRoleService(roleToDelete.value)
        deleteConfirmationOpen.value = false
        roleToDelete.value = null
        await fetchRoles()
    } catch (err) {
        deleteError.value = getApiErrorMessage(err, 'Gagal menghapus peranan.')
    } finally {
        deleting.value = false
    }
}
</script>

<template>
    <div>
        <h2 class="text-lg font-medium">Senarai Peranan</h2>

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

        <div class="mt-5 grid grid-cols-12 gap-x-6 gap-y-8">
            <div class="col-span-12 mt-2 flex flex-wrap items-center sm:flex-nowrap">
                <!-- Search -->
                <div class="w-full sm:w-auto">
                    <div class="relative w-56">
                        <Input v-model="search" class="w-56 pr-10" type="search" placeholder="Cari peranan..." />
                        <Lucide class="absolute inset-y-0 right-0 my-auto mr-3 h-4 w-4" icon="Search" />
                    </div>
                </div>

                <!-- Add Button -->
                <Button class="mt-3 sm:mt-0 sm:ml-auto" look="outline" variant="primary" :disabled="loading"
                    @click="goToCreateRole">
                    Tambah Peranan
                </Button>
            </div>
            <!-- BEGIN: Data List -->
            <div v-for="role in roles" :key="role.id" class="col-span-12 md:col-span-6 lg:col-span-4 xl:col-span-3">
                <Box class="p-0">
                    <div class="p-5">
                        <div class="rounded-lg border border-foreground/10 bg-foreground/2 p-4">
                            <div class="flex items-start justify-between gap-3">
                                <div class="min-w-0">
                                    <div class="truncate text-base font-medium">
                                        {{ role.name }}
                                    </div>
                                    <div class="mt-1 truncate text-xs opacity-70">
                                        {{ role.fullname || '-' }}
                                    </div>
                                </div>
                                <Badge class="shrink-0" look="outline" :variant="contextBadgeVariant(role.context)">
                                    {{ role.context }}
                                </Badge>
                            </div>
                        </div>
                        <div class="mt-5 opacity-70">
                            <div class="flex items-center">
                                <Lucide class="mr-2 h-4 w-4" icon="Shield" />
                                Guard: {{ role.guard_name }}
                            </div>
                            <div class="mt-2 flex items-center">
                                <Lucide class="mr-2 h-4 w-4" icon="KeyRound" />
                                Permissions: {{ role.permissions?.length ?? 0 }}
                            </div>
                        </div>
                    </div>
                    <div class="flex items-center justify-center border-t border-foreground/8 p-5 lg:justify-end">
                        <a class="mr-3 flex items-center" href="#" @click.prevent="goToEditRole(role.id)">
                            <Lucide class="mr-1 h-4 w-4" icon="CheckSquare" /> Edit
                        </a>
                        <a class="text-danger flex items-center" href="#"
                            @click.prevent="openDeleteConfirmation(role.id)">
                            <Lucide class="mr-1 h-4 w-4" icon="Trash" /> Delete
                        </a>
                    </div>
                </Box>
            </div>
            <!-- END: Data List -->
            <div v-if="!loading && !roles.length" class="col-span-12">
                <Box class="p-6 text-center opacity-70">Tiada rekod ditemui</Box>
            </div>
            <!-- BEGIN: Pagination -->
            <div class="col-span-12 flex flex-wrap items-center sm:flex-row sm:flex-nowrap">
                <PaginationRoot :count="pagination.total" :page="page" :siblingCount="1"
                    :onPageChange="handlePageChange" class="w-full sm:mr-auto sm:w-auto">
                    <PaginationPrevTrigger>Previous</PaginationPrevTrigger>
                    <PaginationContext v-slot="{ pagination }">
                        <template v-for="(page, index) in pagination?.pages" :key="index">
                            <PaginationItem v-if="page.type === 'page'" v-bind="{ ...page }">
                                {{ page.value }}
                            </PaginationItem>
                            <PaginationEllipsis v-else :index="index" />
                        </template>
                    </PaginationContext>
                    <PaginationNextTrigger>Next</PaginationNextTrigger>
                </PaginationRoot>
            </div>
            <!-- END: Pagination -->
        </div>
        <!-- BEGIN: Delete Confirmation Modal -->
        <DialogRoot :open="deleteConfirmationOpen" @openChange="(details) => (deleteConfirmationOpen = details.open)">
            <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">Adakah anda yakin?</div>
                    <div class="mt-2 opacity-70">
                        Adakah anda benar-benar mahu menghapus rekod 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="deleting"> Cancel </DialogCloseTrigger>
                    <Button
                        class="w-24"
                        type="button"
                        variant="danger"
                        look="outline"
                        :disabled="deleting"
                        @click="confirmDelete"
                    >
                        {{ deleting ? 'Menghapus...' : 'Hapus' }}
                    </Button>
                </div>
            </DialogContent>
        </DialogRoot>
        <!-- END: Delete Confirmation Modal -->
    </div>
</template>
