import React, {
  useState,
  useEffect,
  useMemo,
  useCallback,
  useRef,
} from 'react';
import { generateSchedule, generateReminderSchedule } from './utils/schedule';
import { getAppConfig } from './utils/env';
import {
  Medication,
  Dose,
  DoseStatus,
  HistoricalDose,
  User,
  UserSettings,
  TakenDoses,
  CustomReminder,
  ScheduleItem,
  DailyStat,
  MedicationStat,
} from './types';

// Component imports - organized by feature
import {
  AddMedicationModal,
  EditMedicationModal,
  ManageMedicationsModal,
  DoseCard,
} from './components/medication';
import {
  AuthPage,
  AvatarDropdown,
  ChangePasswordModal,
  ResetPasswordPage,
} from './components/auth';
import { AdminInterface } from './components/admin';
import {
  AccountModal,
  AddReminderModal,
  EditReminderModal,
  HistoryModal,
  ManageRemindersModal,
  OnboardingModal,
  StatsModal,
} from './components/modals';
import { ReminderCard, ThemeSwitcher } from './components/ui';

// Icon and utility imports
import {
  PillIcon,
  PlusIcon,
  MenuIcon,
  HistoryIcon,
  SunIcon,
  SunsetIcon,
  MoonIcon,
  SearchIcon,
  SettingsIcon,
  BellIcon,
  BarChartIcon,
} from './components/icons/Icons';
import { useUser } from './contexts/UserContext';
import { databaseService } from './services/database';
import { databaseSeeder } from './services/database.seeder';
import { logger } from './services/logging';
import { normalizeError } from './utils/error';

const Header: React.FC<{
  onAdd: () => void;
  onManage: () => void;
  onManageReminders: () => void;
  onHistory: () => void;
  onStats: () => void;
  onAccount: () => void;
  onAdmin: () => void;
  onChangePassword: () => void;
  user: User;
  onLogout: () => void;
}> = ({
  onAdd,
  onManage,
  onManageReminders,
  onHistory,
  onStats,
  onAccount,
  onAdmin,
  onChangePassword,
  user,
  onLogout,
}) => (
  <header className='bg-white dark:bg-slate-800 shadow-md sticky top-0 z-20 border-b border-slate-200 dark:border-slate-700'>
    <div className='container mx-auto px-4 py-3 flex justify-between items-center'>
      <div className='flex items-center space-x-3'>
        <div className='bg-indigo-600 p-2 rounded-lg'>
          <PillIcon className='w-6 h-6 text-white' />
        </div>
        <h1 className='text-xl md:text-2xl font-bold text-slate-800 dark:text-slate-100'>
          Medication Reminder
        </h1>
      </div>
      <div className='flex items-center space-x-2'>
        <button
          onClick={onStats}
          className='hidden sm:flex items-center space-x-2 px-4 py-2 text-sm font-medium text-slate-700 bg-slate-100 rounded-lg hover:bg-slate-200 transition-colors dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600'
        >
          <BarChartIcon className='w-4 h-4' aria-hidden='true' />
          <span>Stats</span>
        </button>
        <button
          onClick={onHistory}
          className='hidden sm:flex items-center space-x-2 px-4 py-2 text-sm font-medium text-slate-700 bg-slate-100 rounded-lg hover:bg-slate-200 transition-colors dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600'
        >
          <HistoryIcon className='w-4 h-4' aria-hidden='true' />
          <span>History</span>
        </button>
        <button
          onClick={onManage}
          className='hidden sm:flex items-center space-x-2 px-4 py-2 text-sm font-medium text-slate-700 bg-slate-100 rounded-lg hover:bg-slate-200 transition-colors dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600'
        >
          <MenuIcon className='w-4 h-4' aria-hidden='true' />
          <span>{getAppConfig().name}</span>
        </button>
        <button
          onClick={onManageReminders}
          className='flex items-center space-x-2 px-4 py-2 text-sm font-medium text-slate-700 bg-slate-100 rounded-lg hover:bg-slate-200 transition-colors dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600'
        >
          <BellIcon className='w-4 h-4' aria-hidden='true' />
          <span className='hidden sm:inline'>Reminders</span>
        </button>
        <button
          onClick={onAdd}
          className='flex items-center space-x-2 px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-slate-900'
        >
          <PlusIcon className='w-4 h-4' aria-hidden='true' />
          <span className='hidden sm:inline'>Add Med</span>
        </button>
        <div className='border-l border-slate-200 dark:border-slate-600 h-8 mx-2'></div>
        <ThemeSwitcher />
        <button
          onClick={onAccount}
          className='flex items-center justify-center w-10 h-10 rounded-lg bg-slate-100 hover:bg-slate-200 dark:bg-slate-700 dark:hover:bg-slate-600 transition-colors'
          aria-label='Account settings'
        >
          <SettingsIcon className='w-5 h-5 text-slate-700 dark:text-slate-200' />
        </button>
        <div className='border-l border-slate-200 dark:border-slate-600 h-8 ml-2'></div>
        <AvatarDropdown
          user={user}
          onLogout={onLogout}
          onAdmin={onAdmin}
          onChangePassword={onChangePassword}
        />
      </div>
    </div>
  </header>
);

