<template>
    <div>
        <div class="flex items-center justify-between">
            <h2 class="text-lg font-bold text-neutral-900">{{ $t('clientTicket.adminTab') }}</h2>
        </div>

        <!-- Filters -->
        <div class="mt-4 flex flex-wrap gap-3">
            <MalioSelect
                v-model="filterProjectId"
                :options="projectOptions"
                label="Projet"
                :empty-option-label="$t('clientTicket.allProjects')"
                min-width="!w-40"
                text-field="text-sm"
                text-value="text-sm"
            />
            <div>
                <label class="mb-1 block text-sm font-medium text-neutral-700">Statut</label>
                <select
                    v-model="filterStatus"
                    class="rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
                >
                    <option :value="null">{{ $t('clientTicket.allStatuses') }}</option>
                    <option value="new">{{ $t('clientTicket.status.new') }}</option>
                    <option value="in_progress">{{ $t('clientTicket.status.in_progress') }}</option>
                    <option value="done">{{ $t('clientTicket.status.done') }}</option>
                    <option value="rejected">{{ $t('clientTicket.status.rejected') }}</option>
                </select>
            </div>
        </div>

        <!-- Ticket list -->
        <div v-if="isLoading" class="py-8 text-center text-sm text-neutral-400">
            {{ $t('common.loading') }}
        </div>

        <div v-else-if="filteredTickets.length === 0" class="py-8 text-center text-sm text-neutral-400">
            {{ $t('clientTicket.noTickets') }}
        </div>

        <div v-else class="mt-4 overflow-x-auto">
            <table class="w-full text-left text-sm">
                <thead>
                    <tr class="border-b border-neutral-200 text-xs font-semibold uppercase text-neutral-500">
                        <th class="px-3 py-3">#</th>
                        <th class="px-3 py-3">Type</th>
                        <th class="px-3 py-3">{{ $t('clientTicket.title') }}</th>
                        <th class="px-3 py-3">Statut</th>
                        <th class="px-3 py-3">Projet</th>
                        <th class="px-3 py-3">{{ $t('clientTicket.submittedBy') }}</th>
                        <th class="px-3 py-3">{{ $t('clientTicket.createdAt') }}</th>
                        <th class="px-3 py-3">Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <tr
                        v-for="ticket in filteredTickets"
                        :key="ticket.id"
                        class="cursor-pointer border-b border-neutral-100 transition-colors hover:bg-neutral-50"
                        @click="openDetail(ticket)"
                    >
                        <td class="px-3 py-3 font-bold text-primary-500">CT-{{ String(ticket.number).padStart(3, '0') }}</td>
                        <td class="px-3 py-3">
                            <span
                                class="rounded-full px-2 py-0.5 text-xs font-semibold text-white"
                                :class="typeBadgeClass(ticket.type)"
                            >
                                {{ $t(`clientTicket.type.${ticket.type}`) }}
                            </span>
                        </td>
                        <td class="px-3 py-3 font-medium text-neutral-900">{{ ticket.title }}</td>
                        <td class="px-3 py-3">
                            <span
                                class="rounded-full px-2 py-0.5 text-xs font-semibold"
                                :class="statusBadgeClass(ticket.status)"
                            >
                                {{ $t(`clientTicket.status.${ticket.status}`) }}
                            </span>
                        </td>
                        <td class="px-3 py-3 text-neutral-600">{{ getProjectName(ticket.project) }}</td>
                        <td class="px-3 py-3 text-neutral-600">{{ getSubmitterName(ticket.submittedBy) }}</td>
                        <td class="px-3 py-3 text-neutral-400">{{ formatDate(ticket.createdAt) }}</td>
                        <td class="px-3 py-3">
                            <div class="flex items-center gap-2">
                                <button
                                    class="rounded p-1 text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-primary-500"
                                    :title="$t('clientTicket.changeStatus')"
                                    @click.stop="openStatusChange(ticket)"
                                >
                                    <Icon name="mdi:swap-horizontal" size="18" />
                                </button>
                                <button
                                    class="rounded p-1 text-neutral-400 transition-colors hover:bg-red-50 hover:text-red-500"
                                    @click.stop="openDeleteConfirm(ticket)"
                                >
                                    <Icon name="mdi:delete-outline" size="18" />
                                </button>
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

        <!-- Status change modal -->
        <Teleport v-if="statusModalOpen" to="body">
            <Transition name="status-modal" appear>
                <div class="fixed inset-0 z-50 flex items-center justify-center p-4">
                    <div
                        class="absolute inset-0 bg-slate-900/40 backdrop-blur-sm"
                        @click="statusModalOpen = false"
                    />
                    <div class="relative z-10 w-full max-w-md rounded-2xl bg-white p-6 shadow-2xl">
                        <h3 class="text-lg font-bold text-neutral-900">{{ $t('clientTicket.changeStatus') }}</h3>
                        <p v-if="statusTarget" class="mt-1 text-sm text-neutral-500">
                            CT-{{ String(statusTarget.number).padStart(3, '0') }} — {{ statusTarget.title }}
                        </p>

                        <div class="mt-4">
                            <label class="mb-1 block text-sm font-medium text-neutral-700">Nouveau statut</label>
                            <select
                                v-model="newStatus"
                                class="w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
                            >
                                <option :value="null" disabled>—</option>
                                <option
                                    v-for="s in availableStatusTransitions"
                                    :key="s.value"
                                    :value="s.value"
                                >
                                    {{ s.label }}
                                </option>
                            </select>
                        </div>

                        <div v-if="newStatus === 'rejected'" class="mt-4">
                            <MalioInputTextArea
                                v-model="statusComment"
                                :label="$t('clientTicket.statusComment')"
                                :size="3"
                            />
                            <p v-if="rejectionError" class="mt-1 text-xs text-red-500">
                                {{ $t('clientTicket.rejectionRequired') }}
                            </p>
                        </div>

                        <div class="mt-6 flex justify-end gap-3">
                            <button
                                class="rounded-lg border border-neutral-300 px-4 py-2 text-sm font-semibold text-neutral-700 transition-colors hover:bg-neutral-50"
                                @click="statusModalOpen = false"
                            >
                                {{ $t('common.cancel') }}
                            </button>
                            <button
                                class="rounded-lg bg-primary-500 px-6 py-2 text-sm font-semibold text-white transition-colors hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
                                :disabled="isUpdatingStatus"
                                @click="confirmStatusChange"
                            >
                                Confirmer
                            </button>
                        </div>
                    </div>
                </div>
            </Transition>
        </Teleport>

        <!-- Delete confirm modal -->
        <Teleport v-if="deleteModalOpen" to="body">
            <Transition name="status-modal" appear>
                <div class="fixed inset-0 z-50 flex items-center justify-center p-4">
                    <div
                        class="absolute inset-0 bg-slate-900/40 backdrop-blur-sm"
                        @click="deleteModalOpen = false"
                    />
                    <div class="relative z-10 w-full max-w-sm rounded-2xl bg-white p-6 shadow-2xl">
                        <h3 class="text-lg font-bold text-neutral-900">{{ $t('clientTicket.confirmDelete') }}</h3>
                        <p class="mt-2 text-sm text-neutral-600">{{ $t('clientTicket.confirmDeleteMessage') }}</p>
                        <div class="mt-6 flex justify-end gap-3">
                            <button
                                class="rounded-lg border border-neutral-300 px-4 py-2 text-sm font-semibold text-neutral-700 transition-colors hover:bg-neutral-50"
                                @click="deleteModalOpen = false"
                            >
                                {{ $t('common.cancel') }}
                            </button>
                            <button
                                class="rounded-lg bg-red-500 px-6 py-2 text-sm font-semibold text-white transition-colors hover:bg-red-600 disabled:cursor-not-allowed disabled:opacity-50"
                                :disabled="isDeleting"
                                @click="confirmDelete"
                            >
                                Supprimer
                            </button>
                        </div>
                    </div>
                </div>
            </Transition>
        </Teleport>

        <!-- Ticket detail modal (read-only) -->
        <ClientTicketDetailModal
            v-model="detailOpen"
            :ticket="detailTicket"
        />
    </div>
