'use client';

import { useEffect, useState, useMemo } from 'react';
import { useRouter } from 'next/navigation';
import api from '@/lib/api';
import { PlusIcon, CheckIcon, PillIcon, ClockIcon, TrashIcon } from '@/components/ui/Icons';
import Link from 'next/link';
import PushNotificationToggle from '@/components/notifications/PushNotificationToggle';

interface Medication {
  id: string;
  name: string;
  dosage: string;
  unit: string;
  frequency: string;
  times: string[];
  days_of_week?: string[];
  interval_days?: number;
  start_date?: string;
  next_dose_date?: string;
  notes?: string;
  active: boolean;
  quantity_remaining?: number;
}

interface TodaysMedication {
  medication: {
    id: string;
    name: string;
    dosage: string;
    unit: string;
  };
  scheduled_times: string[];
  taken_times: string[];
  skipped_times?: string[];
  is_prn?: boolean;
  is_next_day?: boolean;
  is_previous_day?: boolean;
}

interface AdherenceEntry {
  medication_id: string;
  name: string;
  adherence_percent: number | null;
  is_prn?: boolean;
}

type TimeStatus = 'overdue' | 'due_now' | 'upcoming' | 'taken' | 'skipped';

function getTimeStatus(scheduledTime: string, takenTimes: string[], skippedTimes: string[], now: Date): TimeStatus {
  if (takenTimes.includes(scheduledTime)) return 'taken';
  if (skippedTimes.includes(scheduledTime)) return 'skipped';

  const [h, m] = scheduledTime.split(':').map(Number);
  const scheduled = new Date(now);
  scheduled.setHours(h, m, 0, 0);

  const diffMs = now.getTime() - scheduled.getTime();
  const diffMin = diffMs / 60000;

  if (diffMin > 15) return 'overdue';
  if (diffMin >= -15) return 'due_now';
  return 'upcoming';
}

const formatSchedule = (med: Medication): string => {
  if (med.frequency === 'specific_days' && med.days_of_week?.length) {
    return med.days_of_week.map(d => d.charAt(0).toUpperCase() + d.slice(1)).join(', ');
  }
  if (med.frequency === 'every_n_days' && med.interval_days) {
    return `Every ${med.interval_days} days`;
  }
  if (med.frequency === 'as_needed') return 'As needed';
  const timesCount = med.times?.length || 0;
  if (med.frequency === 'twice_daily' || timesCount === 2) return 'Twice daily';
  if (timesCount >= 3) return `${timesCount}x daily`;
  return 'Daily';
};

interface DueEntry {
  item: TodaysMedication;
  time: string;
  status: TimeStatus;
}

