<template>
    <div class="flex flex-col gap-5 pt-6">
        <!-- Barre d'action -->
        <div class="flex items-center justify-between gap-3">
            <p class="text-sm text-neutral-500">
                <span v-if="reports.length">{{ $t('directory.reports.count', { n: reports.length }, reports.length) }}</span>
            </p>
            <MalioButton
                v-if="canManage"
                icon-name="mdi:plus"
                icon-position="left"
                :label="$t('common.add')"
                @click="openCreate"
            />
        </div>

        <!-- État vide -->
        <div
            v-if="!loading && !reports.length"
            class="flex flex-col items-center gap-2 rounded-lg border border-dashed border-neutral-200 bg-neutral-50 px-6 py-12 text-center"
        >
            <Icon name="mdi:message-text-outline" class="text-4xl text-neutral-300" />
            <p class="font-medium text-neutral-600">{{ $t('directory.reports.empty') }}</p>
            <p class="max-w-sm text-sm text-neutral-400">{{ $t('directory.reports.emptyHint') }}</p>
            <MalioButton
                v-if="canManage"
                variant="tertiary"
                icon-name="mdi:plus"
                icon-position="left"
                button-class="mt-2 w-auto px-4"
                :label="$t('directory.reports.add')"
                @click="openCreate"
            />
        </div>

        <!-- Timeline antéchronologique -->
        <ol v-else class="flex flex-col">
            <li
                v-for="report in sortedReports"
                :key="report.id"
                class="relative flex gap-4 pb-6 last:pb-0"
            >
                <!-- Rail + pastille de type -->
                <div class="flex flex-col items-center">
                    <span
                        class="flex h-9 w-9 shrink-0 items-center justify-center rounded-full"
                        :class="typeStyle(report.type).badge"
                    >
                        <Icon :name="typeStyle(report.type).icon" class="text-lg" />
                    </span>
                    <span class="mt-1 w-px grow bg-neutral-200" aria-hidden="true" />
                </div>

                <!-- Carte -->
                <div class="flex-1 rounded-lg border border-neutral-200 bg-white p-4 shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]">
                    <div class="flex items-start justify-between gap-3">
                        <div class="min-w-0">
                            <div class="flex flex-wrap items-center gap-2">
                                <span
                                    class="rounded-full px-2 py-0.5 text-xs font-medium"
                                    :class="typeStyle(report.type).chip"
                                >
                                    {{ $t(`directory.reports.types.${report.type}`) }}
                                </span>
                                <p class="truncate font-semibold text-neutral-800">{{ report.subject }}</p>
                            </div>
                            <p class="mt-1 text-xs text-neutral-500">
                                <span :title="absoluteDate(report.occurredAt)">{{ relativeDate(report.occurredAt) }}</span>
                                <span v-if="report.author"> · {{ report.author.username }}</span>
                            </p>
                        </div>
                        <div v-if="canManage" class="flex shrink-0 gap-1">
                            <MalioButtonIcon
                                icon="mdi:pencil-outline"
                                variant="ghost"
                                :aria-label="$t('common.edit')"
                                @click="openEdit(report)"
                            />
                            <MalioButtonIcon
                                icon="mdi:delete-outline"
                                variant="ghost"
                                :aria-label="$t('common.delete')"
                                @click="askDelete(report)"
                            />
                        </div>
                    </div>

                    <MalioInputRichText
                        v-if="report.body"
                        :model-value="report.body"
                        :editable="false"
                        :reserve-message-space="false"
                        editor-class="!border-0 !rounded-none !bg-transparent !p-0 text-sm text-neutral-700"
                        class="mt-2"
                    />

                    <!-- Documents joints -->
                    <div
                        v-if="(report.documents?.length ?? 0) || canManage"
                        class="mt-3 border-t border-neutral-100 pt-3"
                    >
                        <p class="mb-2 text-xs font-medium uppercase tracking-wide text-neutral-400">
                            {{ $t('directory.reports.documentsLabel') }}
                        </p>
                        <div class="flex flex-col gap-2">
                            <ReportDocumentList
                                v-if="report.documents?.length"
                                :documents="report.documents"
                                :can-manage="canManage"
                                @delete="(docId) => askDeleteDocument(docId)"
                            />
                            <ReportDocumentUpload
                                v-if="canManage"
                                :report-id="report.id"
                                @uploaded="reload"
                            />
                        </div>
                    </div>
                </div>
            </li>
        </ol>

        <CommercialReportDrawer
            v-model="drawerOpen"
            :report="editing"
            :owner="owner"
            @saved="reload"
        />
        <ConfirmModal
            v-model="confirmOpen"
            :title="$t('directory.reports.confirmDeleteTitle')"
            :message="$t('directory.reports.confirmDeleteMessage')"
            @confirm="confirmDelete"
        />
        <ConfirmModal
            v-model="docConfirmOpen"
            :title="$t('directory.reports.documentDeleteTitle')"
            :message="$t('directory.reports.documentDeleteMessage')"
            @confirm="confirmDeleteDocument"
        />
    </div>
