<script setup>
import { computed, ref } from 'vue'
import { NSelect, NButton, NDataTable, NEmpty, NFlex, NText, NTabs, NTabPane, NBadge, NDivider, NGrid, NGi } from 'naive-ui'
import { router, Link } from '@inertiajs/vue3'
import AppLayout from '../../Layouts/AppLayout.vue'
import AppContainer from '../../Components/AppContainer.vue'
import SectionCard from '../../Components/SectionCard.vue'
import PageBanner from '../../Components/PageBanner.vue'
import ActionTile from '../../Components/ActionTile.vue'
import DatePickerQuery from '../../Components/DatePickerQuery.vue'
import { useAuthStore } from '../../Stores/auth.js'
import { TbReportMedical, TbBuildingHospital, TbSettings, TbArrowLeft } from 'vue-icons-plus/tb'
import { TbFileSpreadsheet, TbFileTypePdf } from 'vue-icons-plus/tb'

const authStore = useAuthStore()
const canManageTemplates = computed(() => authStore.isAdmin || authStore.isChiefDoctor || authStore.isDeputyChief)

const props = defineProps({
    reportTypes: { type: Array, default: () => [] },
    departments: { type: Array, default: () => [] },
    selectedType: { type: String, default: null },
    selectedDepartmentId: { type: [Number, String], default: null },
    isHeadOrAdmin: { type: Boolean, default: false },
    date: { type: [Number, Array], default: () => [] },
    payload: { type: Object, default: null },
})

// Локальный выбор отчёта до того, как параметры подтверждены и отчёт сформирован на сервере.
const pendingType = ref(props.selectedType)
const dateModel = ref(props.date)
const departmentModel = ref(props.selectedDepartmentId)
const downloading = ref(null)

// list — выбираем отчёт из каталога; params — задаём период/отделение перед формированием; result — отчёт построен
const stage = computed(() => {
    if (props.payload) return 'result'
    if (pendingType.value) return 'params'
    return 'list'
})

const typeOptions = computed(() => props.reportTypes.map(t => ({ label: t.label, value: t.code })))
const departmentOptions = computed(() => props.departments.map(d => ({ label: d.name, value: d.id })))

const selectReport = (code) => {
    pendingType.value = code
}

const backToList = () => {
    pendingType.value = null
    if (props.payload) {
        router.get('/reports', {}, { preserveState: false })
    }
}

const generate = () => {
    router.get('/reports', {
        type: pendingType.value,
        departmentId: departmentModel.value,
        startAt: dateModel.value?.[0],
        endAt: dateModel.value?.[1],
    })
}

const onTypeChange = (value) => {
    router.reload({ data: { type: value } })
}

const onDepartmentChange = (value) => {
    router.reload({ data: { departmentId: value } })
}

const metaLine = computed(() => Object.values(props.payload?.meta ?? {}).join('  ·  '))

// Раздел с одной строкой коротких значений (показатели смены) удобнее показать
// как карточки KPI, а не как таблицу из одной строки.
const isKpiSection = (section) => {
    if (section.rows.length !== 1) return false
    const row = section.rows[0]
    return Object.keys(section.columns).every((key) => String(row[key] ?? '').length <= 40)
}

const kpiSections = computed(() => props.payload?.sections.filter(isKpiSection) ?? [])
const tableSections = computed(() => props.payload?.sections.filter((s) => !isKpiSection(s)) ?? [])

const kpiCards = computed(() => kpiSections.value.flatMap((section) => {
    const row = section.rows[0]
    return Object.entries(section.columns).map(([key, label]) => ({
        sectionTitle: section.title,
        label,
        value: row[key] ?? '—',
    }))
}))

const sectionColumns = (section) => Object.entries(section.columns ?? {}).map(([key, title]) => ({ key, title }))

const buildExportUrl = (kind) => {
    const params = new URLSearchParams(window.location.search)
    return `/reports/export/${kind}?${params.toString()}`
}

const download = async (kind) => {
    downloading.value = kind
    try {
        const response = await fetch(buildExportUrl(kind), { method: 'GET' })

        if (!response.ok) {
            throw new Error('Ошибка загрузки файла')
        }

        const blob = await response.blob()
        const url = window.URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `${props.payload?.title || 'report'}.${kind === 'excel' ? 'xlsx' : 'pdf'}`
        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(a)
    } catch {
        // silent
    } finally {
        downloading.value = null
    }
}
</script>

