import DayNavigator from '@/Components/DayNavigator';
import PrintButton from '@/Components/PrintButton';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import BarMetricChart from '@/Pages/Metric/BarMetricChart';
import MetricMeasure from '@/Pages/Metric/MetricMeasure';
import MetricPeriodSummary from '@/Pages/Metric/MetricPeriodSummary';
import MetricSummaryCard from '@/Pages/Metric/MetricSummaryCard';
import { MetricPeriod, Sleep, User } from '@/types';
import { Head, router, usePage } from '@inertiajs/react';
import dayjs, { Dayjs } from 'dayjs';
import duration from 'dayjs/plugin/duration';
import { useState } from 'react';

dayjs.extend(duration);

interface MetricDetailProps {
    measures: Sleep[];
    patient: User;
    availableDates: string[];
    period: MetricPeriod<{ date: string; average: number }> | null;
}

export default function SleepsMetricDetail({
    measures,
    patient,
    availableDates,
    period,
}: MetricDetailProps) {
    const user = usePage().props.auth.user;
    const now = dayjs();
    const { filters } = usePage().props;
    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);

        // Immediately send search request
        router.get(
            route('sleep.detail', { patient: patient.id }),
            {
                date: dateString,
            },
            {
                preserveState: true,
                preserveScroll: true,
                replace: true, // Prevent duplicate history entries
            },
        );
    };

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

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

    const formatDuration = (seconds: number) => {
        const d = dayjs.duration(seconds, 'seconds');
        const hours = Math.floor(d.asHours());
        return hours > 0 ? `${hours}h ${d.minutes()}m` : `${d.minutes()}m`;
    };

    // Hours per night for the period bar chart.
    const periodData = period
        ? period.data.map((point) => ({
              date: dayjs(point.date).format(
                  period.byMonth ? 'MM/YYYY' : 'DD/MM',
              ),
              value: Math.round((point.average / 3600) * 10) / 10,
          }))
        : [];

    const sleepTotal = measures.reduce(
        (sum, sleep) => sum + sleep.total_duration,
        0,
    );
    const deepTotal = measures.reduce(
        (sum, sleep) => sum + sleep.deep_duration,
        0,
    );
    const lightTotal = measures.reduce(
        (sum, sleep) => sum + sleep.light_duration,
        0,
    );
    const remTotal = measures.reduce(
        (sum, sleep) => sum + (sleep.rem_duration ?? 0),
        0,
    );
    const deepPercentage =
        sleepTotal > 0 ? Math.round((deepTotal / sleepTotal) * 100) : '-';
    const lightPercentage =
        sleepTotal > 0 ? Math.round((lightTotal / sleepTotal) * 100) : '-';
    const remPercentage =
        sleepTotal > 0 ? Math.round((remTotal / sleepTotal) * 100) : '-';
    const totalSleepDuration = dayjs.duration(sleepTotal, 'seconds');
    const formattedTotalSleepDuration = `${totalSleepDuration.hours()}h ${totalSleepDuration.minutes()}m`;
    const firstMeasure = measures.length ? measures[0] : null;
    const start = firstMeasure
        ? dayjs(firstMeasure.started_at).format('HH:mm')
        : '';
    const end = firstMeasure
        ? dayjs(firstMeasure.ended_at).format('HH:mm')
        : '';

    // Rich per-night details from the chosen measure (one record per night after dedup).
    const sleepDetails = firstMeasure
        ? [
              firstMeasure.time_in_bed != null
                  ? {
                        label: 'Tempo a letto',
                        value: formatDuration(firstMeasure.time_in_bed),
                    }
                  : null,
              firstMeasure.sleep_efficiency != null
                  ? {
                        label: 'Efficienza',
                        value: `${Math.round(firstMeasure.sleep_efficiency * 100)} %`,
                    }
                  : null,
              firstMeasure.rem_duration != null
                  ? {
                        label: 'REM',
                        value: formatDuration(firstMeasure.rem_duration),
                    }
                  : null,
              firstMeasure.awake_duration != null
                  ? {
                        label: 'Tempo sveglio',
                        value: formatDuration(firstMeasure.awake_duration),
                    }
                  : null,
              firstMeasure.sleep_latency != null
                  ? {
                        label: 'Latenza addormentamento',
                        value: formatDuration(firstMeasure.sleep_latency),
                    }
                  : null,
              firstMeasure.wakeup_count != null
                  ? { label: 'Risvegli', value: `${firstMeasure.wakeup_count}` }
                  : null,
              firstMeasure.out_of_bed_count != null
                  ? {
                        label: 'Fuori dal letto',
                        value: `${firstMeasure.out_of_bed_count}`,
                    }
                  : null,
          ].filter((d): d is { label: string; value: string } => d !== null)
        : [];

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

            <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">
                                Qualità del sonno
                            </div>
                            <div className="flex justify-center gap-2 md:justify-end">
                                <PrintButton />
                                <DayNavigator
                                    date={dayjs(date)}
                                    onChange={onDateChange}
                                    availableDates={availableDates}
                                    range={
                                        period
                                            ? {
                                                  from: dayjs(period.from),
                                                  to: dayjs(period.to),
                                              }
                                            : null
                                    }
                                    onRangeChange={onRangeChange}
                                />
                            </div>
                            <div>
                                {period && <BarMetricChart data={periodData} />}
                            </div>
                            <div className="flex w-full justify-center">
                                <div className="max-w-2xl">
                                    {period && (
                                        <MetricPeriodSummary
                                            average={
                                                period.summary
                                                    ? formatDuration(
                                                          period.summary
                                                              .average,
                                                      )
                                                    : null
                                            }
                                            max={
                                                period.summary
                                                    ? formatDuration(
                                                          period.summary.max,
                                                      )
                                                    : null
                                            }
                                            min={
                                                period.summary
                                                    ? formatDuration(
                                                          period.summary.min,
                                                      )
                                                    : null
                                            }
                                            caption={
                                                period.summary
                                                    ? `${period.summary.count} notti dal ${dayjs(period.from).format('DD/MM/YYYY')} al ${dayjs(period.to).format('DD/MM/YYYY')}`
                                                    : null
                                            }
                                        />
                                    )}
                                    {!period && (
                                        <div className="mt-8 flex flex-col gap-4 md:flex-row">
                                            <MetricSummaryCard
                                                title="Totale"
                                                value={
                                                    formattedTotalSleepDuration
                                                }
                                                className="w-full bg-neutral-400"
                                            />
                                            <MetricSummaryCard
                                                title="Profondo"
                                                value={`${deepPercentage} %`}
                                                className="bg-neutral-300"
                                            />
                                            <MetricSummaryCard
                                                title="REM"
                                                value={`${remPercentage} %`}
                                                className="bg-neutral-200"
                                            />
                                            <MetricSummaryCard
                                                title="Leggero"
                                                value={`${lightPercentage} %`}
                                                className="bg-neutral-100"
                                            />
                                            <MetricSummaryCard
                                                title="Orario"
                                                value={`${start} - ${end}`}
                                                className="bg-neutral-50 md:min-w-[200px]"
                                            />
                                        </div>
                                    )}
                                    <div className="mt-8 text-zinc-500">
                                        Monitorare il sonno aiuta a capire la
                                        qualità del riposo, fondamentale per la
                                        salute fisica e mentale. Il sonno può
                                        essere diviso in leggero e profondo: il
                                        primo supporta il recupero mentale, il
                                        secondo la rigenerazione fisica. Un
                                        sonno equilibrato migliora energia,
                                        memoria e benessere generale.
                                    </div>
                                    {!period && sleepDetails.length > 0 && (
                                        <div className="mt-8">
                                            <h2 className="mb-4 font-semibold">
                                                Dettaglio notte
                                            </h2>
                                            <dl className="grid grid-cols-2 gap-x-4 gap-y-3 sm:grid-cols-3">
                                                {sleepDetails.map((detail) => (
                                                    <div
                                                        key={detail.label}
                                                        className="flex flex-col"
                                                    >
                                                        <dt className="text-sm text-zinc-500">
                                                            {detail.label}
                                                        </dt>
                                                        <dd className="text-lg font-medium text-black">
                                                            {detail.value}
                                                        </dd>
                                                    </div>
                                                ))}
                                            </dl>
                                        </div>
                                    )}
                                    {!period && measures.length > 0 && (
                                        <div className="mt-8">
                                            <h2 className="mb-4 font-semibold">
                                                Misurazioni
                                            </h2>
                                            <ul>
                                                {measures.map((measure) => {
                                                    const d = dayjs.duration(
                                                        measure.total_duration,
                                                        'seconds',
                                                    );
                                                    return (
                                                        <MetricMeasure
                                                            key={measure.id}
                                                            value={`${d.hours()}h ${d.minutes()}m`}
                                                            measuredAt={dayjs(
                                                                measure.ended_at,
                                                            )}
                                                            deviceName={
                                                                measure.device_label ??
                                                                measure.device_name ??
                                                                undefined
                                                            }
                                                        />
                                                    );
                                                })}
                                            </ul>
                                        </div>
                                    )}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}