const EmptyState: React.FC<{ onAdd: () => void }> = ({ onAdd }) => (
  <div className='text-center py-20 px-4'>
    <div className='mx-auto bg-slate-200 dark:bg-slate-700 rounded-full h-16 w-16 flex items-center justify-center animate-float'>
      <PillIcon className='w-8 h-8 text-slate-500 dark:text-slate-400' />
    </div>
    <h3 className='mt-4 text-lg font-semibold text-slate-800 dark:text-slate-100'>
      No Medications Scheduled
    </h3>
    <p className='mt-1 text-slate-500 dark:text-slate-400'>
      Get started by adding your first medication.
    </p>
    <div className='mt-6'>
      <button
        type='button'
        onClick={onAdd}
        className='inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-slate-900'
      >
        <PlusIcon className='-ml-1 mr-2 h-5 w-5' />
        Add Medication
      </button>
    </div>
  </div>
);

const groupDetails: {
  [key: string]: {
    icon: React.FC<React.SVGProps<SVGSVGElement>>;
    iconClass: string;
  };
} = {
  Morning: { icon: SunIcon, iconClass: 'text-amber-500' },
  Afternoon: { icon: SunIcon, iconClass: 'text-sky-500' },
  Evening: {
    icon: SunsetIcon,
    iconClass: 'text-indigo-500 dark:text-indigo-400',
  },
  Night: { icon: MoonIcon, iconClass: 'text-slate-500 dark:text-slate-400' },
};