</template>

<script setup lang="ts">
import type { ClientTicket, ClientTicketStatus } from '~/services/dto/client-ticket'
import type { Project } from '~/services/dto/project'
import type { UserData } from '~/services/dto/user-data'
import { useClientTicketService } from '~/services/client-tickets'
import { useProjectService } from '~/services/projects'
import { useUserService } from '~/services/users'

const { t } = useI18n()
const clientTicketService = useClientTicketService()
const projectService = useProjectService()
const userService = useUserService()
const { typeBadgeClass, statusBadgeClass, formatDate } = useClientTicketHelpers()

const tickets = ref<ClientTicket[]>([])
const projects = ref<Project[]>([])
const users = ref<UserData[]>([])
const isLoading = ref(true)

// Filters
const filterProjectId = ref<number | null>(null)
const filterStatus = ref<string | null>(null)

const projectOptions = computed(() =>
    projects.value.map(p => ({ label: p.name, value: p.id }))
)

const filteredTickets = computed(() => {
    let result = tickets.value
    if (filterProjectId.value) {
        result = result.filter(t => t.project === `/api/projects/${filterProjectId.value}`)
    }
    if (filterStatus.value) {
        result = result.filter(t => t.status === filterStatus.value)
    }
    return result
})

// Status change modal
const statusModalOpen = ref(false)
const statusTarget = ref<ClientTicket | null>(null)
const newStatus = ref<string | null>(null)
const statusComment = ref('')
const rejectionError = ref(false)
const isUpdatingStatus = ref(false)