</template>

<script setup lang="ts">
import type { CommercialReport, ReportType } from '~/modules/directory/services/dto/commercial-report'
import { useCommercialReportService } from '~/modules/directory/services/commercial-reports'
import { useReportDocumentService } from '~/modules/directory/services/report-documents'

const props = defineProps<{
    owner: { client?: string, prospect?: string, prestataire?: string }
    canManage: boolean
}>()

const reportService = useCommercialReportService()
const documentService = useReportDocumentService()

const reports = ref<CommercialReport[]>([])
const loading = ref(true)

const drawerOpen = ref(false)
const editing = ref<CommercialReport | null>(null)

const confirmOpen = ref(false)
const pendingDelete = ref<CommercialReport | null>(null)
const deleting = ref(false)

// Suppression d'un document joint : passe désormais par une modal de confirmation.
const docConfirmOpen = ref(false)
const pendingDocId = ref<number | null>(null)
const deletingDoc = ref(false)

// Le plus récent en haut (l'API ne garantit pas l'ordre).
const sortedReports = computed(() =>
    [...reports.value].sort((a, b) => b.occurredAt.localeCompare(a.occurredAt)),
)

const typeStyles: Record<ReportType, { icon: string, badge: string, chip: string }> = {
    call: { icon: 'mdi:phone-outline', badge: 'bg-emerald-100 text-emerald-700', chip: 'bg-emerald-50 text-emerald-700' },
    meeting: { icon: 'mdi:account-group-outline', badge: 'bg-violet-100 text-violet-700', chip: 'bg-violet-50 text-violet-700' },
    email: { icon: 'mdi:email-outline', badge: 'bg-sky-100 text-sky-700', chip: 'bg-sky-50 text-sky-700' },
    note: { icon: 'mdi:note-text-outline', badge: 'bg-amber-100 text-amber-700', chip: 'bg-amber-50 text-amber-700' },
}
function typeStyle(type: ReportType) {
    return typeStyles[type]
}

function startOfDay(d: Date): number {
    return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
}

function absoluteDate(iso: string): string {
    return new Date(iso).toLocaleDateString('fr-FR')
}

// Date relative lisible (« aujourd'hui », « il y a 3 jours »…) avec repli sur la
// date absolue au-delà d'un an. La date exacte reste disponible en infobulle.
function relativeDate(iso: string): string {
    const diffDays = Math.round((startOfDay(new Date(iso)) - startOfDay(new Date())) / 86400000)
    const rtf = new Intl.RelativeTimeFormat('fr-FR', { numeric: 'auto' })
    const abs = Math.abs(diffDays)
    if (abs < 1) return rtf.format(0, 'day')
    if (abs < 7) return rtf.format(diffDays, 'day')
    if (abs < 31) return rtf.format(Math.round(diffDays / 7), 'week')
    if (abs < 365) return rtf.format(Math.round(diffDays / 30), 'month')
    return absoluteDate(iso)
}

function openCreate(): void {
    editing.value = null
    drawerOpen.value = true
}

function openEdit(report: CommercialReport): void {
    editing.value = report
    drawerOpen.value = true
}

function askDelete(report: CommercialReport): void {
    pendingDelete.value = report
    confirmOpen.value = true
}

async function confirmDelete(): Promise<void> {
    if (!pendingDelete.value || deleting.value) return
    deleting.value = true
    try {
        await reportService.remove(pendingDelete.value.id)
        confirmOpen.value = false
        pendingDelete.value = null
        await reload()
    } finally {
        deleting.value = false
    }
}

function askDeleteDocument(id: number): void {
    pendingDocId.value = id
    docConfirmOpen.value = true
}

async function confirmDeleteDocument(): Promise<void> {
    if (pendingDocId.value === null || deletingDoc.value) return
    deletingDoc.value = true
    try {
        await documentService.remove(pendingDocId.value)
        docConfirmOpen.value = false
        pendingDocId.value = null
        await reload()
    } finally {
        deletingDoc.value = false
    }
}

async function reload(): Promise<void> {
    reports.value = await reportService.getByOwner(props.owner)
    loading.value = false
}

onMounted(reload)
watch(() => props.owner, reload, { deep: true })
</script>
