import DayNavigator from '@/Components/DayNavigator';
import ExportButton from '@/Components/ExportButton';
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 { Activity, AggregatedMetricData, MetricPeriod, User } from '@/types';
import { Head, router, usePage } from '@inertiajs/react';
import dayjs, { Dayjs } from 'dayjs';
import { useState } from 'react';

interface ActivityMetricDetailProps {
    measures: Activity[];
    measuresByHour: AggregatedMetricData[];
    patient: User;
    availableDates: string[];
    period: MetricPeriod<{ date: string; kcal: number }> | null;
    filters: { date: string };
}

export default function ActivityMetricDetail({
    measures,
    measuresByHour,
    patient,
    availableDates,
    period,
    filters,
}: ActivityMetricDetailProps) {
    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('activity.detail', { patient: patient.id }),
            { date: dateString },
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

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

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

    const totalKcal = measures.reduce((s, m) => s + (m.kcal ?? 0), 0);
    const totalSteps = measures.reduce((s, m) => s + (m.steps ?? 0), 0);
    const totalDistance = measures.reduce((s, m) => s + (m.distance ?? 0), 0);

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

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

            <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">
                                Attività fisica
                            </div>
                            <div className="flex justify-center gap-2 md:justify-end">
                                <PrintButton />
                                <ExportButton
                                    href={route('activity.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>
                                <BarMetricChart
                                    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} kcal/giorno`
                                                    : null
                                            }
                                            max={
                                                period.summary
                                                    ? `${period.summary.max} kcal`
                                                    : null
                                            }
                                            min={
                                                period.summary
                                                    ? `${period.summary.min} kcal`
                                                    : null
                                            }
                                            caption={
                                                period.summary
                                                    ? `${period.summary.count} giorni con attività 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="Kcal totali"
                                                value={`${totalKcal} kcal`}
                                                className="bg-neutral-200"
                                            />
                                            <MetricSummaryCard
                                                title="Passi totali"
                                                value={`${totalSteps} passi`}
                                                className="bg-neutral-100"
                                            />
                                            {totalDistance > 0 && (
                                                <MetricSummaryCard
                                                    title="Distanza"
                                                    value={`${totalDistance} m`}
                                                    className="bg-neutral-100"
                                                />
                                            )}
                                        </div>
                                    )}
                                    <div className="mt-8 text-zinc-500">
                                        Monitorare l'attività fisica quotidiana
                                        aiuta a mantenere un buon stato di
                                        salute. Il grafico mostra le calorie
                                        bruciate ora per ora durante la
                                        giornata.
                                    </div>
                                    {!period && (
                                        <div className="mt-8">
                                            <h2 className="mb-4 font-semibold">
                                                Attività rilevate
                                            </h2>
                                            <ul>
                                                {measures.map((measure) => {
                                                    const parts = [
                                                        measure.kcal != null
                                                            ? `${measure.kcal} kcal`
                                                            : null,
                                                        measure.steps != null
                                                            ? `${measure.steps} passi`
                                                            : null,
                                                        measure.distance != null
                                                            ? `${measure.distance} m`
                                                            : null,
                                                    ]
                                                        .filter(Boolean)
                                                        .join(' · ');
                                                    return (
                                                        <MetricMeasure
                                                            key={measure.id}
                                                            value={parts}
                                                            measuredAt={dayjs(
                                                                measure.measured_at,
                                                            )}
                                                            deviceName={
                                                                measure.device_label ??
                                                                measure.device_name
                                                            }
                                                        />
                                                    );
                                                })}
                                            </ul>
                                        </div>
                                    )}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}
