<script setup lang="ts">
import { Form, Head, Link } from '@inertiajs/vue3';
import { ref, watch } from 'vue';
import MedicalReportController from '@/actions/App/Http/Controllers/MedicalReportController';
import Heading from '@/components/Heading.vue';
import InputError from '@/components/InputError.vue';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import type {
    MedicalReport,
    MedicalReportBuilderDepartment,
    MedicalReportBuilderSection,
    MedicalReportBuilderTemplate,
    MedicalReportStructuredEntry,
} from '@/types';

type Props = {
    report: MedicalReport;
    selectedDepartment?: string | null;
    departments: MedicalReportBuilderDepartment[];
    builder?: {
        department: {
            key: string;
            name: string;
            profile_name?: string | null;
            report_input_type?: string | null;
            report_input_type_label?: string | null;
            sources?: Array<{
                name: string;
                path: string;
                extension: string;
            }>;
        };
        template: MedicalReportBuilderTemplate;
        uses_database_template: boolean;
        starter_source: string;
    } | null;
};

const props = defineProps<Props>();

const template = ref<MedicalReportBuilderTemplate | null>(null);

watch(
    () => props.builder?.template,
    (value) => {
        template.value = value
            ? JSON.parse(JSON.stringify(value))
            : null;
    },
    { immediate: true },
);

const addSection = (): void => {
    if (!template.value) {
        return;
    }

    template.value.schema.sections.push({
        key: `section_${template.value.schema.sections.length + 1}`,
        title: `Секция ${template.value.schema.sections.length + 1}`,
        economist_label: `${template.value.name} / Секция ${template.value.schema.sections.length + 1}`,
        fields: [
            { key: 'name', label: 'Показатель', type: 'text' },
            { key: 'value', label: 'Значение', type: 'number' },
        ],
        export_metrics: [{ key: 'value_total', label: 'Значение', source_field: 'value', aggregation: 'sum' }],
        default_entries: [{ name: '', value: '0' }],
    });
};

const removeSection = (index: number): void => {
    template.value?.schema.sections.splice(index, 1);
};

const addField = (section: MedicalReportBuilderSection): void => {
    const key = `field_${section.fields.length + 1}`;
    section.fields.push({
        key,
        label: `Поле ${section.fields.length + 1}`,
        type: 'text',
    });
    section.default_entries = section.default_entries.map((entry) => ({
        ...entry,
        [key]: '',
    }));
};

const removeField = (section: MedicalReportBuilderSection, fieldIndex: number): void => {
    const [field] = section.fields.splice(fieldIndex, 1);

    if (!field) {
        return;
    }

    section.default_entries = section.default_entries.map((entry) => {
        const nextEntry = { ...entry };
        delete nextEntry[field.key];

        return nextEntry;
    });
    section.export_metrics = section.export_metrics.filter((metric) => metric.source_field !== field.key);
};

const addDefaultEntry = (section: MedicalReportBuilderSection): void => {
    const entry = section.fields.reduce(
        (carry, field) => {
            carry[field.key] = field.type === 'number' ? '0' : '';

            return carry;
        },
        {} as MedicalReportStructuredEntry,
    );

    section.default_entries.push(entry);
};

const removeDefaultEntry = (section: MedicalReportBuilderSection, index: number): void => {
    section.default_entries.splice(index, 1);
};

const addExportMetric = (section: MedicalReportBuilderSection): void => {
    const numericField = section.fields.find((field) => field.type === 'number');
    const hasDepartmentSelect = section.fields.some((field) => field.type === 'department-select');

    section.export_metrics.push({
        key: `metric_${section.export_metrics.length + 1}`,
        label: `Метрика ${section.export_metrics.length + 1}`,
        source_field: numericField?.key ?? '',
        aggregation: 'sum',
        analysis_column: '',
        row_mode: hasDepartmentSelect ? 'entry_department' : 'fixed_unit',
        target_unit_slug: '',
    });
};

const removeExportMetric = (section: MedicalReportBuilderSection, index: number): void => {
    section.export_metrics.splice(index, 1);
};

const numericFields = (section: MedicalReportBuilderSection) => {
    return section.fields.filter((field) => field.type === 'number');
};
</script>