// Delete modal
const deleteModalOpen = ref(false)
const deleteTarget = ref<ClientTicket | null>(null)
const isDeleting = ref(false)

// Detail modal
const detailOpen = ref(false)
const detailTicket = ref<ClientTicket | null>(null)

const availableStatusTransitions = computed(() => {
    if (!statusTarget.value) return []
    const current = statusTarget.value.status
    const allStatuses: { label: string; value: ClientTicketStatus }[] = [
        { label: t('clientTicket.status.new'), value: 'new' },
        { label: t('clientTicket.status.in_progress'), value: 'in_progress' },
        { label: t('clientTicket.status.done'), value: 'done' },
        { label: t('clientTicket.status.rejected'), value: 'rejected' },
    ]
    // Filter out forbidden transitions
    return allStatuses.filter(s => {
        if (s.value === current) return false
        if ((current === 'done' || current === 'rejected') && s.value === 'new') return false
        return true
    })
})

function getProjectName(iri: string): string {
    const match = iri.match(/\/api\/projects\/(\d+)/)
    if (!match) return ''
    const id = Number(match[1])
    return projects.value.find(p => p.id === id)?.name ?? ''
}

function getSubmitterName(iri: string | null): string {
    if (!iri) return '-'
    const match = iri.match(/\/api\/users\/(\d+)/)
    if (!match) return ''
    const id = Number(match[1])
    return users.value.find(u => u.id === id)?.username ?? ''
}

function openDetail(ticket: ClientTicket) {
    detailTicket.value = ticket
    detailOpen.value = true
}

function openStatusChange(ticket: ClientTicket) {
    statusTarget.value = ticket
    newStatus.value = null
    statusComment.value = ''
    rejectionError.value = false
    statusModalOpen.value = true
}

function openDeleteConfirm(ticket: ClientTicket) {
    deleteTarget.value = ticket
    deleteModalOpen.value = true
}

async function confirmStatusChange() {
    if (!statusTarget.value || !newStatus.value) return

    if (newStatus.value === 'rejected' && !statusComment.value.trim()) {
        rejectionError.value = true
        return
    }

    isUpdatingStatus.value = true
    try {
        await clientTicketService.updateStatus(statusTarget.value.id, {
            status: newStatus.value as ClientTicketStatus,
            statusComment: newStatus.value === 'rejected' ? statusComment.value.trim() : null,
        })
        statusModalOpen.value = false
        await loadTickets()
    } finally {
        isUpdatingStatus.value = false
    }
}

async function confirmDelete() {
    if (!deleteTarget.value) return
    isDeleting.value = true
    try {
        await clientTicketService.remove(deleteTarget.value.id)
        deleteModalOpen.value = false
        await loadTickets()
    } finally {
        isDeleting.value = false
    }
}

async function loadTickets() {
    tickets.value = await clientTicketService.getAll()
}

async function loadData() {
    isLoading.value = true
    try {
        const [ticketsResult, projectsResult, usersResult] = await Promise.all([
            clientTicketService.getAll(),
            projectService.getAll(),
            userService.getAll(),
        ])
        tickets.value = ticketsResult
        projects.value = projectsResult
        users.value = usersResult
    } finally {
        isLoading.value = false
    }
}

onMounted(() => {
    loadData()
})
</script>

<style scoped>
.status-modal-enter-active,
.status-modal-leave-active {
    transition: opacity 0.2s ease;
}
.status-modal-enter-from,
.status-modal-leave-to {
    opacity: 0;
}
</style>
