<template>
    <div>
        <div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
            <h1 class="text-xl font-bold text-primary-500 sm:text-2xl">
                {{ $t('reporting.title') }}
            </h1>

            <!-- Filters -->
            <div class="mt-4 flex flex-wrap items-end gap-3">
                <MalioSelect
                    v-model="selectedPeriod"
                    :options="periodOptions"
                    :label="$t('reporting.filters.period')"
                    group-class="!w-48"
                    text-field="text-sm"
                    text-value="text-sm"
                />
                <div class="w-40">
                    <label class="mb-1 block text-sm font-medium text-neutral-700">
                        {{ $t('reporting.filters.from') }}
                    </label>
                    <MalioDate
                        v-model="customFrom"
                        :disabled="selectedPeriod !== 'custom'"
                        group-class="w-full"
                    />
                </div>
                <div class="w-40">
                    <label class="mb-1 block text-sm font-medium text-neutral-700">
                        {{ $t('reporting.filters.to') }}
                    </label>
                    <MalioDate
                        v-model="customTo"
                        :disabled="selectedPeriod !== 'custom'"
                        group-class="w-full"
                    />
                </div>
                <MalioSelect
                    v-model="selectedProjectId"
                    :options="projectOptions"
                    :label="$t('reporting.filters.project')"
                    :empty-option-label="$t('reporting.filters.allProjects')"
                    group-class="!w-44"
                    text-field="text-sm"
                    text-value="text-sm"
                />
                <MalioSelect
                    v-model="selectedUserId"
                    :options="userOptions"
                    :label="$t('reporting.filters.user')"
                    :empty-option-label="$t('reporting.filters.allUsers')"
                    group-class="!w-44"
                    text-field="text-sm"
                    text-value="text-sm"
                />
            </div>
        </div>

        <!-- Loading -->
        <div v-if="isLoading" class="mt-12 flex items-center justify-center">
            <p class="text-neutral-400">{{ $t('common.loading') }}</p>
        </div>

        <template v-else>
            <!-- Section 1 : Time per project -->
            <section class="mt-8 rounded-xl border border-neutral-100 bg-neutral-50 p-5">
                <div class="flex items-center justify-between">
                    <h2 class="text-sm font-semibold text-neutral-700">
                        {{ $t('reporting.sections.timePerProject') }}
                    </h2>
                    <MalioButton
                        icon-name="mdi:download"
                        icon-position="left"
                        button-class="w-auto px-3 py-1.5 text-sm"
                        :label="$t('reporting.export')"
                        :disabled="timePerProject.length === 0"
                        @click="exportTimePerProject"
                    />
                </div>
                <div class="mt-4 grid gap-6 lg:grid-cols-2">
                    <DataTable
                        :columns="projectColumns"
                        :items="timePerProject"
                        :empty-message="$t('reporting.empty')"
                    >
                        <template #cell-hours="{ item }">
                            {{ formatHours((item as TimePerProject).hours) }}
                        </template>
                    </DataTable>
                    <ReportingDoughnut
                        :labels="timePerProject.map(r => r.projectName)"
                        :values="timePerProject.map(r => round(r.hours))"
                    />
                </div>
            </section>

            <!-- Section 2 : Time per user -->
            <section class="mt-6 rounded-xl border border-neutral-100 bg-neutral-50 p-5">
                <div class="flex items-center justify-between">
                    <h2 class="text-sm font-semibold text-neutral-700">
                        {{ $t('reporting.sections.timePerUser') }}
                    </h2>
                    <MalioButton
                        icon-name="mdi:download"
                        icon-position="left"
                        button-class="w-auto px-3 py-1.5 text-sm"
                        :label="$t('reporting.export')"
                        :disabled="timePerUser.length === 0"
                        @click="exportTimePerUser"
                    />
                </div>
                <div class="mt-4 grid gap-6 lg:grid-cols-2">
                    <DataTable
                        :columns="userColumns"
                        :items="timePerUser"
                        :empty-message="$t('reporting.empty')"
                    >
                        <template #cell-hours="{ item }">
                            {{ formatHours((item as TimePerUser).hours) }}
                        </template>
                    </DataTable>
                    <ReportingBarChart
                        :labels="timePerUser.map(r => r.fullName || r.username)"
                        :values="timePerUser.map(r => round(r.hours))"
                        color="#10b981"
                    />
                </div>
            </section>

            <!-- Section 3 : Tasks by status -->
            <section class="mt-6 rounded-xl border border-neutral-100 bg-neutral-50 p-5">
                <div class="flex items-center justify-between">
                    <h2 class="text-sm font-semibold text-neutral-700">
                        {{ $t('reporting.sections.tasksByStatus') }}
                    </h2>
                    <MalioButton
                        icon-name="mdi:download"
                        icon-position="left"
                        button-class="w-auto px-3 py-1.5 text-sm"
                        :label="$t('reporting.export')"
                        :disabled="tasksByStatus.length === 0"
                        @click="exportTasksByStatus"
                    />
                </div>
                <div class="mt-4 grid gap-6 lg:grid-cols-2">
                    <DataTable
                        :columns="statusColumns"
                        :items="tasksByStatus"
                        :empty-message="$t('reporting.empty')"
                    />
                    <ReportingDoughnut
                        :labels="tasksByStatus.map(r => r.statusLabel)"
                        :values="tasksByStatus.map(r => r.count)"
                    />
                </div>
            </section>

            <!-- Section 4 : Absences by type -->
            <section class="mt-6 rounded-xl border border-neutral-100 bg-neutral-50 p-5">
                <div class="flex items-center justify-between">
                    <h2 class="text-sm font-semibold text-neutral-700">
                        {{ $t('reporting.sections.absencesByType') }}
                    </h2>
                    <MalioButton
                        icon-name="mdi:download"
                        icon-position="left"
                        button-class="w-auto px-3 py-1.5 text-sm"
                        :label="$t('reporting.export')"
                        :disabled="absencesByType.length === 0"
                        @click="exportAbsencesByType"
                    />
                </div>
                <div class="mt-4 grid gap-6 lg:grid-cols-2">
                    <DataTable
                        :columns="absenceColumns"
                        :items="absenceRows"
                        :empty-message="$t('reporting.empty')"
                    />
                    <ReportingBarChart
                        :labels="absencesByType.map(r => absenceTypeLabel(r.type))"
                        :values="absencesByType.map(r => r.totalDays)"
                        color="#f59e0b"
                    />
                </div>
            </section>
        </template>
    </div>