<template>
    <Head :title="`${report.name} - Конструктор форм`" />

    <div class="flex flex-col gap-6 p-4 md:p-6">
        <section class="rounded-3xl border border-slate-200 bg-linear-to-br from-white via-slate-50 to-sky-50 p-6 shadow-sm">
            <div class="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
                <div class="space-y-3">
                    <div class="inline-flex w-fit rounded-full bg-sky-100 px-3 py-1 text-xs font-semibold tracking-[0.18em] text-sky-700 uppercase">
                        Конструктор форм
                    </div>
                    <Heading
                        title="Уникальные шаблоны отчетов отделений"
                        description="Здесь настраивается структура формы: секции, поля и строки по умолчанию. Именно эта схема будет использоваться отделением при вводе отчета."
                    />
                </div>

                <div class="flex flex-wrap gap-2">
                    <Link
                        :href="MedicalReportController.show({ medicalReport: report.id })"
                        class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
                    >
                        Ввод отделений
                    </Link>
                    <Link
                        :href="MedicalReportController.economists({ medicalReport: report.id })"
                        class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
                    >
                        Свод экономистов
                    </Link>
                    <div class="rounded-full border border-slate-950 bg-slate-950 px-4 py-2 text-sm text-white">
                        Конструктор
                    </div>
                </div>
            </div>
        </section>

        <section class="grid gap-6 xl:grid-cols-[320px_1fr]">
            <aside class="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="mb-4 text-sm font-semibold text-slate-900">
                    Отделения
                </div>

                <div class="space-y-2">
                    <Link
                        v-for="department in departments"
                        :key="department.key"
                        :href="
                            MedicalReportController.builder(
                                { medicalReport: report.id },
                                { query: { department: department.key } },
                            )
                        "
                        class="block rounded-2xl border px-4 py-3 transition-colors"
                        :class="
                            selectedDepartment === department.key
                                ? 'border-sky-300 bg-sky-50 text-sky-900'
                                : 'border-slate-200 bg-slate-50 text-slate-700 hover:border-slate-300 hover:bg-white'
                        "
                    >
                        <div class="text-[11px] uppercase tracking-[0.16em] text-slate-400">
                            {{ department.profile_name ?? 'Без профиля' }}
                        </div>
                        <div class="font-medium">{{ department.name }}</div>
                        <div class="mt-1 text-xs text-slate-500">
                            {{ department.report_input_type_label ?? 'Тип ввода не задан' }}
                        </div>
                        <div class="mt-1 text-xs">
                            <span :class="department.has_builder_template ? 'text-sky-600' : 'text-amber-600'">
                                {{ department.has_builder_template ? 'Настроено в конструкторе' : 'Используется автосхема' }}
                            </span>
                        </div>
                    </Link>
                </div>
            </aside>

            <div class="rounded-3xl border border-slate-200 bg-white p-5 shadow-sm">
                <div v-if="!builder || !template" class="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">
                    Отделение не выбрано.
                </div>

                <Form
                    v-else
                    v-bind="MedicalReportController.upsertBuilder.form({ medicalReport: report.id })"
                    class="space-y-6"
                    v-slot="{ errors, processing, recentlySuccessful }"
                >
                    <input type="hidden" name="department" :value="builder.department.key" />

                    <div class="flex flex-col gap-4 border-b border-slate-100 pb-5 md:flex-row md:items-start md:justify-between">
                        <div>
                            <div class="text-xs uppercase tracking-[0.16em] text-slate-500">
                                Отделение
                            </div>
                            <h1 class="mt-2 text-2xl font-semibold text-slate-950">
                                {{ builder.department.name }}
                            </h1>
                            <p class="mt-1 text-sm text-slate-500">
                                {{
                                    builder.uses_database_template
                                        ? 'Форма уже сохраняется из конструктора.'
                                        : builder.starter_source === 'blueprint'
                                          ? 'Сейчас показан стартовый шаблон по типу ввода этого подразделения.'
                                          : 'Сейчас показан стартовый шаблон, собранный из существующей схемы.'
                                }}
                            </p>
                        </div>

                        <div class="flex flex-wrap gap-2">
                            <div class="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600">
                                Источников: {{ builder.department.sources?.length ?? 0 }}
                            </div>
                            <div
                                v-if="builder.department.report_input_type_label"
                                class="rounded-2xl border border-sky-200 bg-sky-50 px-4 py-3 text-sm text-sky-700"
                            >
                                {{ builder.department.report_input_type_label }}
                            </div>
                        </div>
                    </div>

                    <div class="grid gap-4 md:grid-cols-2">
                        <div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                            <Label for="builder-name">Название шаблона</Label>
                            <Input id="builder-name" v-model="template.name" name="name" class="mt-3" />
                            <InputError class="mt-2" :message="errors.name" />
                        </div>

                        <div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                            <Label for="schema-title">Заголовок формы</Label>
                            <Input id="schema-title" v-model="template.schema.title" name="schema[title]" class="mt-3" />
                            <InputError class="mt-2" :message="errors['schema.title']" />
                        </div>
                    </div>

                    <div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                        <Label for="builder-description">Описание</Label>
                        <textarea
                            id="builder-description"
                            v-model="template.description"
                            name="description"
                            class="mt-3 min-h-24 w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 outline-none ring-0"
                        />
                        <input type="hidden" name="schema[description]" :value="template.description" />
                        <InputError class="mt-2" :message="errors.description || errors['schema.description']" />
                    </div>

                    <div class="space-y-4">
                        <div
                            v-for="(section, sectionIndex) in template.schema.sections"
                            :key="`${section.key}-${sectionIndex}`"
                            class="rounded-3xl border border-slate-200 bg-slate-50/80 p-4"
                        >
                            <div class="mb-4 flex flex-wrap items-center justify-between gap-3">
                                <div class="text-lg font-semibold text-slate-900">
                                    Секция {{ sectionIndex + 1 }}
                                </div>
                                <Button type="button" variant="outline" size="sm" :disabled="template.schema.sections.length === 1" @click="removeSection(sectionIndex)">
                                    Удалить секцию
                                </Button>
                            </div>

                            <div class="grid gap-4 md:grid-cols-3">
                                <div class="rounded-2xl border border-white bg-white p-4">
                                    <Label :for="`section-key-${sectionIndex}`">Ключ</Label>
                                    <Input :id="`section-key-${sectionIndex}`" v-model="section.key" :name="`schema[sections][${sectionIndex}][key]`" class="mt-3" />
                                    <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.key`]" />
                                </div>
                                <div class="rounded-2xl border border-white bg-white p-4">
                                    <Label :for="`section-title-${sectionIndex}`">Название секции</Label>
                                    <Input :id="`section-title-${sectionIndex}`" v-model="section.title" :name="`schema[sections][${sectionIndex}][title]`" class="mt-3" />
                                    <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.title`]" />
                                </div>
                                <div class="rounded-2xl border border-white bg-white p-4">
                                    <Label :for="`section-economist-${sectionIndex}`">Заголовок для экономистов</Label>
                                    <Input :id="`section-economist-${sectionIndex}`" v-model="section.economist_label" :name="`schema[sections][${sectionIndex}][economist_label]`" class="mt-3" />
                                    <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.economist_label`]" />
                                </div>
                            </div>

                            <div class="mt-4 space-y-3">
                                <div class="flex items-center justify-between">
                                    <div class="text-sm font-semibold text-slate-900">Поля секции</div>
                                    <Button type="button" variant="outline" size="sm" @click="addField(section)">
                                        Добавить поле
                                    </Button>
                                </div>

                                <div
                                    v-for="(field, fieldIndex) in section.fields"
                                    :key="`${section.key}-${field.key}-${fieldIndex}`"
                                    class="grid gap-4 rounded-2xl border border-slate-200 bg-white p-4 md:grid-cols-[1fr_1fr_220px_auto]"
                                >
                                    <div>
                                        <Label :for="`field-key-${sectionIndex}-${fieldIndex}`">Ключ поля</Label>
                                        <Input :id="`field-key-${sectionIndex}-${fieldIndex}`" v-model="field.key" :name="`schema[sections][${sectionIndex}][fields][${fieldIndex}][key]`" class="mt-3" />
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.fields.${fieldIndex}.key`]" />
                                    </div>
                                    <div>
                                        <Label :for="`field-label-${sectionIndex}-${fieldIndex}`">Подпись</Label>
                                        <Input :id="`field-label-${sectionIndex}-${fieldIndex}`" v-model="field.label" :name="`schema[sections][${sectionIndex}][fields][${fieldIndex}][label]`" class="mt-3" />
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.fields.${fieldIndex}.label`]" />
                                    </div>
                                    <div>
                                        <Label>Тип</Label>
                                        <input type="hidden" :name="`schema[sections][${sectionIndex}][fields][${fieldIndex}][type]`" :value="field.type" />
                                        <Select v-model="field.type">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Тип поля" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value="text">Текст</SelectItem>
                                                <SelectItem value="number">Число</SelectItem>
                                                <SelectItem value="department-select">Выбор отделения</SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.fields.${fieldIndex}.type`]" />
                                    </div>
                                    <div class="flex items-end">
                                        <Button type="button" variant="outline" size="sm" :disabled="section.fields.length === 1" @click="removeField(section, fieldIndex)">
                                            Удалить
                                        </Button>
                                    </div>
                                </div>
                            </div>

                            <div class="mt-6 space-y-3">
                                <div class="flex items-center justify-between">
                                    <div class="text-sm font-semibold text-slate-900">Экспорт для экономистов</div>
                                    <Button type="button" variant="outline" size="sm" @click="addExportMetric(section)">
                                        Добавить метрику
                                    </Button>
                                </div>

                                <div
                                    v-for="(metric, metricIndex) in section.export_metrics"
                                    :key="`${section.key}-metric-${metricIndex}`"
                                    class="grid gap-4 rounded-2xl border border-slate-200 bg-white p-4 md:grid-cols-2 xl:grid-cols-4"
                                >
                                    <div>
                                        <Label :for="`metric-key-${sectionIndex}-${metricIndex}`">Ключ</Label>
                                        <Input
                                            :id="`metric-key-${sectionIndex}-${metricIndex}`"
                                            v-model="metric.key"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][key]`"
                                            class="mt-3"
                                        />
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.key`]" />
                                    </div>
                                    <div>
                                        <Label :for="`metric-label-${sectionIndex}-${metricIndex}`">Подпись</Label>
                                        <Input
                                            :id="`metric-label-${sectionIndex}-${metricIndex}`"
                                            v-model="metric.label"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][label]`"
                                            class="mt-3"
                                        />
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.label`]" />
                                    </div>
                                    <div>
                                        <Label>Числовое поле</Label>
                                        <input
                                            type="hidden"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][source_field]`"
                                            :value="metric.source_field"
                                        />
                                        <Select v-model="metric.source_field">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Поле для агрегации" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem
                                                    v-for="field in numericFields(section)"
                                                    :key="`${section.key}-metric-field-${field.key}`"
                                                    :value="field.key"
                                                >
                                                    {{ field.label }}
                                                </SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.source_field`]" />
                                    </div>
                                    <div>
                                        <Label>Агрегация</Label>
                                        <input
                                            type="hidden"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][aggregation]`"
                                            :value="metric.aggregation"
                                        />
                                        <Select v-model="metric.aggregation">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Агрегация" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value="sum">Сумма</SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.aggregation`]" />
                                    </div>
                                    <div>
                                        <Label>Колонка анализа</Label>
                                        <input
                                            type="hidden"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][analysis_column]`"
                                            :value="metric.analysis_column ?? ''"
                                        />
                                        <Select v-model="metric.analysis_column">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Колонка для экономистов" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem
                                                    v-for="column in template.analysis_columns ?? []"
                                                    :key="`${section.key}-analysis-${column.key}`"
                                                    :value="column.key"
                                                >
                                                    {{ column.coordinate }} · {{ column.label }}
                                                </SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.analysis_column`]" />
                                    </div>
                                    <div>
                                        <Label>Строка анализа</Label>
                                        <input
                                            type="hidden"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][row_mode]`"
                                            :value="metric.row_mode ?? ''"
                                        />
                                        <Select v-model="metric.row_mode">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Куда писать" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value="entry_department">Из выбранного отделения строки</SelectItem>
                                                <SelectItem value="fixed_unit">В фиксированное подразделение</SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.row_mode`]" />
                                    </div>
                                    <div v-if="metric.row_mode === 'fixed_unit'">
                                        <Label>Фиксированное подразделение</Label>
                                        <input
                                            type="hidden"
                                            :name="`schema[sections][${sectionIndex}][export_metrics][${metricIndex}][target_unit_slug]`"
                                            :value="metric.target_unit_slug ?? ''"
                                        />
                                        <Select v-model="metric.target_unit_slug">
                                            <SelectTrigger class="mt-3 w-full">
                                                <SelectValue placeholder="Подразделение финансистов" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem
                                                    v-for="unit in template.analysis_units ?? []"
                                                    :key="`${section.key}-unit-${unit.slug}`"
                                                    :value="unit.slug"
                                                >
                                                    {{ unit.name }}
                                                </SelectItem>
                                            </SelectContent>
                                        </Select>
                                        <InputError class="mt-2" :message="errors[`schema.sections.${sectionIndex}.export_metrics.${metricIndex}.target_unit_slug`]" />
                                    </div>
                                    <div class="flex items-end">
                                        <Button
                                            type="button"
                                            variant="outline"
                                            size="sm"
                                            :disabled="section.export_metrics.length === 1"
                                            @click="removeExportMetric(section, metricIndex)"
                                        >
                                            Удалить
                                        </Button>
                                    </div>
                                </div>
                            </div>

                            <div class="mt-6 space-y-3">
                                <div class="flex items-center justify-between">
                                    <div class="text-sm font-semibold text-slate-900">Значения по умолчанию</div>
                                    <Button type="button" variant="outline" size="sm" @click="addDefaultEntry(section)">
                                        Добавить строку
                                    </Button>
                                </div>

                                <div
                                    v-for="(entry, entryIndex) in section.default_entries"
                                    :key="`${section.key}-default-${entryIndex}`"
                                    class="rounded-2xl border border-slate-200 bg-white p-4"
                                >
                                    <div class="mb-4 flex items-center justify-between gap-3">
                                        <div class="text-sm font-semibold text-slate-900">
                                            Строка по умолчанию {{ entryIndex + 1 }}
                                        </div>
                                        <Button type="button" variant="outline" size="sm" :disabled="section.default_entries.length === 1" @click="removeDefaultEntry(section, entryIndex)">
                                            Удалить
                                        </Button>
                                    </div>

                                    <div class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                                        <div
                                            v-for="field in section.fields"
                                            :key="`${section.key}-${field.key}-default-${entryIndex}`"
                                            class="rounded-2xl border border-slate-100 bg-slate-50 p-4"
                                        >
                                            <Label :for="`${section.key}-${field.key}-${entryIndex}`">
                                                {{ field.label }}
                                            </Label>

                                            <input
                                                v-if="field.type === 'department-select'"
                                                type="hidden"
                                                :name="`schema[sections][${sectionIndex}][default_entries][${entryIndex}][${field.key}]`"
                                                :value="entry[field.key] ?? ''"
                                            />
                                            <Select
                                                v-if="field.type === 'department-select'"
                                                v-model="entry[field.key]"
                                            >
                                                <SelectTrigger class="mt-3 w-full">
                                                    <SelectValue :placeholder="`Выберите: ${field.label}`" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    <SelectItem
                                                        v-for="option in template.department_options ?? []"
                                                        :key="option.id"
                                                        :value="String(option.id)"
                                                    >
                                                        {{ option.name }}
                                                    </SelectItem>
                                                </SelectContent>
                                            </Select>
                                            <Input
                                                v-else
                                                :id="`${section.key}-${field.key}-${entryIndex}`"
                                                v-model="entry[field.key]"
                                                :name="`schema[sections][${sectionIndex}][default_entries][${entryIndex}][${field.key}]`"
                                                class="mt-3"
                                            />
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="flex flex-wrap items-center gap-4">
                        <Button type="button" variant="outline" @click="addSection">
                            Добавить секцию
                        </Button>
                        <Button :disabled="processing">
                            Сохранить шаблон
                        </Button>
                        <p v-if="recentlySuccessful" class="text-sm text-emerald-600">
                            Шаблон сохранен.
                        </p>
                    </div>
                </Form>
            </div>
        </section>
    </div>
</template>
