import SummaryCard from '@/Components/SummaryCard';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import BarMetricCard from '@/Pages/Dashboard/BarMetricCard';
import EcgMetricCard from '@/Pages/Dashboard/EcgMetricCard';
import LineMetricCard from '@/Pages/Dashboard/LineMetricCard';
import SpirometryMetricCard from '@/Pages/Dashboard/SpirometryMetricCard';
import {
    Activity,
    AggregatedMetricData,
    BloodPressure,
    BodyComposition,
    DynamicBloodPressure,
    Ecg,
    Glucose,
    HeartRate,
    LabSummary,
    OxygenSaturation,
    Spirometry,
    Temperature,
    User,
} from '@/types';
import { Head, usePage } from '@inertiajs/react';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import { Bell, FileText, Pill, Watch } from 'lucide-react';

dayjs.extend(duration);

interface PatientDashboardProps {
    devicesCount: number;
    alertsCount: number;
    drugsToRestockCount: number;
    documentsCount: number;
    user: User;
    heartRates: AggregatedMetricData[];
    lastHeartRate?: HeartRate;
    oxygenSaturations: AggregatedMetricData[];
    lastOxygenSaturation?: OxygenSaturation;
    sleeps: AggregatedMetricData[];
    ecg?: Ecg;
    bloodPressures: {
        date: string;
        systolic: number | null;
        diastolic: number | null;
    }[];
    lastBloodPressure?: BloodPressure;
    holterPressures: {
        date: string;
        systolic: number | null;
        diastolic: number | null;
    }[];
    lastHolterPressure?: DynamicBloodPressure;
    temperatures: AggregatedMetricData[];
    lastTemperature?: Temperature;
    glucoses: AggregatedMetricData[];
    lastGlucose?: Glucose;
    labMeasures: LabSummary[];
    activities: AggregatedMetricData[];
    lastActivity?: Activity;
    lastSpirometry?: Spirometry;
    bodyCompositions: BodyComposition[];
    lastBodyComposition?: BodyComposition;
}

