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

        <!-- Filtres -->
        <div class="mt-4 flex flex-wrap gap-3">
            <div class="[&>div]:!mt-0">
                <MalioSelect
                    v-model="filters.project"
                    :options="projectOptions"
                    :label="$t('clientTicket.filterProject')"
                    group-class="!w-48"
                    empty-option-label="—"
                    @update:model-value="load"
                />
            </div>
            <div class="[&>div]:!mt-0">
                <MalioSelect
                    v-model="filters.status"
                    :options="statusOptions"
                    :label="$t('clientTicket.filterStatus')"
                    group-class="!w-48"
                    empty-option-label="—"
                    @update:model-value="load"
                />
            </div>
        </div>

        <DataTable
            class="mt-4"
            :columns="columns"
            :items="tickets"
            :loading="isLoading"
            :empty-message="$t('portal.noTickets')"
            @row-click="openDetail"
        >
            <template #cell-number="{ item }">
                <span class="font-mono font-semibold text-primary-500">
                    {{ formatTicketNumber((item as ClientTicket).number) }}
                </span>
            </template>
            <template #cell-type="{ item }">
                <ClientTicketTypeBadge :type="(item as ClientTicket).type" />
            </template>
            <template #cell-status="{ item }">
                <ClientTicketStatusBadge :status="(item as ClientTicket).status" />
            </template>
            <template #cell-project="{ item }">
                {{ projectName((item as ClientTicket).project) }}
            </template>
            <template #cell-submittedBy="{ item }">
                {{ submitterName((item as ClientTicket).submittedBy) }}
            </template>
            <template #cell-createdAt="{ item }">
                {{ formatDate((item as ClientTicket).createdAt) }}
            </template>
            <template #cell-actions="{ item }">
                <MalioButton
                    :label="$t('clientTicket.changeStatus')"
                    button-class="w-auto px-3 py-1 text-xs"
                    @click.stop="openStatus(item as ClientTicket)"
                />
            </template>
        </DataTable>

        <!-- Detail modal (read-only + documents) -->
        <ClientTicketDetailModal
            v-model="detailOpen"
            :ticket="selectedTicket"
        />

        <!-- Status change modal -->
        <AppModal v-model="statusOpen" :title="$t('clientTicket.changeStatus')" width="md">
            <div v-if="statusTicket" class="flex flex-col gap-4">
                <p class="text-sm text-neutral-500">
                    {{ formatTicketNumber(statusTicket.number) }} — {{ statusTicket.title }}
                </p>
                <MalioSelect
                    v-model="statusForm.status"
                    :options="statusEditOptions"
                    :label="$t('clientTicket.status.label')"
                    group-class="w-full"
                />
                <MalioInputTextArea
                    v-model="statusForm.statusComment"
                    :label="$t('clientTicket.statusComment')"
                    :rows="3"
                    input-class="w-full"
                    :error="statusError"
                />
            </div>
            <template #footer>
                <MalioButton
                    :label="$t('common.cancel')"
                    button-class="w-auto px-4"
                    variant="secondary"
                    @click="statusOpen = false"
                />
                <MalioButton
                    :label="$t('common.save')"
                    button-class="w-auto px-6"
                    :disabled="isSavingStatus"
                    @click="saveStatus"
                />
            </template>
        </AppModal>
    </div>
</template>

<script setup lang="ts">
import type {
    ClientTicket,
    ClientTicketStatus,
} from '~/modules/client-portal/services/dto/client-ticket'
import type { Project } from '~/modules/project-management/services/dto/project'
import type { UserData } from '~/services/dto/user-data'
import { useClientTicketService } from '~/modules/client-portal/services/client-tickets'
import { useProjectService } from '~/modules/project-management/services/projects'
import { useUserService } from '~/services/users'
import { formatTicketNumber, iriToId } from '~/modules/client-portal/utils/ticket'
import type { DataTableColumn } from '~/components/ui/DataTable.vue'

const { t } = useI18n()
const { getAll, getById, updateStatus } = useClientTicketService()
const { getAll: getProjects } = useProjectService()
const { getAll: getUsers } = useUserService()

const columns: DataTableColumn[] = [
    { key: 'number', label: 'N°', primary: true },
    { key: 'type', label: t('clientTicket.typeLabel') },
    { key: 'title', label: t('clientTicket.title') },
    { key: 'status', label: t('clientTicket.status.label') },
    { key: 'project', label: t('clientTicket.project') },
    { key: 'submittedBy', label: t('clientTicket.submittedBy') },
    { key: 'createdAt', label: t('clientTicket.date') },
    { key: 'actions', label: '' },
]

const STATUSES: ClientTicketStatus[] = ['new', 'in_progress', 'done', 'rejected']

const statusOptions = computed(() =>
    STATUSES.map((s) => ({ label: t(`clientTicket.status.${s}`), value: s })),
)
const statusEditOptions = statusOptions

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

const filters = reactive({
    project: null as string | null,
    status: null as string | null,
})

const projectOptions = computed(() =>
    projects.value.map((p) => ({
        label: p.name,
        value: p['@id'] ?? `/api/projects/${p.id}`,
    })),
)

function projectName(iri: string): string {
    const id = iriToId(iri)
    return projects.value.find((p) => p.id === id)?.name ?? '—'
}

function submitterName(iri: string | null): string {
    if (!iri) return '—'
    const id = iriToId(iri)
    return users.value.find((u) => u.id === id)?.username ?? '—'
}

function formatDate(value: string): string {
    return new Date(value).toLocaleDateString('fr-FR', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
    })
}

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

async function openDetail(ticket: ClientTicket) {
    try {
        selectedTicket.value = await getById(ticket.id)
    } catch {
        selectedTicket.value = ticket
    }
    detailOpen.value = true
}

// Status modal
const statusOpen = ref(false)
const statusTicket = ref<ClientTicket | null>(null)
const isSavingStatus = ref(false)
const statusForm = reactive({
    status: 'new' as ClientTicketStatus,
    statusComment: '',
})

const statusError = computed(() => {
    if (statusForm.status === 'rejected' && !statusForm.statusComment.trim()) {
        return t('clientTicket.rejectionRequired')
    }
    return ''
})

function openStatus(ticket: ClientTicket) {
    statusTicket.value = ticket
    statusForm.status = ticket.status
    statusForm.statusComment = ticket.statusComment ?? ''
    statusOpen.value = true
}

async function saveStatus() {
    if (!statusTicket.value) return
    if (statusForm.status === 'rejected' && !statusForm.statusComment.trim()) {
        return
    }
    isSavingStatus.value = true
    try {
        await updateStatus(statusTicket.value.id, {
            status: statusForm.status,
            statusComment: statusForm.statusComment.trim() || null,
        })
        statusOpen.value = false
        await load()
    } finally {
        isSavingStatus.value = false
    }
}

async function load() {
    isLoading.value = true
    try {
        tickets.value = await getAll({
            project: filters.project ?? undefined,
            status: filters.status ?? undefined,
        })
    } finally {
        isLoading.value = false
    }
}

onMounted(async () => {
    const [proj, usr] = await Promise.all([getProjects(), getUsers()])
    projects.value = proj
    users.value = usr
    await load()
})
</script>