</template>

<script setup lang="ts">
import type { DataTableColumn } from '~/components/ui/DataTable.vue'
import type {
    AbsencesByType,
    ReportFilters,
    TasksByStatus,
    TimePerProject,
    TimePerUser,
} from '~/modules/reporting/services/dto/reporting'
import { useReportingService } from '~/modules/reporting/services/reporting'
import {
    useReportingFilters,
    type ReportPeriodKey,
} from '~/modules/reporting/composables/useReportingFilters'
import { useCsvExport } from '~/modules/reporting/composables/useCsvExport'
import type { Project } from '~/modules/project-management/services/dto/project'
import type { UserData } from '~/services/dto/user-data'
import { useProjectService } from '~/modules/project-management/services/projects'
import { useUserService } from '~/services/users'

definePageMeta({ middleware: ['admin'] })

const { t } = useI18n()
useHead({ title: t('reporting.title') })

const reportingService = useReportingService()
const projectService = useProjectService()
const userService = useUserService()
const { rangeForPreset, thisMonth } = useReportingFilters()
const { downloadCsv } = useCsvExport()

// --- Filters state ---
const selectedPeriod = ref<ReportPeriodKey>('thisMonth')
const initialRange = thisMonth()
const customFrom = ref<string | null>(initialRange.from)
const customTo = ref<string | null>(initialRange.to)
const selectedProjectId = ref<number | null>(null)
const selectedUserId = ref<number | null>(null)

const periodOptions = computed(() => [
    { label: t('reporting.periods.thisMonth'), value: 'thisMonth' },
    { label: t('reporting.periods.lastMonth'), value: 'lastMonth' },
    { label: t('reporting.periods.custom'), value: 'custom' },
])

const projects = ref<Project[]>([])
const users = ref<UserData[]>([])

const projectOptions = computed(() =>
    projects.value.map(p => ({ label: p.name, value: p.id })),
)
const userOptions = computed(() =>
    users.value.map(u => ({
        label: [u.firstName, u.lastName].filter(Boolean).join(' ') || u.username,
        value: u.id,
    })),
)

// --- Effective range (preset → concrete dates) ---
const activeFilters = computed<ReportFilters>(() => ({
    from: customFrom.value ?? initialRange.from,
    to: customTo.value ?? initialRange.to,
    projectId: selectedProjectId.value,
    userId: selectedUserId.value,
}))