export default function PatientDashboard({
    devicesCount,
    user,
    heartRates,
    lastHeartRate,
    oxygenSaturations,
    lastOxygenSaturation,
    sleeps,
    ecg,
    alertsCount,
    drugsToRestockCount,
    documentsCount,
    bloodPressures,
    lastBloodPressure,
    holterPressures,
    lastHolterPressure,
    temperatures,
    lastTemperature,
    glucoses,
    lastGlucose,
    labMeasures,
    activities,
    lastActivity,
    lastSpirometry,
    bodyCompositions,
    lastBodyComposition,
}: PatientDashboardProps) {
    const authUser: User = usePage().props.auth.user;
    const isAuthUserPatient = usePage().props.auth.is_patient;

    const heartRatesForChart = heartRates.map((heartRate) => {
        return {
            date: new Date(heartRate.date).toLocaleDateString('it', {
                weekday: 'long',
            }),
            average: heartRate.average,
            min: heartRate.min,
            max: heartRate.max,
        };
    });

    const lastHeartRateValue = lastHeartRate ? lastHeartRate.value : null;
    const lastHeartRateDate = lastHeartRate
        ? new Date(lastHeartRate.measured_at)
        : null;
    const lastHeartRateFormattedDate = lastHeartRateDate
        ? `${lastHeartRateDate.getHours().toString().padStart(2, '0')}:${lastHeartRateDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const oxygenSaturationsForChart = oxygenSaturations.map(
        (oxygenSaturation) => {
            return {
                date: new Date(oxygenSaturation.date).toLocaleDateString('it', {
                    weekday: 'long',
                }),
                average: oxygenSaturation.average,
                min: oxygenSaturation.min,
                max: oxygenSaturation.max,
            };
        },
    );

    const lastOxygenSaturationValue = lastOxygenSaturation?.value;
    const lastOxygenSaturationDate = lastOxygenSaturation
        ? new Date(lastOxygenSaturation.measured_at)
        : null;
    const lastOxygenSaturationFormattedDate = lastOxygenSaturationDate
        ? `${lastOxygenSaturationDate.getHours().toString().padStart(2, '0')}:${lastOxygenSaturationDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const sleepsForChart = sleeps.map((sleep) => {
        return {
            date: new Date(sleep.date).toLocaleDateString('it', {
                weekday: 'long',
            }),
            value: sleep.sum,
        };
    });

    const notNullSleeps = sleeps.filter((sleep) => sleep.sum !== null);
    const averageSleep =
        notNullSleeps.reduce((sum, sleep) => sum + sleep.sum, 0) /
        notNullSleeps.length;
    const averageSleepDuration = dayjs.duration(averageSleep, 'seconds');
    const formattedAverageSleep = `${averageSleepDuration.hours()}h ${averageSleepDuration.minutes()}m`;

    const ecgForChart = ecg
        ? ecg.signals
              .map((signal, index) => {
                  return {
                      date: index,
                      average: signal,
                  };
              })
              .slice(0, 1000)
        : [];

    const bloodPressuresForChart = bloodPressures.map((bp) => ({
        date: new Date(bp.date).toLocaleDateString('it', { weekday: 'long' }),
        average: bp.systolic,
    }));

    const lastBloodPressureValue = lastBloodPressure
        ? `${lastBloodPressure.systolic}/${lastBloodPressure.diastolic}`
        : null;
    const lastBloodPressureDate = lastBloodPressure
        ? new Date(lastBloodPressure.measured_at)
        : null;
    const lastBloodPressureFormattedDate = lastBloodPressureDate
        ? `${lastBloodPressureDate.getHours().toString().padStart(2, '0')}:${lastBloodPressureDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const holterPressuresForChart = holterPressures.map((bp) => ({
        date: new Date(bp.date).toLocaleDateString('it', { weekday: 'long' }),
        average: bp.systolic,
    }));

    const lastHolterValue = lastHolterPressure
        ? `${lastHolterPressure.systolic}/${lastHolterPressure.diastolic}`
        : null;
    const lastHolterDate = lastHolterPressure
        ? new Date(lastHolterPressure.measured_at)
        : null;
    const lastHolterFormattedDate = lastHolterDate
        ? `${lastHolterDate.getHours().toString().padStart(2, '0')}:${lastHolterDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const temperaturesForChart = temperatures.map((t) => ({
        date: new Date(t.date).toLocaleDateString('it', { weekday: 'long' }),
        average: t.average,
        min: t.min,
        max: t.max,
    }));

    const lastTemperatureValue = lastTemperature?.value ?? null;
    const lastTemperatureDate = lastTemperature
        ? new Date(lastTemperature.measured_at)
        : null;
    const lastTemperatureFormattedDate = lastTemperatureDate
        ? `${lastTemperatureDate.getHours().toString().padStart(2, '0')}:${lastTemperatureDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const glucosesForChart = glucoses.map((g) => ({
        date: new Date(g.date).toLocaleDateString('it', { weekday: 'long' }),
        average: g.average,
        min: g.min,
        max: g.max,
    }));

    const lastGlucoseValue = lastGlucose?.value ?? null;
    const lastGlucoseDate = lastGlucose
        ? new Date(lastGlucose.measured_at)
        : null;
    const lastGlucoseFormattedDate = lastGlucoseDate
        ? `${lastGlucoseDate.getHours().toString().padStart(2, '0')}:${lastGlucoseDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const activitiesForChart = activities.map((a) => ({
        date: new Date(a.date).toLocaleDateString('it', { weekday: 'long' }),
        value: a.sum,
    }));

    const lastActivityValue =
        lastActivity?.kcal != null ? `${lastActivity.kcal} kcal` : null;
    const lastActivityDate = lastActivity
        ? new Date(lastActivity.measured_at)
        : null;
    const lastActivityFormattedDate = lastActivityDate
        ? `${lastActivityDate.getHours().toString().padStart(2, '0')}:${lastActivityDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const bodyCompositionForChart = bodyCompositions.map((bc) => ({
        date: new Date(bc.measured_at).toLocaleDateString('it', {
            weekday: 'long',
        }),
        average: bc.weight ?? null,
    }));
    const lastBodyCompositionValue =
        lastBodyComposition?.weight != null
            ? `${Number(lastBodyComposition.weight).toFixed(1)} kg`
            : null;
    const lastBodyCompositionDate = lastBodyComposition
        ? new Date(lastBodyComposition.measured_at)
        : null;
    const lastBodyCompositionFormattedDate = lastBodyCompositionDate
        ? `${lastBodyCompositionDate.getHours().toString().padStart(2, '0')}:${lastBodyCompositionDate.getMinutes().toString().padStart(2, '0')}`
        : undefined;

    const spirometryFlow = lastSpirometry?.waveform_flow ?? [];
    const spirometryVolume = lastSpirometry?.waveform_volume ?? [];
    const spirometryForChart = spirometryVolume.map((v, i) => ({
        x: v,
        y: spirometryFlow[i] ?? 0,
    }));
    const lastSpirometryValue =
        lastSpirometry?.fev1 != null
            ? `FEV1 ${Number(lastSpirometry.fev1).toFixed(2)} L`
            : '-';
    const lastSpirometryDate = lastSpirometry
        ? new Date(lastSpirometry.measured_at)
        : null;
    const lastSpirometryFormattedDate = lastSpirometryDate
        ? `${lastSpirometryDate.getHours().toString().padStart(2, '0')}:${lastSpirometryDate.getMinutes().toString().padStart(2, '0')}`
        : undefined;

    const lastEcgDate = ecg ? new Date(ecg.measured_at) : null;
    const lastEcgFormattedDate = lastEcgDate
        ? `${lastEcgDate.getHours().toString().padStart(2, '0')}:${lastEcgDate.getMinutes().toString().padStart(2, '0')}`
        : null;

    const backLink = isAuthUserPatient ? null : route('admin-users');
    const backLinkLabel = backLink ? 'Utenti' : null;

    return (
        <AuthenticatedLayout backLink={backLink} backLinkLabel={backLinkLabel}>
            <Head title="Dashboard" />

            <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">
                            {authUser.id == user.id ? (
                                <div className="scroll-m-20 text-4xl font-light tracking-tight lg:text-5xl">
                                    Ciao,
                                </div>
                            ) : null}
                            <div className="scroll-m-20 pb-8 text-4xl font-semibold tracking-tight lg:text-5xl">
                                {`${user.name} ${user.surname}`}
                            </div>
                            <div>
                                <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                    <SummaryCard
                                        title="Dispositivi"
                                        amount={devicesCount}
                                        icon={Watch}
                                        href={route('patient-devices', {
                                            patient: user.id,
                                        })}
                                    />
                                    <SummaryCard
                                        title="Avvisi"
                                        amount={alertsCount}
                                        icon={Bell}
                                        href={route('patient-alerts', {
                                            target: user.id,
                                        })}
                                    />
                                    <SummaryCard
                                        title="Farmaci da riordinare"
                                        amount={drugsToRestockCount}
                                        icon={Pill}
                                        href={route('patient-drug-restocks', {
                                            patient: user.id,
                                        })}
                                    />
                                    <SummaryCard
                                        title="Documenti"
                                        amount={documentsCount}
                                        icon={FileText}
                                        href={route('patient-documents', {
                                            patient: user.id,
                                        })}
                                    />
                                </div>
                            </div>
                            <div className="mt-8">
                                <h2 className="mb-4 font-semibold">
                                    Statistiche
                                </h2>
                                <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                    <LineMetricCard
                                        title="Frequenza cardiaca"
                                        resume={lastHeartRateValue}
                                        unit={lastHeartRateFormattedDate}
                                        href={route('heart-rate.detail', {
                                            patient: user.id,
                                        })}
                                        data={heartRatesForChart}
                                    />
                                    <BarMetricCard
                                        title="Qualità del sonno"
                                        resume={formattedAverageSleep}
                                        unit="Media"
                                        href={route('sleep.detail', {
                                            patient: user.id,
                                        })}
                                        data={sleepsForChart}
                                    />
                                    <LineMetricCard
                                        title="Saturazione di ossigeno"
                                        resume={lastOxygenSaturationValue}
                                        unit={lastOxygenSaturationFormattedDate}
                                        href={route(
                                            'oxygen-saturation.detail',
                                            { patient: user.id },
                                        )}
                                        data={oxygenSaturationsForChart}
                                    />
                                    <LineMetricCard
                                        title="Pressione arteriosa"
                                        resume={lastBloodPressureValue ?? '-'}
                                        unit={
                                            lastBloodPressureFormattedDate ??
                                            undefined
                                        }
                                        href={route('blood-pressure.detail', {
                                            patient: user.id,
                                        })}
                                        data={bloodPressuresForChart}
                                    />
                                    <LineMetricCard
                                        title="Holter pressorio"
                                        resume={lastHolterValue ?? '-'}
                                        unit={
                                            lastHolterFormattedDate ?? undefined
                                        }
                                        href={route('holter.detail', {
                                            patient: user.id,
                                        })}
                                        data={holterPressuresForChart}
                                    />
                                    <EcgMetricCard
                                        title="ECG"
                                        resume={
                                            ecg ? `${ecg.heart_rate} bpm` : '-'
                                        }
                                        unit={lastEcgFormattedDate}
                                        href={route('ecg.detail', {
                                            patient: user.id,
                                        })}
                                        data={ecgForChart}
                                    />
                                    <LineMetricCard
                                        title="Temperatura corporea"
                                        resume={
                                            lastTemperatureValue !== null
                                                ? `${lastTemperatureValue} °C`
                                                : '-'
                                        }
                                        unit={
                                            lastTemperatureFormattedDate ??
                                            undefined
                                        }
                                        href={route('temperature.detail', {
                                            patient: user.id,
                                        })}
                                        data={temperaturesForChart}
                                    />
                                    <LineMetricCard
                                        title="Glicemia"
                                        resume={
                                            lastGlucoseValue !== null
                                                ? `${lastGlucoseValue} mg/dL`
                                                : '-'
                                        }
                                        unit={
                                            lastGlucoseFormattedDate ??
                                            undefined
                                        }
                                        href={route('glucose.detail', {
                                            patient: user.id,
                                        })}
                                        data={glucosesForChart}
                                    />
                                    {labMeasures.map((lab) => {
                                        const labDate = lab.last_measured_at
                                            ? new Date(lab.last_measured_at)
                                            : null;
                                        const labTime = labDate
                                            ? `${labDate.getHours().toString().padStart(2, '0')}:${labDate.getMinutes().toString().padStart(2, '0')}`
                                            : undefined;
                                        const labChart = lab.chart.map((m) => ({
                                            date: new Date(
                                                m.date,
                                            ).toLocaleDateString('it', {
                                                weekday: 'long',
                                            }),
                                            average: m.average,
                                            min: m.min,
                                            max: m.max,
                                        }));
                                        return (
                                            <LineMetricCard
                                                key={lab.type}
                                                title={lab.label}
                                                resume={
                                                    lab.last_value !== null
                                                        ? `${lab.last_value.toFixed(lab.decimals)} ${lab.unit}`
                                                        : '-'
                                                }
                                                unit={labTime}
                                                href={route('lab.detail', {
                                                    patient: user.id,
                                                    type: lab.type,
                                                })}
                                                data={labChart}
                                            />
                                        );
                                    })}
                                    <BarMetricCard
                                        title="Attività fisica"
                                        resume={lastActivityValue ?? '-'}
                                        unit={
                                            lastActivityFormattedDate ??
                                            undefined
                                        }
                                        href={route('activity.detail', {
                                            patient: user.id,
                                        })}
                                        data={activitiesForChart}
                                    />
                                    <SpirometryMetricCard
                                        title="Spirometria"
                                        resume={lastSpirometryValue}
                                        unit={lastSpirometryFormattedDate}
                                        href={route('spirometry.detail', {
                                            patient: user.id,
                                        })}
                                        data={spirometryForChart}
                                    />
                                    <LineMetricCard
                                        title="Peso"
                                        resume={lastBodyCompositionValue ?? '-'}
                                        unit={
                                            lastBodyCompositionFormattedDate ??
                                            undefined
                                        }
                                        href={route('body-composition.detail', {
                                            patient: user.id,
                                        })}
                                        data={bodyCompositionForChart}
                                    />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}
