import DayNavigator from '@/Components/DayNavigator';
import ExportButton from '@/Components/ExportButton';
import PrintButton from '@/Components/PrintButton';
import {
    ChartConfig,
    ChartContainer,
    ChartTooltip,
    ChartTooltipContent,
} from '@/Components/ui/chart';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import MetricChart from '@/Pages/Metric/MetricChart';
import MetricMeasure from '@/Pages/Metric/MetricMeasure';
import MetricSummaryCard from '@/Pages/Metric/MetricSummaryCard';
import { BloodPressure, MetricPeriod, User } from '@/types';
import { Head, router, usePage } from '@inertiajs/react';
import dayjs, { Dayjs } from 'dayjs';
import { useState } from 'react';
import { Line, LineChart, XAxis, YAxis } from 'recharts';

interface BloodPressurePeriodPoint {
    date: string;
    systolic: number;
    diastolic: number;
}

interface BloodPressurePeriodSummary {
    systolic: { average: number; min: number; max: number };
    diastolic: { average: number; min: number; max: number };
    count: number;
}

interface BloodPressureMetricDetailProps {
    measures: BloodPressure[];
    patient: User;
    availableDates: string[];
    period: MetricPeriod<
        BloodPressurePeriodPoint,
        BloodPressurePeriodSummary
    > | null;
    filters: { date: string };
}