// When a non-custom preset is picked, sync the date pickers.
watch(selectedPeriod, (key) => {
    if (key !== 'custom') {
        const range = rangeForPreset(key, {
            from: customFrom.value ?? initialRange.from,
            to: customTo.value ?? initialRange.to,
        })
        customFrom.value = range.from
        customTo.value = range.to
    }
})

// --- Report data ---
const timePerProject = ref<TimePerProject[]>([])
const timePerUser = ref<TimePerUser[]>([])
const tasksByStatus = ref<TasksByStatus[]>([])
const absencesByType = ref<AbsencesByType[]>([])
const isLoading = ref(true)

const absenceRows = computed(() =>
    absencesByType.value.map(r => ({ ...r, typeLabel: absenceTypeLabel(r.type) })),
)

// --- Columns ---
const projectColumns: DataTableColumn[] = [
    { key: 'projectName', label: t('reporting.columns.project'), primary: true },
    { key: 'hours', label: t('reporting.columns.hours') },
    { key: 'entryCount', label: t('reporting.columns.entries') },
]
const userColumns: DataTableColumn[] = [
    { key: 'fullName', label: t('reporting.columns.user'), primary: true },
    { key: 'hours', label: t('reporting.columns.hours') },
    { key: 'entryCount', label: t('reporting.columns.entries') },
]
const statusColumns: DataTableColumn[] = [
    { key: 'statusLabel', label: t('reporting.columns.status'), primary: true },
    { key: 'count', label: t('reporting.columns.count') },
]
const absenceColumns: DataTableColumn[] = [
    { key: 'typeLabel', label: t('reporting.columns.type'), primary: true },
    { key: 'count', label: t('reporting.columns.count') },
    { key: 'totalDays', label: t('reporting.columns.days') },
]

// --- Helpers ---
function round(value: number): number {
    return Math.round(value * 100) / 100
}

function formatHours(h: number): string {
    const hours = Math.floor(h)
    const mins = Math.round((h - hours) * 60)
    return mins > 0 ? `${hours}h${String(mins).padStart(2, '0')}` : `${hours}h`
}

function absenceTypeLabel(type: string): string {
    const key = `reporting.absenceTypes.${type}`
    const label = t(key)
    return label === key ? type : label
}

// --- Loading ---
async function loadReferenceData() {
    const [proj, usr] = await Promise.all([
        projectService.getAll(),
        userService.getAll(),
    ])
    projects.value = proj
    users.value = usr
}

async function loadReports() {
    isLoading.value = true
    try {
        const filters = activeFilters.value
        const [tpp, tpu, tbs, abt] = await Promise.all([
            reportingService.timePerProject(filters),
            reportingService.timePerUser(filters),
            reportingService.tasksByStatus(filters),
            reportingService.absencesByType(filters),
        ])
        timePerProject.value = tpp
        timePerUser.value = tpu
        tasksByStatus.value = tbs
        absencesByType.value = abt
    } finally {
        isLoading.value = false
    }
}

// Reload reports whenever the effective filters change.
watch(activeFilters, () => {
    loadReports()
}, { deep: true })

onMounted(async () => {
    await loadReferenceData()
    await loadReports()
})

// --- CSV export ---
function exportTimePerProject() {
    downloadCsv('rapport-temps-par-projet', timePerProject.value, [
        { header: t('reporting.columns.project'), value: r => r.projectName },
        { header: t('reporting.columns.code'), value: r => r.projectCode },
        { header: t('reporting.columns.hours'), value: r => round(r.hours) },
        { header: t('reporting.columns.entries'), value: r => r.entryCount },
    ])
}

function exportTimePerUser() {
    downloadCsv('rapport-temps-par-utilisateur', timePerUser.value, [
        { header: t('reporting.columns.user'), value: r => r.fullName || r.username },
        { header: t('reporting.columns.hours'), value: r => round(r.hours) },
        { header: t('reporting.columns.entries'), value: r => r.entryCount },
    ])
}

function exportTasksByStatus() {
    downloadCsv('rapport-taches-par-statut', tasksByStatus.value, [
        { header: t('reporting.columns.status'), value: r => r.statusLabel },
        { header: t('reporting.columns.count'), value: r => r.count },
    ])
}

function exportAbsencesByType() {
    downloadCsv('rapport-absences-par-type', absencesByType.value, [
        { header: t('reporting.columns.type'), value: r => absenceTypeLabel(r.type) },
        { header: t('reporting.columns.count'), value: r => r.count },
        { header: t('reporting.columns.days'), value: r => r.totalDays },
    ])
}
</script>