const MedicationScheduleApp: React.FC<{ user: User }> = ({ user }) => {
  const { logout, updateUser } = useUser();

  const [medications, setMedications] = useState<Medication[]>([]);
  const [customReminders, setCustomReminders] = useState<CustomReminder[]>([]);
  const [takenDosesDoc, setTakenDosesDoc] = useState<TakenDoses | null>(null);
  const [settings, setSettings] = useState<UserSettings | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [currentTime, setCurrentTime] = useState(() => new Date());
  const [isAddModalOpen, setAddModalOpen] = useState(false);
  const [isManageModalOpen, setManageModalOpen] = useState(false);
  const [isHistoryModalOpen, setHistoryModalOpen] = useState(false);
  const [isAccountModalOpen, setAccountModalOpen] = useState(false);
  const [isStatsModalOpen, setStatsModalOpen] = useState(false);
  const [editingMedication, setEditingMedication] = useState<Medication | null>(
    null
  );
  const [searchQuery, setSearchQuery] = useState('');
  const [isOnboardingOpen, setOnboardingOpen] = useState(false);
  const [isAdminInterfaceOpen, setAdminInterfaceOpen] = useState(false);
  const [isChangePasswordOpen, setChangePasswordOpen] = useState(false);

  const [isManageRemindersOpen, setManageRemindersOpen] = useState(false);
  const [isAddReminderOpen, setAddReminderOpen] = useState(false);
  const [editingReminder, setEditingReminder] = useState<CustomReminder | null>(
    null
  );
  const [snoozedDoses, setSnoozedDoses] = useState<Record<string, string>>({});

  const notificationTimers = useRef<Record<string, number>>({});

  const takenDoses = useMemo(() => takenDosesDoc?.doses ?? {}, [takenDosesDoc]);

  useEffect(() => {
    // Don't try to fetch data if user._id is not available
    if (!user._id) {
      logger.ui.action('Skipping data fetch because user id is missing', {
        userId: user._id,
      });
      return;
    }

    const fetchData = async () => {
      try {
        setIsLoading(true);
        setError(null);

        logger.db.query('Fetching medication data for user', {
          userId: user._id,
        });

        const [medsData, remindersData, takenDosesData, settingsData] =
          await Promise.all([
            databaseService.getMedications(user._id),
            databaseService.getCustomReminders(user._id),
            databaseService.getTakenDoses(user._id),
            databaseService.getUserSettings(user._id),
          ]);

        logger.db.query('Fetched user data successfully', {
          userId: user._id,
          medicationCount: medsData.length,
          reminderCount: remindersData.length,
          hasTakenDoses: !!takenDosesData,
          hasSettings: !!settingsData,
        });

        setMedications(medsData);
        setCustomReminders(remindersData);
        setTakenDosesDoc(takenDosesData);
        setSettings(settingsData);

        if (!settingsData.hasCompletedOnboarding) {
          setOnboardingOpen(true);
        }
      } catch (e) {
        setError('Failed to load your data. Please try again.');
        logger.db.error('Error loading user data', normalizeError(e), {
          userId: user._id,
        });
      } finally {
        setIsLoading(false);
      }
    };

    // Add a small delay to ensure user state is fully settled
    const timeoutId = setTimeout(() => {
      fetchData();
    }, 100);

    return () => clearTimeout(timeoutId);
  }, [user._id, user]);

  useEffect(() => {
    if (
      settings?.notificationsEnabled &&
      'Notification' in window &&
      Notification.permission === 'default'
    ) {
      Notification.requestPermission();
    }
  }, [settings?.notificationsEnabled]);

  useEffect(() => {
    const timer = setInterval(() => setCurrentTime(new Date()), 60000);
    return () => clearInterval(timer);
  }, []);

  const unifiedSchedule = useMemo(() => {
    const medSchedule = generateSchedule(medications, currentTime);
    const reminderSchedule = generateReminderSchedule(
      customReminders,
      currentTime
    );
    const combined = [...medSchedule, ...reminderSchedule] as ScheduleItem[];
    return combined.sort(
      (a, b) => a.scheduledTime.getTime() - b.scheduledTime.getTime()
    );
  }, [medications, customReminders, currentTime]);

  const handleAddMedication = async (med: Omit<Medication, '_id' | '_rev'>) => {
    const newMed = await databaseService.createMedication(user._id, med);
    setMedications(prev => [...prev, newMed]);
    setAddModalOpen(false);
  };

  const handleDeleteMedication = async (medToDelete: Medication) => {
    await databaseService.deleteMedication(medToDelete._id);
    setMedications(meds => meds.filter(med => med._id !== medToDelete._id));
  };

  const handleUpdateMedication = async (updatedMed: Medication) => {
    const savedMed = await databaseService.updateMedication(updatedMed);
    setMedications(meds =>
      meds.map(m => (m._id === savedMed._id ? savedMed : m))
    );
    setEditingMedication(null);
  };

  const handleAddReminder = async (
    reminder: Omit<CustomReminder, '_id' | '_rev'>
  ) => {
    const newReminder = await databaseService.createCustomReminder(
      user._id,
      reminder
    );
    setCustomReminders(prev => [...prev, newReminder]);
    setAddReminderOpen(false);
  };

  const handleUpdateReminder = async (updatedReminder: CustomReminder) => {
    const savedReminder =
      await databaseService.updateCustomReminder(updatedReminder);
    setCustomReminders(reminders =>
      reminders.map(r => (r._id === savedReminder._id ? savedReminder : r))
    );
    setEditingReminder(null);
  };

  const handleDeleteReminder = async (reminderToDelete: CustomReminder) => {
    await databaseService.deleteCustomReminder(reminderToDelete._id);
    setCustomReminders(reminders =>
      reminders.filter(r => r._id !== reminderToDelete._id)
    );
  };

  const handleOpenEditModal = (med: Medication) => {
    setEditingMedication(med);
    setManageModalOpen(false);
  };

  const handleOpenEditReminderModal = (reminder: CustomReminder) => {
    setEditingReminder(reminder);
    setManageRemindersOpen(false);
  };

  const handleToggleDose = useCallback(
    async (doseId: string) => {
      if (!takenDosesDoc) return;
      const newDoses = { ...takenDosesDoc.doses };
      if (newDoses[doseId]) {
        delete newDoses[doseId];
      } else {
        newDoses[doseId] = new Date().toISOString();
      }
      const updatedDoc = await databaseService.updateTakenDoses({
        ...takenDosesDoc,
        doses: newDoses,
      });
      setTakenDosesDoc(updatedDoc);
    },
    [takenDosesDoc]
  );

  const handleSnoozeDose = useCallback((doseId: string) => {
    const SNOOZE_DURATION = 5 * 60 * 1000; // 5 minutes
    const snoozedUntil = new Date(Date.now() + SNOOZE_DURATION).toISOString();
    setSnoozedDoses(prev => ({ ...prev, [doseId]: snoozedUntil }));

    // Clear existing timer and set a new one
    if (notificationTimers.current[doseId]) {
      clearTimeout(notificationTimers.current[doseId]);
      delete notificationTimers.current[doseId];
    }
  }, []);

  const getDoseStatus = useCallback(
    (dose: Dose, doseTime: Date, now: Date): DoseStatus => {
      if (takenDoses[dose.id]) return DoseStatus.TAKEN;
      if (snoozedDoses[dose.id] && new Date(snoozedDoses[dose.id]) > now)
        return DoseStatus.SNOOZED;
      if (doseTime.getTime() < now.getTime()) return DoseStatus.MISSED;
      return DoseStatus.UPCOMING;
    },
    [takenDoses, snoozedDoses]
  );

  const scheduleWithStatus = useMemo(() => {
    return unifiedSchedule
      .map(item => {
        if ('medicationId' in item) {
          // It's a Dose
          const medication = medications.find(m => m._id === item.medicationId);
          if (!medication) return null;

          return {
            ...item,
            type: 'dose' as const,
            medication,
            status: getDoseStatus(item, item.scheduledTime, currentTime),
            takenAt: takenDoses[item.id],
            snoozedUntil: snoozedDoses[item.id]
              ? new Date(snoozedDoses[item.id])
              : undefined,
          };
        } else {
          // It's a Custom Reminder
          return {
            ...item,
            type: 'reminder' as const,
          };
        }
      })
      .filter((d): d is NonNullable<typeof d> => d !== null);
  }, [
    unifiedSchedule,
    medications,
    getDoseStatus,
    currentTime,
    takenDoses,
    snoozedDoses,
  ]);

  useEffect(() => {
    if (
      !settings?.notificationsEnabled ||
      !('Notification' in window) ||
      Notification.permission !== 'granted'
    ) {
      return;
    }

    const now = new Date();
    const activeTimers = notificationTimers.current;

    scheduleWithStatus.forEach(item => {
      const itemId = item.id;
      if (activeTimers[itemId]) return; // Timer already set

      let timeToNotification = -1;
      let notificationBody = '';
      let notificationTitle = '';

      if (item.type === 'dose' && item.status === DoseStatus.UPCOMING) {
        timeToNotification = item.scheduledTime.getTime() - now.getTime();
        notificationTitle = 'Time for your medication!';
        notificationBody = `${item.medication.name} (${item.medication.dosage})`;
      } else if (
        item.type === 'dose' &&
        item.status === DoseStatus.SNOOZED &&
        item.snoozedUntil
      ) {
        timeToNotification = item.snoozedUntil.getTime() - now.getTime();
        notificationTitle = 'Snoozed Medication Reminder';
        notificationBody = `${item.medication.name} (${item.medication.dosage})`;
      } else if (item.type === 'reminder' && item.scheduledTime > now) {
        timeToNotification = item.scheduledTime.getTime() - now.getTime();
        notificationTitle = 'Reminder';
        notificationBody = item.title;
      }

      if (timeToNotification > 0) {
        activeTimers[itemId] = setTimeout(() => {
          new Notification(notificationTitle, {
            body: notificationBody,
            tag: itemId,
          });
          if (item.type === 'dose' && item.status === DoseStatus.SNOOZED) {
            setSnoozedDoses(prev => {
              const newSnoozed = { ...prev };
              delete newSnoozed[itemId];
              return newSnoozed;
            });
          }
          delete activeTimers[itemId];
        }, timeToNotification) as unknown as number;
      }
    });

    return () => Object.values(activeTimers).forEach(clearTimeout);
  }, [scheduleWithStatus, settings?.notificationsEnabled]);

  const filteredSchedule = useMemo(
    () =>
      scheduleWithStatus.filter(item => {
        if (item.type === 'reminder') {
          return item.title.toLowerCase().includes(searchQuery.toLowerCase());
        }
        return item.medication.name
          .toLowerCase()
          .includes(searchQuery.toLowerCase());
      }),
    [scheduleWithStatus, searchQuery]
  );

  const groupedSchedule = useMemo(() => {
    const groups: { [key: string]: typeof filteredSchedule } = {
      Morning: [],
      Afternoon: [],
      Evening: [],
      Night: [],
    };
    filteredSchedule.forEach(item => {
      const hour = item.scheduledTime.getHours();
      if (hour >= 5 && hour < 12) groups['Morning'].push(item);
      else if (hour >= 12 && hour < 17) groups['Afternoon'].push(item);
      else if (hour >= 17 && hour < 21) groups['Evening'].push(item);
      else groups['Night'].push(item);
    });
    return groups;
  }, [filteredSchedule]);

  const medicationHistory = useMemo(() => {
    const history: { date: string; doses: HistoricalDose[] }[] = [];
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const now = new Date();
    for (let i = 0; i < 7; i++) {
      const date = new Date(today);
      date.setDate(date.getDate() - i);
      const daySchedule = generateSchedule(medications, date);
      if (daySchedule.length === 0 || date.getTime() > now.getTime()) continue;
      const dosesForDay: HistoricalDose[] = daySchedule
        .map(dose => {
          const medication = medications.find(m => m._id === dose.medicationId);
          return medication
            ? {
                id: dose.id,
                medication,
                scheduledTime: dose.scheduledTime,
                status: getDoseStatus(dose, dose.scheduledTime, now),
                takenAt: takenDoses[dose.id],
              }
            : null;
        })
        .filter((d): d is NonNullable<typeof d> => d !== null);
      if (dosesForDay.length > 0)
        history.push({
          date: date.toISOString().split('T')[0],
          doses: dosesForDay,
        });
    }
    return history;
  }, [medications, takenDoses, getDoseStatus]);

  const { dailyStats, medicationStats } = useMemo(() => {
    const today = new Date();
    today.setHours(23, 59, 59, 999);
    const now = new Date();

    const daily: DailyStat[] = [];
    for (let i = 6; i >= 0; i--) {
      const date = new Date();
      date.setHours(0, 0, 0, 0);
      date.setDate(date.getDate() - i);

      const daySchedule = generateSchedule(medications, date);
      const pastDoses = daySchedule.filter(d => d.scheduledTime < now);

      if (pastDoses.length === 0) {
        daily.push({ date: date.toISOString().split('T')[0], adherence: 100 });
        continue;
      }

      let takenCount = 0;
      pastDoses.forEach(dose => {
        if (takenDoses[dose.id]) {
          takenCount++;
        }
      });

      const adherence = (takenCount / pastDoses.length) * 100;
      daily.push({
        date: date.toISOString().split('T')[0],
        adherence: Math.round(adherence),
      });
    }

    const statsByMedId: Record<
      string,
      {
        taken: number;
        missed: number;
        upcoming: number;
        medication: Medication;
        lastTakenAt?: string;
      }
    > = {};
    medications.forEach(med => {
      statsByMedId[med._id] = {
        taken: 0,
        missed: 0,
        upcoming: 0,
        medication: med,
      };
    });

    const sevenDaysAgo = new Date();
    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

    medications.forEach(med => {
      for (let i = 0; i < 7; i++) {
        const date = new Date();
        date.setDate(date.getDate() - i);
        const daySchedule = generateSchedule([med], date);

        daySchedule.forEach(dose => {
          const stat = statsByMedId[dose.medicationId];
          if (stat) {
            const status = getDoseStatus(dose, dose.scheduledTime, now);
            if (status === DoseStatus.TAKEN) {
              stat.taken++;
              const takenAt = takenDoses[dose.id];
              if (
                takenAt &&
                (!stat.lastTakenAt ||
                  new Date(takenAt) > new Date(stat.lastTakenAt))
              ) {
                stat.lastTakenAt = takenAt;
              }
            } else if (status === DoseStatus.MISSED) stat.missed++;
            else if (status === DoseStatus.UPCOMING) stat.upcoming++;
          }
        });
      }
    });

    const medication: MedicationStat[] = Object.values(statsByMedId)
      .map(stat => {
        const totalPast = stat.taken + stat.missed;
        const adherence =
          totalPast > 0 ? Math.round((stat.taken / totalPast) * 100) : 100;
        return { ...stat, adherence };
      })
      .sort((a, b) => a.medication.name.localeCompare(b.medication.name));

    return { dailyStats: daily, medicationStats: medication };
  }, [medications, takenDoses, getDoseStatus]);

  const handleUpdateSettings = async (newSettings: UserSettings) => {
    const updatedSettings =
      await databaseService.updateUserSettings(newSettings);
    setSettings(updatedSettings);
  };

  const handleDeleteAllData = async () => {
    if (
      window.confirm(
        'Are you sure you want to delete all your medication data? This action cannot be undone.'
      )
    ) {
      await databaseService.deleteAllUserData(user._id);
      setMedications([]);
      setCustomReminders([]);
      const updatedTakenDoses = await databaseService.getTakenDoses(user._id);
      setTakenDosesDoc(updatedTakenDoses);
      setAccountModalOpen(false);
    }
  };

  const handleCompleteOnboarding = async () => {
    if (settings) {
      try {
        const updatedSettings = await databaseService.updateUserSettings({
          ...settings,
          hasCompletedOnboarding: true,
        });
        setSettings(updatedSettings);
        setOnboardingOpen(false);
      } catch (error) {
        logger.ui.error(
          'Failed to update onboarding status',
          normalizeError(error),
          { userId: user._id }
        );
        setOnboardingOpen(false);
      }
    }
  };

  if (isLoading) {
    return (
      <div className='min-h-screen flex items-center justify-center'>
        <PillIcon className='w-12 h-12 text-indigo-500 animate-spin' />
      </div>
    );
  }

  if (error) {
    return (
      <div className='min-h-screen flex items-center justify-center text-red-500'>
        {error}
      </div>
    );
  }

  return (
    <div className='min-h-screen text-slate-800 dark:text-slate-200'>
      <Header
        onAdd={() => setAddModalOpen(true)}
        onManage={() => setManageModalOpen(true)}
        onManageReminders={() => setManageRemindersOpen(true)}
        onHistory={() => setHistoryModalOpen(true)}
        onStats={() => setStatsModalOpen(true)}
        onAccount={() => setAccountModalOpen(true)}
        onAdmin={() => setAdminInterfaceOpen(true)}
        onChangePassword={() => setChangePasswordOpen(true)}
        user={user}
        onLogout={logout}
      />

      <main className='container mx-auto p-4 md:p-6'>
        <div className='flex items-center justify-between mb-6'>
          <h2 className='text-2xl font-bold dark:text-slate-100'>
            Today's Schedule
          </h2>
          <time className='font-medium text-slate-500 dark:text-slate-400'>
            {currentTime.toLocaleDateString(undefined, {
              weekday: 'long',
              month: 'long',
              day: 'numeric',
            })}
          </time>
        </div>

        {medications.length > 0 || customReminders.length > 0 ? (
          <>
            <div className='relative mb-6'>
              <div className='pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3'>
                <SearchIcon
                  className='h-5 w-5 text-slate-400'
                  aria-hidden='true'
                />
              </div>
              <input
                type='search'
                name='search'
                id='search'
                className='block w-full pl-10 pr-4 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
                placeholder='Search schedule...'
                value={searchQuery}
                onChange={e => setSearchQuery(e.target.value)}
              />
            </div>
            {filteredSchedule.length > 0 ? (
              <div className='space-y-8'>
                {Object.entries(groupedSchedule).map(([groupName, items]) => {
                  const scheduleItems = items as typeof filteredSchedule;
                  if (scheduleItems.length === 0) return null;
                  const Icon = groupDetails[groupName]?.icon;
                  return (
                    <section key={groupName}>
                      <div className='flex items-center space-x-3 mb-3 pb-2 border-b border-slate-200 dark:border-slate-700'>
                        {Icon && (
                          <Icon
                            className={`w-6 h-6 ${groupDetails[groupName].iconClass}`}
                            aria-hidden='true'
                          />
                        )}
                        <h3 className='text-lg font-semibold text-slate-600 dark:text-slate-300'>
                          {groupName}
                        </h3>
                      </div>
                      <ul className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
                        {scheduleItems.map(item =>
                          item.type === 'dose' ? (
                            <DoseCard
                              key={item.id}
                              dose={item}
                              medication={item.medication}
                              status={item.status}
                              onToggleDose={handleToggleDose}
                              onSnooze={handleSnoozeDose}
                              snoozedUntil={item.snoozedUntil}
                            />
                          ) : (
                            <ReminderCard key={item.id} reminder={item} />
                          )
                        )}
                      </ul>
                    </section>
                  );
                })}
              </div>
            ) : (
              <div className='text-center py-10 px-4'>
                <SearchIcon className='mx-auto h-12 w-12 text-slate-400' />
                <h3 className='mt-2 text-sm font-semibold text-slate-900 dark:text-slate-100'>
                  No items found
                </h3>
                <p className='mt-1 text-sm text-slate-500 dark:text-slate-400'>
                  Your search for "{searchQuery}" did not match any items
                  scheduled for today.
                </p>
              </div>
            )}
          </>
        ) : (
          <EmptyState onAdd={() => setAddModalOpen(true)} />
        )}
      </main>

      <AddMedicationModal
        isOpen={isAddModalOpen}
        onClose={() => setAddModalOpen(false)}
        onAdd={handleAddMedication}
      />
      <ManageMedicationsModal
        isOpen={isManageModalOpen}
        onClose={() => setManageModalOpen(false)}
        medications={medications}
        onDelete={handleDeleteMedication}
        onEdit={handleOpenEditModal}
      />
      <EditMedicationModal
        isOpen={editingMedication !== null}
        onClose={() => setEditingMedication(null)}
        medication={editingMedication}
        onUpdate={handleUpdateMedication}
      />
      <HistoryModal
        isOpen={isHistoryModalOpen}
        onClose={() => setHistoryModalOpen(false)}
        history={medicationHistory}
      />
      <StatsModal
        isOpen={isStatsModalOpen}
        onClose={() => setStatsModalOpen(false)}
        dailyStats={dailyStats}
        medicationStats={medicationStats}
      />
      {settings && (
        <AccountModal
          isOpen={isAccountModalOpen}
          onClose={() => setAccountModalOpen(false)}
          user={user}
          settings={settings}
          onUpdateUser={updateUser}
          onUpdateSettings={handleUpdateSettings}
          onDeleteAllData={handleDeleteAllData}
        />
      )}
      <OnboardingModal
        isOpen={isOnboardingOpen}
        onComplete={handleCompleteOnboarding}
      />

      <ManageRemindersModal
        isOpen={isManageRemindersOpen}
        onClose={() => setManageRemindersOpen(false)}
        reminders={customReminders}
        onAdd={() => {
          setManageRemindersOpen(false);
          setAddReminderOpen(true);
        }}
        onEdit={handleOpenEditReminderModal}
        onDelete={handleDeleteReminder}
      />
      <AddReminderModal
        isOpen={isAddReminderOpen}
        onClose={() => setAddReminderOpen(false)}
        onAdd={handleAddReminder}
      />
      <EditReminderModal
        isOpen={editingReminder !== null}
        onClose={() => setEditingReminder(null)}
        reminder={editingReminder}
        onUpdate={handleUpdateReminder}
      />

      {/* Admin Interface - Only shown when opened */}
      {isAdminInterfaceOpen && (
        <AdminInterface onClose={() => setAdminInterfaceOpen(false)} />
      )}

      {/* Password Change Modal - Only shown when opened */}
      {isChangePasswordOpen && (
        <ChangePasswordModal
          onClose={() => setChangePasswordOpen(false)}
          onSuccess={() => {
            alert('Password changed successfully!');
            setChangePasswordOpen(false);
          }}
        />
      )}
    </div>
  );
};

const App: React.FC = () => {
  const { user, isLoading } = useUser();

  // Run database seeding on app startup
  useEffect(() => {
    const runSeeding = async () => {
      try {
        logger.db.query('Initializing database seeding');
        await databaseSeeder.seedDatabase();
      } catch (error) {
        logger.db.error('Database seeding failed', normalizeError(error));
      }
    };

    runSeeding();
  }, []);

  if (isLoading) {
    return (
      <div className='min-h-screen flex items-center justify-center bg-slate-50 dark:bg-slate-900'>
        <PillIcon className='w-12 h-12 text-indigo-500 animate-spin' />
      </div>
    );
  }

  if (!user) {
    if (
      typeof window !== 'undefined' &&
      window.location.pathname === '/reset-password'
    ) {
      return <ResetPasswordPage />;
    }
    return <AuthPage />;
  }

  return <MedicationScheduleApp user={user} />;
};

export default App;