<template>
    <AppLayout>
        <AppContainer>

            <PageBanner
                :title="stage === 'result' ? payload.title : 'Отчёты'"
                :icon="TbReportMedical"
                :breadcrumbs="[{ label: 'Главная', href: '/', tag: Link }]"
            >
                <template #meta>
                    <NText v-if="stage === 'result'" depth="3" style="font-size: 13px;">{{ metaLine }}</NText>
                    <NText v-else depth="3" style="font-size: 13px;">Выберите готовый отчёт или шаблон, чтобы сформировать его</NText>
                </template>
                <template #actions>
                    <NButton
                        v-if="canManageTemplates"
                        :tag="Link"
                        href="/admin/report-templates"
                    >
                        <template #icon><TbSettings /></template>
                        Шаблоны отчётов
                    </NButton>
                    <template v-if="stage === 'result'">
                        <NButton
                            :loading="downloading === 'excel'"
                            @click="download('excel')"
                        >
                            <template #icon><TbFileSpreadsheet /></template>
                            Excel
                        </NButton>
                        <NButton
                            type="primary"
                            :loading="downloading === 'pdf'"
                            @click="download('pdf')"
                        >
                            <template #icon><TbFileTypePdf /></template>
                            PDF
                        </NButton>
                    </template>
                </template>
            </PageBanner>

            <!-- Стадия 1: каталог отчётов -->
            <div v-if="stage === 'list'" class="reports-grid">
                <ActionTile
                    v-for="type in reportTypes"
                    :key="type.code"
                    :icon="TbReportMedical"
                    :title="type.label"
                    :description="type.audience"
                    @click="selectReport(type.code)"
                />
            </div>

            <!-- Стадия 2: параметры перед формированием -->
            <SectionCard v-else-if="stage === 'params'" :title="reportTypes.find(t => t.code === pendingType)?.label" :icon="TbReportMedical">
                <NFlex align="center" :size="16" :wrap="true">
                    <NSelect
                        v-if="departmentOptions.length > 1"
                        v-model:value="departmentModel"
                        :options="departmentOptions"
                        style="width: 240px;"
                    >
                        <template #prefix><TbBuildingHospital /></template>
                    </NSelect>
                    <DatePickerQuery v-model:date="dateModel" :is-head-or-admin="isHeadOrAdmin" />
                </NFlex>
                <NFlex :size="8" style="margin-top: 16px;">
                    <NButton @click="backToList">
                        <template #icon><TbArrowLeft /></template>
                        К списку отчётов
                    </NButton>
                    <NButton type="primary" @click="generate">Сформировать отчёт</NButton>
                </NFlex>
            </SectionCard>

            <!-- Стадия 3: результат -->
            <template v-else-if="stage === 'result'">

                <NFlex align="center" :size="12" :wrap="true" class="reports-toolbar">
                    <NButton text @click="backToList">
                        <template #icon><TbArrowLeft /></template>
                        К списку отчётов
                    </NButton>
                    <NDivider vertical style="height: 24px;" />
                    <NSelect
                        v-if="typeOptions.length > 1"
                        :value="selectedType"
                        :options="typeOptions"
                        style="width: 280px;"
                        @update:value="onTypeChange"
                    />
                    <NSelect
                        v-if="departmentOptions.length > 1"
                        :value="selectedDepartmentId"
                        :options="departmentOptions"
                        style="width: 240px;"
                        @update:value="onDepartmentChange"
                    >
                        <template #prefix><TbBuildingHospital /></template>
                    </NSelect>
                    <DatePickerQuery v-model:date="dateModel" :is-head-or-admin="isHeadOrAdmin" />
                </NFlex>

                <!-- KPI-карточки: разделы с единственной строкой коротких значений -->
                <NGrid v-if="kpiCards.length" responsive="screen" cols="2 s:3 m:4 l:6" :x-gap="10" :y-gap="10">
                    <NGi v-for="card in kpiCards" :key="card.sectionTitle + card.label">
                        <SectionCard :title="card.label" no-padding>
                            <div class="kpi-cell">
                                <div class="kpi-value">{{ card.value }}</div>
                            </div>
                        </SectionCard>
                    </NGi>
                </NGrid>

                <!-- Детальные таблицы по разделам отчёта -->
                <SectionCard v-if="tableSections.length === 1" :title="tableSections[0].title" no-padding>
                    <NEmpty v-if="!tableSections[0].rows.length" description="Нет данных за выбранный период" style="padding: 24px;" />
                    <NDataTable
                        v-else
                        :columns="sectionColumns(tableSections[0])"
                        :data="tableSections[0].rows"
                        :bordered="false"
                        size="small"
                    />
                </SectionCard>

                <NTabs v-else-if="tableSections.length > 1" type="line" animated class="reports-tabs">
                    <NTabPane v-for="section in tableSections" :key="section.title" :name="section.title">
                        <template #tab>
                            <NFlex align="center" :size="6">
                                {{ section.title }}
                                <NBadge :value="section.rows.length" :max="999" show-zero type="default" />
                            </NFlex>
                        </template>
                        <NEmpty v-if="!section.rows.length" description="Нет данных за выбранный период" style="padding: 24px;" />
                        <NDataTable
                            v-else
                            :columns="sectionColumns(section)"
                            :data="section.rows"
                            :bordered="false"
                            size="small"
                        />
                    </NTabPane>
                </NTabs>

            </template>

        </AppContainer>
    </AppLayout>
</template>

<style scoped>
.reports-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 10px;
}

.reports-toolbar {
    padding: 10px 4px;
}

.kpi-cell {
    position: relative;
    padding: 12px 16px 14px;
    min-height: 64px;
}

.kpi-value {
    font-size: 24px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.3px;
}

.reports-tabs :deep(.n-tabs-pane-wrapper) {
    padding-top: 4px;
}
</style>