export default function MedicationsPage() {
  const router = useRouter();
  const [medications, setMedications] = useState<Medication[]>([]);
  const [todayMeds, setTodayMeds] = useState<TodaysMedication[]>([]);
  const [adherence, setAdherence] = useState<AdherenceEntry[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [tick, setTick] = useState(0);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const [medsData, todayData, adherenceData] = await Promise.all([
          api.medications.list(),
          api.medications.getToday().catch(() => []),
          api.medications.getAdherence(30).catch(() => []),
        ]);
        setMedications(medsData);
        setTodayMeds(todayData);
        setAdherence(adherenceData);
      } catch (err) {
        console.error('Failed to fetch medications:', err);
      } finally {
        setIsLoading(false);
      }
    };
    fetchData();
  }, []);

  // Auto-refresh grouping every 60s
  useEffect(() => {
    const interval = setInterval(() => setTick(t => t + 1), 60000);
    return () => clearInterval(interval);
  }, []);

  const { dueEntries, upcomingEntries, prnEntries } = useMemo(() => {
    const now = new Date();
    const due: DueEntry[] = [];
    const upcoming: DueEntry[] = [];
    const prn: TodaysMedication[] = [];

    for (const item of todayMeds) {
      if (item.is_prn) {
        prn.push(item);
        continue;
      }

      // Next-day meds are always upcoming
      if (item.is_next_day) {
        for (const time of item.scheduled_times) {
          upcoming.push({ item, time, status: 'upcoming' });
        }
        continue;
      }

      for (const time of item.scheduled_times) {
        const status = getTimeStatus(time, item.taken_times, item.skipped_times || [], now);
        if (status === 'upcoming') {
          upcoming.push({ item, time, status });
        } else {
          due.push({ item, time, status });
        }
      }
    }

    // Sort due: overdue first, then due_now, then by time
    const statusOrder: Record<TimeStatus, number> = { overdue: 0, due_now: 1, taken: 2, skipped: 3, upcoming: 4 };
    due.sort((a, b) => statusOrder[a.status] - statusOrder[b.status] || a.time.localeCompare(b.time));
    upcoming.sort((a, b) => a.time.localeCompare(b.time));

    return { dueEntries: due, upcomingEntries: upcoming, prnEntries: prn };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [todayMeds, tick]);

  const [error, setError] = useState<string | null>(null);

  const handleTake = async (medId: string, time?: string) => {
    try {
      setError(null);
      await api.medications.take(medId, time);
      window.location.reload();
    } catch (err) {
      console.error('Failed to log medication:', err);
      setError(err instanceof Error ? err.message : 'Failed to log medication');
    }
  };

  const handleSkip = async (medId: string, time?: string) => {
    try {
      setError(null);
      await api.medications.skip(medId, time);
      window.location.reload();
    } catch (err) {
      console.error('Failed to skip medication:', err);
      setError(err instanceof Error ? err.message : 'Failed to skip medication');
    }
  };

  const handleDelete = async (medId: string) => {
    try {
      await api.medications.delete(medId);
      setMedications(medications.filter(m => m.id !== medId));
    } catch (err) {
      console.error('Failed to delete medication:', err);
    }
  };

  const getAdherenceForMed = (medId: string) => {
    const entry = adherence.find(a => a.medication_id === medId);
    if (!entry) return { percent: 0, isPrn: false };
    return { percent: entry.adherence_percent, isPrn: entry.is_prn || false };
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center min-h-[50vh]">
        <div className="w-8 h-8 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
      </div>
    );
  }

  const borderColor = (status: TimeStatus) => {
    if (status === 'overdue') return 'border-l-4 border-l-red-500';
    if (status === 'due_now') return 'border-l-4 border-l-amber-500';
    if (status === 'taken') return 'border-l-4 border-l-green-500';
    if (status === 'skipped') return 'border-l-4 border-l-gray-400';
    return '';
  };

  return (
    <div className="p-4 space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">Medications</h1>
        <Link href="/dashboard/medications/new" className="bg-indigo-600 text-white p-2 rounded-full">
          <PlusIcon size={24} />
        </Link>
      </div>

      {/* Push Notification Toggle */}
      <PushNotificationToggle />

      {error && (
        <div className="bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-700 dark:text-red-400 px-4 py-3 rounded-lg">
          {error}
        </div>
      )}

      {/* Due Now Section */}
      {dueEntries.length > 0 && (
        <div>
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Due</h2>
          <div className="space-y-3">
            {dueEntries.map((entry) => (
              <div
                key={`${entry.item.medication.id}-${entry.time}`}
                className={`bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm ${borderColor(entry.status)}`}
              >
                <div className="flex items-center justify-between mb-2">
                  <div>
                    <div className="flex items-center gap-2">
                      <h3 className="font-semibold text-gray-900 dark:text-gray-100">{entry.item.medication.name}</h3>
                      {entry.item.is_previous_day && (
                        <span className="text-xs bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-400 px-2 py-0.5 rounded">Yesterday</span>
                      )}
                    </div>
                    <p className="text-sm text-gray-500 dark:text-gray-400">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
                  </div>
                </div>
                <div className="flex items-center justify-between bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
                  <div className="flex items-center gap-2">
                    <ClockIcon size={16} className="text-gray-500 dark:text-gray-400" />
                    <span className="font-medium text-gray-900 dark:text-gray-100">{entry.time}</span>
                    {entry.status === 'overdue' && (
                      <span className="text-xs text-red-600 dark:text-red-400 font-medium">Overdue</span>
                    )}
                  </div>
                  {entry.status === 'taken' ? (
                    <span className="text-green-600 dark:text-green-400 font-medium flex items-center gap-1">
                      <CheckIcon size={16} /> Taken
                    </span>
                  ) : entry.status === 'skipped' ? (
                    <span className="text-gray-400 dark:text-gray-500 font-medium">Skipped</span>
                  ) : (
                    <div className="flex gap-2">
                      <button
                        onClick={() => handleTake(entry.item.medication.id, entry.time)}
                        className="bg-green-600 text-white px-3 py-1 rounded-lg text-sm font-medium"
                      >
                        Take
                      </button>
                      <button
                        onClick={() => handleSkip(entry.item.medication.id, entry.time)}
                        className="text-gray-500 dark:text-gray-400 px-2 py-1"
                      >
                        Skip
                      </button>
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* PRN Section */}
      {prnEntries.length > 0 && (
        <div>
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">As Needed</h2>
          <div className="space-y-3">
            {prnEntries.map((item) => (
              <div key={item.medication.id} className="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm">
                <div className="flex items-center justify-between mb-2">
                  <div>
                    <h3 className="font-semibold text-gray-900 dark:text-gray-100">{item.medication.name}</h3>
                    <p className="text-sm text-gray-500 dark:text-gray-400">{item.medication.dosage} {item.medication.unit}</p>
                  </div>
                </div>
                <div className="flex items-center justify-between bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
                  <span className="text-gray-500 dark:text-gray-400 text-sm">As needed</span>
                  <button
                    onClick={() => handleTake(item.medication.id)}
                    className="bg-green-600 text-white px-3 py-1 rounded-lg text-sm font-medium"
                  >
                    Log Dose
                  </button>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Upcoming Section */}
      {upcomingEntries.length > 0 && (
        <div>
          <h2 className="text-lg font-semibold text-gray-500 dark:text-gray-400 mb-3">Upcoming</h2>
          <div className="space-y-3">
            {upcomingEntries.map((entry) => (
              <div
                key={`${entry.item.medication.id}-${entry.time}`}
                className="bg-gray-50 dark:bg-gray-800 rounded-xl p-4 shadow-sm opacity-75"
              >
                <div className="flex items-center justify-between">
                  <div>
                    <div className="flex items-center gap-2">
                      <h3 className="font-medium text-gray-700 dark:text-gray-300">{entry.item.medication.name}</h3>
                      {entry.item.is_next_day && (
                        <span className="text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400 px-2 py-0.5 rounded">Tomorrow</span>
                      )}
                    </div>
                    <p className="text-sm text-gray-400 dark:text-gray-500">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
                  </div>
                  <div className="flex items-center gap-2 text-gray-400 dark:text-gray-500">
                    <ClockIcon size={16} />
                    <span className="font-medium">{entry.time}</span>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* All Medications */}
      <div>
        <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">All Medications</h2>

        {medications.length === 0 ? (
          <div className="bg-white dark:bg-gray-800 rounded-xl p-8 shadow-sm text-center">
            <div className="w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
              <PillIcon className="text-gray-400 dark:text-gray-500" size={32} />
            </div>
            <h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-1">No medications yet</h3>
            <p className="text-gray-500 dark:text-gray-400 text-sm mb-4">Add your medications to track them</p>
            <Link href="/dashboard/medications/new" className="inline-block bg-indigo-600 text-white px-4 py-2 rounded-lg font-medium">
              Add Medication
            </Link>
          </div>
        ) : (
          <div className="space-y-3">
            {medications.map((med) => {
              const { percent: adherencePercent, isPrn } = getAdherenceForMed(med.id);
              return (
                <div key={med.id} className="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm">
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <div className="flex items-center gap-2">
                        <h3 className="font-semibold text-gray-900 dark:text-gray-100">{med.name}</h3>
                        {!med.active && (
                          <span className="text-xs bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 px-2 py-0.5 rounded">Inactive</span>
                        )}
                      </div>
                      <p className="text-gray-500 dark:text-gray-400 text-sm">{med.dosage} {med.unit} &middot; {formatSchedule(med)}</p>
                      {med.times.length > 0 && (
                        <p className="text-gray-400 dark:text-gray-500 text-sm mt-1">Times: {med.times.join(', ')}</p>
                      )}
                    </div>
                    <button
                      onClick={() => handleDelete(med.id)}
                      className="text-red-500 dark:text-red-400 p-2"
                    >
                      <TrashIcon size={18} />
                    </button>
                  </div>

                  {/* Adherence */}
                  <div className="mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
                    {isPrn || adherencePercent === null ? (
                      <span className="text-sm text-gray-400 dark:text-gray-500">PRN &mdash; no adherence tracking</span>
                    ) : (
                      <>
                        <div className="flex items-center justify-between mb-1">
                          <span className="text-sm text-gray-500 dark:text-gray-400">30-day adherence</span>
                          <span className={`font-semibold ${adherencePercent >= 80 ? 'text-green-600 dark:text-green-400' : adherencePercent >= 50 ? 'text-yellow-600 dark:text-yellow-400' : 'text-red-600 dark:text-red-400'}`}>
                            {adherencePercent}%
                          </span>
                        </div>
                        <div className="h-2 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
                          <div
                            className={`h-full ${adherencePercent >= 80 ? 'bg-green-500' : adherencePercent >= 50 ? 'bg-yellow-500' : 'bg-red-500'}`}
                            style={{ width: `${adherencePercent}%` }}
                          />
                        </div>
                      </>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}