export default function BloodPressureMetricDetail({
    measures,
    patient,
    availableDates,
    period,
    filters,
}: BloodPressureMetricDetailProps) {
    const user = usePage().props.auth.user;
    const [date, setDate] = useState(
        filters?.date || dayjs().format('YYYY-MM-DD'),
    );

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

    const onRangeChange = (from: Dayjs, to: Dayjs) => {
        router.get(
            route('blood-pressure.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',
              ),
              systolic: point.systolic,
              diastolic: point.diastolic,
          }))
        : [];

    const chartConfig: ChartConfig = {
        systolic: { label: 'Sistolica', color: '#05A7A0' },
        diastolic: { label: 'Diastolica', color: '#7dd3d0' },
    };

    // measures arrive most-recent-first; the chart needs chronological order on the x-axis.
    const chartData = [...measures]
        .sort(
            (a, b) =>
                dayjs(a.measured_at).valueOf() - dayjs(b.measured_at).valueOf(),
        )
        .map((m) => ({
            date: dayjs(m.measured_at).format('HH:mm'),
            systolic: m.systolic,
            diastolic: m.diastolic,
        }));

    const maxSystolic = measures.length
        ? Math.max(...measures.map((m) => m.systolic))
        : null;
    const minSystolic = measures.length
        ? Math.min(...measures.map((m) => m.systolic))
        : null;
    const maxDiastolic = measures.length
        ? Math.max(...measures.map((m) => m.diastolic))
        : null;
    const minDiastolic = measures.length
        ? Math.min(...measures.map((m) => m.diastolic))
        : null;

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

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

            <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">
                                Pressione arteriosa
                            </div>
                            <div className="flex justify-center gap-2 md:justify-end">
                                <PrintButton />
                                <ExportButton
                                    href={route(
                                        'blood-pressure.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>
                                <MetricChart>
                                    <ChartContainer
                                        config={chartConfig}
                                        className="h-[120px] w-full lg:h-[180px]"
                                    >
                                        <LineChart
                                            data={
                                                period ? periodData : chartData
                                            }
                                            margin={{
                                                top: 4,
                                                bottom: 0,
                                                left: 24,
                                                right: 24,
                                            }}
                                        >
                                            <XAxis
                                                className="font-semibold uppercase text-neutral-500"
                                                dataKey="date"
                                                tickLine={false}
                                                axisLine={false}
                                                tickMargin={8}
                                                tick={{ fill: '#69cac6' }}
                                            />
                                            <YAxis
                                                tickLine={false}
                                                axisLine={false}
                                                tickMargin={30}
                                                tick={{ fill: '#69cac6' }}
                                            />
                                            <ChartTooltip
                                                content={
                                                    <ChartTooltipContent />
                                                }
                                            />
                                            <Line
                                                dataKey="systolic"
                                                type="natural"
                                                stroke="var(--color-systolic)"
                                                strokeWidth={2}
                                                dot={{
                                                    fill: 'var(--color-systolic)',
                                                }}
                                                activeDot={{ r: 6 }}
                                            />
                                            <Line
                                                dataKey="diastolic"
                                                type="natural"
                                                stroke="var(--color-diastolic)"
                                                strokeWidth={2}
                                                dot={{
                                                    fill: 'var(--color-diastolic)',
                                                }}
                                                activeDot={{ r: 6 }}
                                            />
                                        </LineChart>
                                    </ChartContainer>
                                </MetricChart>
                            </div>
                            <div className="flex w-full justify-center">
                                <div className="max-w-2xl">
                                    {period && (
                                        <div>
                                            <div className="mt-8 flex gap-4 md:flex-row">
                                                <MetricSummaryCard
                                                    title="Sistolica media"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.systolic.average} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-teal-50"
                                                />
                                                <MetricSummaryCard
                                                    title="Sistolica max"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.systolic.max} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-neutral-200"
                                                />
                                                <MetricSummaryCard
                                                    title="Sistolica min"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.systolic.min} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-neutral-100"
                                                />
                                            </div>
                                            <div className="mt-4 flex gap-4 md:flex-row">
                                                <MetricSummaryCard
                                                    title="Diastolica media"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.diastolic.average} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-teal-50"
                                                />
                                                <MetricSummaryCard
                                                    title="Diastolica max"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.diastolic.max} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-neutral-200"
                                                />
                                                <MetricSummaryCard
                                                    title="Diastolica min"
                                                    value={
                                                        period.summary
                                                            ? `${period.summary.diastolic.min} mmHg`
                                                            : undefined
                                                    }
                                                    className="bg-neutral-100"
                                                />
                                            </div>
                                            {period.summary && (
                                                <div className="mt-2 text-right text-sm text-zinc-500">
                                                    {period.summary.count}{' '}
                                                    misurazioni dal{' '}
                                                    {dayjs(period.from).format(
                                                        'DD/MM/YYYY',
                                                    )}{' '}
                                                    al{' '}
                                                    {dayjs(period.to).format(
                                                        'DD/MM/YYYY',
                                                    )}
                                                </div>
                                            )}
                                        </div>
                                    )}
                                    {!period && (
                                        <div className="mt-8 flex gap-4 md:flex-row">
                                            <MetricSummaryCard
                                                title="Sistolica max"
                                                value={
                                                    maxSystolic
                                                        ? `${maxSystolic} mmHg`
                                                        : undefined
                                                }
                                                className="bg-neutral-200"
                                            />
                                            <MetricSummaryCard
                                                title="Sistolica min"
                                                value={
                                                    minSystolic
                                                        ? `${minSystolic} mmHg`
                                                        : undefined
                                                }
                                                className="bg-neutral-100"
                                            />
                                            <MetricSummaryCard
                                                title="Diastolica max"
                                                value={
                                                    maxDiastolic
                                                        ? `${maxDiastolic} mmHg`
                                                        : undefined
                                                }
                                                className="bg-neutral-200"
                                            />
                                            <MetricSummaryCard
                                                title="Diastolica min"
                                                value={
                                                    minDiastolic
                                                        ? `${minDiastolic} mmHg`
                                                        : undefined
                                                }
                                                className="bg-neutral-100"
                                            />
                                        </div>
                                    )}
                                    <div className="mt-8 text-zinc-500">
                                        La pressione arteriosa misura la forza
                                        del sangue sulle pareti delle arterie.
                                        Il valore sistolico (massima) indica la
                                        pressione durante il battito cardiaco,
                                        quello diastolico (minima) durante il
                                        riposo. Valori normali sono circa 120/80
                                        mmHg.
                                    </div>
                                    {!period && (
                                        <div className="mt-8">
                                            <h2 className="mb-4 font-semibold">
                                                Misurazioni
                                            </h2>
                                            <ul>
                                                {measures.map((measure) => (
                                                    <MetricMeasure
                                                        key={measure.id}
                                                        value={`${measure.systolic}/${measure.diastolic} mmHg${measure.pulse_rate ? ` · ${measure.pulse_rate} bpm` : ''}`}
                                                        measuredAt={dayjs(
                                                            measure.measured_at,
                                                        )}
                                                        deviceName={
                                                            measure.device_label ??
                                                            measure.device_name
                                                        }
                                                    />
                                                ))}
                                            </ul>
                                        </div>
                                    )}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}
