import DayNavigator from '@/Components/DayNavigator';
import ExportButton from '@/Components/ExportButton';
import PrintButton from '@/Components/PrintButton';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { capitalize, t } from '@/lib/utils';
import LineMetricChart from '@/Pages/Metric/LineMetricChart';
import MetricMeasure from '@/Pages/Metric/MetricMeasure';
import MetricPeriodSummary from '@/Pages/Metric/MetricPeriodSummary';
import MetricSummaryCard from '@/Pages/Metric/MetricSummaryCard';
import {
    AggregatedMetricData,
    MetricPeriod,
    OxygenSaturation,
    User,
} from '@/types';
import { Head, router, usePage } from '@inertiajs/react';
import dayjs, { Dayjs } from 'dayjs';
import { useState } from 'react';

interface MetricDetailProps {
    measures: OxygenSaturation[];
    metricName: string;
    patient: User;
    availableDates: string[];
    period: MetricPeriod | null;
    measuresByHour: AggregatedMetricData[];
}

export default function OxygenSaturationMetricDetail({
    measures,
    measuresByHour,
    metricName,
    patient,
    availableDates,
    period,
}: MetricDetailProps) {
    const user = usePage().props.auth.user;
    const now = dayjs();
    const { filters } = usePage().props as unknown as {
        filters: { date?: string };
    };
    const [date, setDate] = useState(filters?.date || now.format('YYYY-MM-DD'));

    const onDateChange = (updatedDate: Dayjs) => {
        const dateString = dayjs(updatedDate).format('YYYY-MM-DD');
        setDate(dateString);
        router.get(
            route('oxygen-saturation.detail', { patient: patient.id }),
            { date: dateString },
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

    const onRangeChange = (from: Dayjs, to: Dayjs) => {
        router.get(
            route('oxygen-saturation.detail', { patient: patient.id }),
            {
                from: from.format('YYYY-MM-DD'),
                to: to.format('YYYY-MM-DD'),
            },
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

    const periodData = period
        ? period.data.map((point) => ({
              date: dayjs(point.date).format(
                  period.byMonth ? 'MM/YYYY' : 'DD/MM',
              ),
              average: point.average,
              min: point.min,
              max: point.max,
          }))
        : [];

    const backLinkLabel =
        patient.id === user.id
            ? 'Dashboard'
            : `${patient.name} ${patient.surname}`;

    const data = measuresByHour.map((measure) => ({
        date: dayjs(measure.date).format('HH:mm'),
        average: measure.average,
        min: measure.min,
        max: measure.max,
    }));

    const ascSortedMeasures = [...measures].sort((a, b) => a.value - b.value);
    const min = measures.length ? ascSortedMeasures[0].value : null;
    const max = measures.length
        ? ascSortedMeasures[ascSortedMeasures.length - 1].value
        : null;

    const measuresWithHrv = measures.filter((m) => m.hrv != null);
    const avgHrv = measuresWithHrv.length
        ? Math.round(
              measuresWithHrv.reduce((s, m) => s + m.hrv!, 0) /
                  measuresWithHrv.length,
          )
        : null;

    const measuresWithBreath = measures.filter((m) => m.breath != null);
    const avgBreath = measuresWithBreath.length
        ? Math.round(
              measuresWithBreath.reduce((s, m) => s + m.breath!, 0) /
                  measuresWithBreath.length,
          )
        : null;

    return (
        <AuthenticatedLayout
            backLink={route('dashboard.personal', { target: patient.id })}
            backLinkLabel={backLinkLabel}
        >
            <Head title={capitalize(t(metricName))} />

            <div className="py-2">
                <div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
                    <div className="overflow-hidden sm:rounded-lg">
                        <div className="p-6 text-gray-900">
                            <div className="scroll-m-20 pb-8 text-4xl font-semibold tracking-tight lg:text-5xl">
                                Saturazione di ossigeno
                            </div>
                            <div className="flex justify-center gap-2 md:justify-end">
                                <PrintButton />
                                <ExportButton
                                    href={route(
                                        'oxygen-saturation.detail.export',
                                        { patient: patient.id },
                                    )}
                                />
                                <DayNavigator
                                    date={dayjs(date)}
                                    onChange={onDateChange}
                                    availableDates={availableDates}
                                    range={
                                        period
                                            ? {
                                                  from: dayjs(period.from),
                                                  to: dayjs(period.to),
                                              }
                                            : null
                                    }
                                    onRangeChange={onRangeChange}
                                />
                            </div>
                            <div>
                                <LineMetricChart
                                    data={period ? periodData : data}
                                />
                            </div>
                            <div className="flex w-full justify-center">
                                <div className="max-w-2xl">
                                    {period && (
                                        <MetricPeriodSummary
                                            average={
                                                period.summary
                                                    ? `${period.summary.average} %`
                                                    : null
                                            }
                                            max={
                                                period.summary
                                                    ? `${period.summary.max} %`
                                                    : null
                                            }
                                            min={
                                                period.summary
                                                    ? `${period.summary.min} %`
                                                    : null
                                            }
                                            caption={
                                                period.summary
                                                    ? `${period.summary.count} misurazioni dal ${dayjs(period.from).format('DD/MM/YYYY')} al ${dayjs(period.to).format('DD/MM/YYYY')}`
                                                    : null
                                            }
                                        />
                                    )}
                                    {!period && (
                                        <div className="mt-8 flex flex-wrap gap-4">
                                            <MetricSummaryCard
                                                title="Massimo SpO2"
                                                value={
                                                    max ? `${max} %` : undefined
                                                }
                                                className="bg-neutral-200"
                                            />
                                            <MetricSummaryCard
                                                title="Minimo SpO2"
                                                value={
                                                    min ? `${min} %` : undefined
                                                }
                                                className="bg-neutral-100"
                                            />
                                            {avgHrv !== null && (
                                                <MetricSummaryCard
                                                    title="HRV medio"
                                                    value={`${avgHrv} ms`}
                                                    className="bg-neutral-100"
                                                />
                                            )}
                                            {avgBreath !== null && (
                                                <MetricSummaryCard
                                                    title="Resp. media"
                                                    value={`${avgBreath} /min`}
                                                    className="bg-neutral-100"
                                                />
                                            )}
                                        </div>
                                    )}
                                    <div className="mt-8 text-zinc-500">
                                        La saturazione di ossigeno (SpO2) indica
                                        la quantità di ossigeno nel sangue.
                                        Monitorarla è importante per valutare la
                                        salute respiratoria e il livello di
                                        ossigenazione del corpo. Valori normali
                                        sono sopra il 95%. Livelli bassi possono
                                        indicare problemi respiratori o
                                        circolatori e richiedere attenzione
                                        medica.
                                    </div>
                                    {!period && (
                                        <div className="mt-8">
                                            <h2 className="mb-4 font-semibold">
                                                Misurazioni
                                            </h2>
                                            <ul>
                                                {measures.map((measure) => {
                                                    const extras = [
                                                        measure.hrv != null
                                                            ? `HRV: ${measure.hrv}`
                                                            : null,
                                                        measure.breath != null
                                                            ? `Resp: ${measure.breath} /min`
                                                            : null,
                                                    ]
                                                        .filter(Boolean)
                                                        .join(' · ');
                                                    const label = extras
                                                        ? `${measure.value} % · ${extras}`
                                                        : `${measure.value} %`;
                                                    return (
                                                        <MetricMeasure
                                                            key={measure.id}
                                                            value={label}
                                                            measuredAt={dayjs(
                                                                measure.measured_at,
                                                            )}
                                                            deviceName={
                                                                measure.device_label ??
                                                                measure.device_name
                                                            }
                                                        />
                                                    );
                                                })}
                                            </ul>
                                        </div>
                                    )}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}
