import React, { useMemo, useState } from 'react';
import {
  IonContent,
  IonIcon,
  IonPage,
  useIonViewWillEnter,
} from '@ionic/react';
import { useHistory } from 'react-router-dom';
import {
  chevronForwardOutline,
  ellipsisVertical,
  flashOutline,
  heart,
  notificationsOutline,
  phonePortraitOutline,
  checkmarkCircleOutline,
  timeOutline,
  wifiOutline,
  medkitOutline,
} from 'ionicons/icons';
import sarahImage from '../assets/sarah.jpg';
import momImage from '../assets/mom.jpg';
import dadImage from '../assets/dad.jpg';
import basketIcon from '../assets/basket.png';
import { setStatusBarStyle, Style } from '../utils/statusBar';
import { supabase } from '../supabase';
import { useAuth } from '../contexts/AuthContext';
import DashboardSkeleton from '../components/DashboardSkeleton';
import { formatMoney } from '../utils/formatMoney';
import { buildCacheKey, readCache, writeCache } from '../utils/localCache';
import '../styles/home.css';

type ActivityStatusTone = 'success' | 'warning' | 'info' | 'partial';

type HomeAlert = {
  id: string;
  scheduleId: string;
  recipientId: string;
  serviceType: string;
  title: string;
  subtitle: string;
  icon: string;
  iconType?: 'ion' | 'image';
  tone: 'grocery' | 'medication' | 'airtime' | 'electricity' | 'default';
  cta: string;
};

type HomeRenderableIcon = {
  iconType: 'ion' | 'image';
  icon?: any;
  iconSrc?: string;
  iconAlt?: string;
};

type SupportCategoryTone = 'grocery' | 'medication' | 'airtime' | 'electricity';

const quickActions: Array<
  HomeRenderableIcon & {
    label: string;
    helper: string;
    tone: SupportCategoryTone;
  }
> = [
  {
    label: 'Grocery',
    helper: 'Voucher for partner stores',
    iconType: 'image',
    iconSrc: basketIcon,
    iconAlt: 'Groceries',
    tone: 'grocery',
  },
  {
    label: 'Medication',
    helper: 'Voucher for trusted pharmacies',
    iconType: 'ion',
    icon: medkitOutline,
    tone: 'medication',
  },
  {
    label: 'Airtime & Data',
    helper: 'Top up mobile credit quickly',
    iconType: 'ion',
    icon: wifiOutline,
    tone: 'airtime',
  },
  {
    label: 'Electricity',
    helper: 'Send ZESA meter support',
    iconType: 'ion',
    icon: flashOutline,
    tone: 'electricity',
  },
];

const renderHomeIcon = (item: HomeRenderableIcon) => {
  if (item.iconType === 'image' && item.iconSrc) {
    const isPill = item.iconSrc.includes('pill');
    const isBasket = item.iconSrc.includes('basket');
    return (
      <img
        src={item.iconSrc}
        alt={item.iconAlt ?? ''}
        className={`home-custom-icon ${isPill ? 'is-pill' : ''} ${isBasket ? 'is-basket' : ''}`}
      />
    );
  }

  return item.icon ? <IonIcon icon={item.icon} /> : null;
};

const HomePage: React.FC = () => {
  const history = useHistory();
  const { user, profileStatus } = useAuth();
  const [alerts, setAlerts] = useState<HomeAlert[]>([]);
  const [alertsLoading, setAlertsLoading] = useState(true);
  const [alertsError, setAlertsError] = useState<string | null>(null);
  const [lovedOnes, setLovedOnes] = useState<any[]>([]);
  const [lovedOnesLoading, setLovedOnesLoading] = useState(true);
  const [lovedOnesError, setLovedOnesError] = useState<string | null>(null);
  const [activities, setActivities] = useState<any[]>([]);
  const [activitiesLoading, setActivitiesLoading] = useState(true);
  const [activitiesError, setActivitiesError] = useState<string | null>(null);
  const [monthlySentTotal, setMonthlySentTotal] = useState(0);

  const formatRelativeSupportDate = (value?: string | null) => {
    if (!value) return 'No support yet';

    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return 'Recent support';

    const today = new Date();
    const startOfToday = new Date(
      today.getFullYear(),
      today.getMonth(),
      today.getDate()
    );
    const startOfDate = new Date(
      date.getFullYear(),
      date.getMonth(),
      date.getDate()
    );
    const diffDays = Math.floor(
      (startOfToday.getTime() - startOfDate.getTime()) / 86_400_000
    );

    if (diffDays <= 0) return 'Last support: today';
    if (diffDays === 1) return 'Last support: yesterday';
    if (diffDays < 30) return `Last support: ${diffDays} days ago`;

    return `Last support: ${date.toLocaleDateString(undefined, {
      month: 'short',
      day: 'numeric',
    })}`;
  };

  const getSeededRecipientImage = (
    firstName?: string | null,
    photoPath?: string | null
  ) => {
    const normalizedPath = photoPath?.trim().toLowerCase();
    if (normalizedPath === 'mom.jpg' || normalizedPath === 'mum.jpg') {
      return momImage;
    }
    if (normalizedPath === 'dad.jpg' || normalizedPath === 'father.jpg') {
      return dadImage;
    }

    const normalizedName = firstName?.trim().toLowerCase();
    if (normalizedName === 'mum' || normalizedName === 'mom') return momImage;
    if (normalizedName === 'dad' || normalizedName === 'father') {
      return dadImage;
    }
    return null;
  };

  const getRecipientAvatarUrl = async (
    photoPath?: string | null,
    firstName?: string | null
  ) => {
    const seededImage = getSeededRecipientImage(firstName, photoPath);
    if (seededImage) return seededImage;

    if (photoPath) {
      const { data: urlData } = await supabase.storage
        .from('recipient-photos')
        .createSignedUrl(photoPath, 3600);
      if (urlData?.signedUrl) return urlData.signedUrl;
    }

    return null;
  };

  const formatAlertSubtitle = (firstName: string, dueAt?: string | null) => {
    if (!dueAt) return `For ${firstName}`;

    const date = new Date(dueAt);
    if (Number.isNaN(date.getTime())) return `For ${firstName}`;

    const today = new Date();
    const startOfToday = new Date(
      today.getFullYear(),
      today.getMonth(),
      today.getDate()
    );
    const startOfDate = new Date(
      date.getFullYear(),
      date.getMonth(),
      date.getDate()
    );
    const diffDays = Math.round(
      (startOfDate.getTime() - startOfToday.getTime()) / 86_400_000
    );

    if (diffDays < 0) return `For ${firstName} · overdue`;
    if (diffDays === 0) return `For ${firstName} · today`;
    if (diffDays === 1) return `For ${firstName} · tomorrow`;
    return `For ${firstName} · in ${diffDays} days`;
  };

  const getNormalizedServiceType = (value: string) => {
    const normalized = value.toLowerCase();
    if (normalized.includes('grocery')) return 'grocery';
    if (normalized.includes('medication') || normalized.includes('pharmacy')) {
      return 'medication';
    }
    if (normalized.includes('airtime') || normalized.includes('data')) {
      return 'airtime';
    }
    if (normalized.includes('electricity') || normalized.includes('zesa')) {
      return 'electricity';
    }
    return normalized;
  };

  const getAlertPresentation = (serviceType: string) => {
    switch (serviceType) {
      case 'grocery':
        return {
          title: 'Grocery',
          icon: basketIcon,
          tone: 'grocery' as const,
          cta: 'Send support',
        };
      case 'medication':
        return {
          title: 'Medication',
          icon: medkitOutline,
          tone: 'medication' as const,
          cta: 'Send support',
        };
      case 'airtime':
        return {
          title: 'Airtime',
          icon: phonePortraitOutline,
          tone: 'airtime' as const,
          cta: 'Top up',
        };
      case 'electricity':
        return {
          title: 'Electricity',
          icon: flashOutline,
          tone: 'electricity' as const,
          cta: 'Top up',
        };
      default:
        return {
          title: 'Support',
          icon: timeOutline,
          tone: 'default' as const,
          cta: 'Send support',
        };
    }
  };

  const getActivityStatusTone = (
    serviceType: string,
    status: string
  ): ActivityStatusTone => {
    const normalizedStatus = status.toLowerCase();
    const normalizedService = serviceType.toLowerCase();
    const isVoucherService =
      normalizedService === 'grocery' || normalizedService === 'medication';

    if (isVoucherService) {
      if (normalizedStatus.includes('redeemed')) return 'success';
      if (normalizedStatus.includes('partial')) return 'partial';
      return 'warning';
    }

    if (
      normalizedStatus.includes('completed') ||
      normalizedStatus.includes('active')
    ) {
      return 'success';
    }

    if (
      normalizedStatus.includes('delivered') ||
      normalizedStatus.includes('created') ||
      normalizedStatus === 'ready_for_redemption'
    ) {
      return 'warning';
    }

    return 'info';
  };

  const getActivityStatusLabel = (serviceType: string, status: string) => {
    const normalizedService = serviceType.toLowerCase();
    const normalizedStatus = status.toLowerCase();
    const isVoucherService =
      normalizedService === 'grocery' || normalizedService === 'medication';

    if (isVoucherService) {
      if (normalizedStatus.includes('redeemed')) return 'redeemed';
      if (normalizedStatus.includes('partial')) return 'partial';
      return 'created';
    }

    if (normalizedStatus === 'ready_for_redemption') return 'created';

    return normalizedStatus.replace(/_/g, ' ');
  };

  useIonViewWillEnter(() => {
    setStatusBarStyle(Style.Light);
    loadHomePageData();
  });

  const loadHomePageData = async () => {
    const activeUserId = user?.id ?? '00000000-0000-0000-0000-000000000000';
    const now = new Date();
    const monthStart = new Date(now.getFullYear(), now.getMonth(), 1)
      .toISOString()
      .slice(0, 10);
    const nextMonthStart = new Date(now.getFullYear(), now.getMonth() + 1, 1)
      .toISOString()
      .slice(0, 10);

    let freshMonthlySentTotal = 0;
    let freshAlerts: HomeAlert[] = [];
    let freshLovedOnes: any[] = [];
    let freshActivities: any[] = [];

    const cacheKey = buildCacheKey(activeUserId, 'homeSnapshot');
    let hasCache = false;
    try {
      const cached = await readCache<any>(cacheKey);
      if (
        cached &&
        typeof cached === 'object' &&
        Array.isArray(cached.alerts) &&
        Array.isArray(cached.lovedOnes) &&
        Array.isArray(cached.activities) &&
        typeof cached.monthlySentTotal === 'number'
      ) {
        freshAlerts = cached.alerts;
        freshLovedOnes = cached.lovedOnes.map((person: any) => ({
          ...person,
          statuses: Array.isArray(person.statuses)
            ? person.statuses.slice(0, 3)
            : [],
        }));
        freshActivities = cached.activities;
        freshMonthlySentTotal = cached.monthlySentTotal;

        setAlerts(cached.alerts);
        setLovedOnes(freshLovedOnes);
        setActivities(cached.activities);
        setMonthlySentTotal(cached.monthlySentTotal);
        setAlertsLoading(false);
        setLovedOnesLoading(false);
        setActivitiesLoading(false);
        hasCache = true;
      }
    } catch (err) {
      console.error('[home cache] error reading', err);
    }

    if (!hasCache) {
      setAlertsLoading(true);
      setLovedOnesLoading(true);
      setActivitiesLoading(true);
    }
    setAlertsError(null);
    setLovedOnesError(null);
    setActivitiesError(null);

    const { data: monthlyOrdersData, error: monthlyOrdersError } =
      await supabase
        .from('support_orders')
        .select('amount, created_at')
        .eq('user_id', activeUserId)
        .gte('created_at', monthStart)
        .lt('created_at', nextMonthStart);

    if (monthlyOrdersError) {
      console.error('[home monthly sent]', monthlyOrdersError);
    } else {
      const total = (monthlyOrdersData || []).reduce(
        (sum, order) => sum + Number(order.amount || 0),
        0
      );
      freshMonthlySentTotal = total;
      setMonthlySentTotal(total);
    }

    const { data: alertsData, error: alertsErr } = await supabase
      .from('care_alerts')
      .select('id, title, body, severity, service_type, due_at, recipient_id')
      .eq('user_id', activeUserId)
      .is('dismissed_at', null)
      .order('due_at', { ascending: true, nullsFirst: false })
      .limit(5);

    if (alertsErr) {
      console.error('[home care alerts]', alertsErr);
      setAlertsError('Could not load care alerts');
      setAlerts([]);
    } else if (alertsData) {
      const recipientIds = Array.from(
        new Set(alertsData.map((alert) => alert.recipient_id).filter(Boolean))
      );
      const recipientNameById = new Map<string, string>();

      if (recipientIds.length > 0) {
        const { data: alertRecipients, error: alertRecipientsError } =
          await supabase
            .from('recipients')
            .select('id, first_name')
            .in('id', recipientIds);

        if (alertRecipientsError) {
          console.error('[home care alert recipients]', alertRecipientsError);
        }

        (alertRecipients || []).forEach((recipient) => {
          recipientNameById.set(recipient.id, recipient.first_name);
        });
      }

      freshAlerts = alertsData.map((alert) => {
        const presentation = getAlertPresentation(
          alert.service_type || 'default'
        );
        const firstName =
          recipientNameById.get(alert.recipient_id) || 'Loved one';
        return {
          id: alert.id,
          scheduleId: alert.id,
          recipientId: alert.recipient_id,
          serviceType: alert.service_type || 'support',
          title: presentation.title,
          subtitle: formatAlertSubtitle(firstName, alert.due_at),
          icon: presentation.icon,
          iconType: presentation.icon === basketIcon ? 'image' : 'ion',
          tone: presentation.tone,
          cta: presentation.cta,
        };
      });
      setAlerts(freshAlerts);
    } else {
      freshAlerts = [];
      setAlerts([]);
    }
    setAlertsLoading(false);

    const { data: recipientsData, error: recipientsErr } = await supabase
      .from('recipients')
      .select(
        'id, first_name, last_name, country, city, photo_path, relationship'
      )
      .eq('user_id', activeUserId);

    if (recipientsErr) {
      setLovedOnesError('Could not load loved ones');
    } else if (recipientsData) {
      const mappedLovedOnes = await Promise.all(
        recipientsData.map(async (rec: any) => {
          const avatarUrl = await getRecipientAvatarUrl(
            rec.photo_path,
            rec.first_name
          );
          const { data: recentOrders } = await supabase
            .from('support_orders')
            .select('service_type, status, created_at, merchants(name)')
            .eq('recipient_id', rec.id)
            .eq('user_id', activeUserId)
            .order('created_at', { ascending: false })
            .limit(3);

          const orderedStatuses = [...(recentOrders || [])]
            .sort(
              (a: any, b: any) =>
                new Date(b.created_at).getTime() -
                new Date(a.created_at).getTime()
            )
            .slice(0, 3);
          const primaryOrder = orderedStatuses[0];

          const statuses = orderedStatuses.slice(0, 3).map((order: any) => {
            const tone = getAlertPresentation(order.service_type).tone;
            const isSuccess =
              order.status === 'redeemed' || order.status === 'completed';

            let detail = getActivityStatusLabel(
              order.service_type,
              order.status
            );
            if (order.status === 'redeemed' && order.merchants?.name) {
              detail = `redeemed • ${order.merchants.name}`;
            }

            return {
              iconType: tone === 'grocery' ? 'image' : 'ion',
              iconSrc: tone === 'grocery' ? basketIcon : undefined,
              icon:
                tone !== 'grocery'
                  ? getAlertPresentation(order.service_type).icon
                  : undefined,
              iconAlt: order.service_type,
              label:
                order.service_type === 'grocery'
                  ? 'Grocery voucher'
                  : order.service_type === 'medication'
                    ? 'Medication voucher'
                    : order.service_type === 'electricity'
                      ? 'Electricity'
                      : order.service_type === 'airtime'
                        ? 'Airtime'
                        : `${order.service_type.charAt(0).toUpperCase()}${order.service_type.slice(1)}`,
              detail,
              status: isSuccess ? 'success' : 'warning',
              iconTone: tone,
              serviceType: order.service_type,
            };
          });

          const primaryTone = primaryOrder
            ? getAlertPresentation(primaryOrder.service_type).tone
            : 'grocery';
          const repeatCta =
            primaryOrder?.service_type === 'medication'
              ? 'Send Medication'
              : primaryOrder?.service_type === 'airtime'
                ? 'Top Up Again'
                : primaryOrder?.service_type === 'electricity'
                  ? 'Send Electricity'
                  : 'Send Groceries';

          return {
            id: rec.id,
            name: rec.first_name,
            emoji:
              rec.relationship === 'Mother' || rec.first_name === 'Mum'
                ? '💜'
                : '💚',
            location: `${rec.city || ''}, ${rec.country || ''}`.replace(
              /^, | , $/g,
              ''
            ),
            cardTone: rec.first_name === 'Mum' ? 'lavender' : 'mint',
            avatar: avatarUrl,
            fallbackInitial: rec.first_name?.charAt(0)?.toUpperCase() ?? '?',
            lastSupportLabel: formatRelativeSupportDate(
              primaryOrder?.created_at
            ),
            repeatCta,
            repeatAction: {
              iconType: primaryTone === 'grocery' ? 'image' : 'ion',
              iconSrc: primaryTone === 'grocery' ? basketIcon : undefined,
              icon:
                primaryTone !== 'grocery' && primaryOrder
                  ? getAlertPresentation(primaryOrder.service_type).icon
                  : undefined,
              tone: primaryTone as SupportCategoryTone,
            },
            statuses,
            primaryServiceType: primaryOrder?.service_type ?? 'grocery',
          };
        })
      );
      freshLovedOnes = mappedLovedOnes;
      setLovedOnes(mappedLovedOnes);
    }
    setLovedOnesLoading(false);

    const { data: recentActivityData, error: activityErr } = await supabase
      .from('support_orders')
      .select(
        'id, service_type, status, amount, created_at, recipient_id, merchant_id'
      )
      .eq('user_id', activeUserId)
      .order('created_at', { ascending: false })
      .limit(5);

    if (activityErr) {
      setActivitiesError('Could not load activity');
    } else if (recentActivityData) {
      const activityRecipientIds = Array.from(
        new Set(
          recentActivityData
            .map((activity) => activity.recipient_id)
            .filter(Boolean)
        )
      );
      const activityMerchantIds = Array.from(
        new Set(
          recentActivityData
            .map((activity) => activity.merchant_id)
            .filter(Boolean)
        )
      );
      const recipientsById = new Map<
        string,
        { first_name: string; photo_path: string | null }
      >();
      const merchantsById = new Map<string, string>();

      if (activityRecipientIds.length > 0) {
        const { data: activityRecipients } = await supabase
          .from('recipients')
          .select('id, first_name, photo_path')
          .in('id', activityRecipientIds);

        (activityRecipients || []).forEach((recipient) => {
          recipientsById.set(recipient.id, {
            first_name: recipient.first_name,
            photo_path: recipient.photo_path,
          });
        });
      }

      if (activityMerchantIds.length > 0) {
        const { data: activityMerchants } = await supabase
          .from('merchants')
          .select('id, name')
          .in('id', activityMerchantIds);

        (activityMerchants || []).forEach((merchant) => {
          merchantsById.set(merchant.id, merchant.name);
        });
      }

      const mappedActivity = await Promise.all(
        recentActivityData.map(async (act) => {
          const recipient = recipientsById.get(act.recipient_id);
          const avatarUrl = await getRecipientAvatarUrl(
            recipient?.photo_path,
            recipient?.first_name
          );
          const tone = getAlertPresentation(act.service_type).tone;

          const activityTitle =
            act.service_type === 'grocery'
              ? 'Grocery voucher'
              : act.service_type === 'medication'
                ? 'Medication voucher'
                : act.service_type === 'airtime'
                  ? 'Airtime'
                  : act.service_type === 'data'
                    ? 'Data'
                    : act.service_type === 'electricity'
                      ? 'Electricity'
                      : `${act.service_type.charAt(0).toUpperCase()}${act.service_type.slice(1)}`;

          const normalizedServiceType = getNormalizedServiceType(
            act.service_type
          );
          const statusLabel = getActivityStatusLabel(
            act.service_type,
            act.status
          );
          const merchantName =
            (act.merchant_id && merchantsById.get(act.merchant_id)) || null;
          const isVoucherSupport =
            normalizedServiceType === 'grocery' ||
            normalizedServiceType === 'medication';

          let subtitle = merchantName;
          if (!subtitle) {
            if (isVoucherSupport) {
              subtitle =
                statusLabel === 'redeemed'
                  ? 'Voucher redeemed'
                  : 'Voucher ready for collection';
            } else if (normalizedServiceType === 'electricity') {
              subtitle = 'Meter support sent';
            } else if (normalizedServiceType === 'airtime') {
              subtitle = 'Top-up sent';
            } else {
              subtitle = 'Support sent';
            }
          }

          return {
            id: act.id,
            recipientId: act.recipient_id,
            title: activityTitle,
            subtitle,
            amount: `${Number(act.amount).toFixed(2)}`,
            status: statusLabel,
            tone: getActivityStatusTone(act.service_type, act.status),
            icon: {
              iconType: tone === 'grocery' ? 'image' : 'ion',
              iconSrc: tone === 'grocery' ? basketIcon : undefined,
              icon:
                tone !== 'grocery'
                  ? getAlertPresentation(act.service_type).icon
                  : undefined,
            },
            iconTone: tone,
            avatar: avatarUrl,
            fallbackInitial:
              recipient?.first_name?.charAt(0)?.toUpperCase() ?? '?',
          };
        })
      );
      freshActivities = mappedActivity;
      setActivities(mappedActivity);
    }
    setActivitiesLoading(false);

    // Save cache after all network updates
    void writeCache(cacheKey, {
      monthlySentTotal: freshMonthlySentTotal,
      alerts: freshAlerts,
      lovedOnes: freshLovedOnes,
      activities: freshActivities,
      cachedAt: new Date().toISOString(),
    });
  };

  const handleAlertTap = (alert: HomeAlert) => {
    history.push('/support/new', {
      recipientId: alert.recipientId,
      serviceType: alert.serviceType,
      parentRoot: '/home',
    });
  };

  const handleSupportClick = (serviceType?: SupportCategoryTone) => {
    history.push(
      '/support/new',
      serviceType
        ? { serviceType, parentRoot: '/home' }
        : { parentRoot: '/home' }
    );
  };

  const handleRecipientsClick = () => {
    history.push('/recipients');
  };

  const isPreviewMode = !user;
  const currentMonthLabel = useMemo(
    () =>
      new Intl.DateTimeFormat(undefined, {
        month: 'long',
      }).format(new Date()),
    []
  );
  const monthlySentLabel = useMemo(
    () => formatMoney(monthlySentTotal, 'USD'),
    [monthlySentTotal]
  );
  const showInitialDashboardSkeleton =
    !isPreviewMode &&
    profileStatus === 'loading' &&
    lovedOnesLoading &&
    activitiesLoading &&
    alertsLoading &&
    lovedOnes.length === 0 &&
    activities.length === 0 &&
    alerts.length === 0;

  return (
    <IonPage>
      <IonContent
        fullscreen
        style={{ '--background': 'var(--color-bg)' } as React.CSSProperties}
      >
        {showInitialDashboardSkeleton ? (
          <DashboardSkeleton />
        ) : (
          <div className="home-shell">
            <div className="home-topline">
              <div className="home-topline-left">
                <div className="home-main-avatar-wrap">
                  <img
                    src={sarahImage}
                    alt="Sarah"
                    className="home-main-avatar"
                  />
                </div>
                <div className="home-greeting-block">
                  <h1 className="home-greeting">Hi Sarah 👋</h1>
                </div>
              </div>

              <button
                type="button"
                className="home-notification-card"
                aria-label="Notifications"
                onClick={() =>
                  history.push('/notifications', { parentRoot: '/home' })
                }
              >
                <IonIcon icon={notificationsOutline} />
                <span className="home-dot" />
              </button>
            </div>

            <div className="home-header-actions-row">
              <div className="home-tagline-wrap">
                <p className="home-subcopy">Supporting 2 loved ones ❤️</p>
              </div>
              <div className="home-month-pill">
                <div className="home-month-icon">
                  <IonIcon icon={heart} />
                </div>
                <div className="home-month-copy">
                  <p className="home-month-label">{currentMonthLabel}</p>
                  <p className="home-month-value">{monthlySentLabel}</p>
                </div>
              </div>
            </div>

            {(alertsLoading || alertsError || alerts.length > 0) && (
              <>
                <div className="home-section-row">
                  <h2 className="home-section-heading">Care Alerts</h2>
                </div>

                <div className="home-alert-marquee">
                  {alertsLoading && alerts.length === 0 ? (
                    <div className="home-alert-overlay-state">
                      <div
                        className="home-alert-card home-alert-skeleton"
                        aria-label="Loading care alerts"
                      >
                        <div className="home-alert-icon" />
                        <div className="home-alert-content">
                          <span className="home-alert-skeleton-title" />
                          <span className="home-alert-skeleton-subtitle" />
                          <span className="home-alert-skeleton-cta" />
                        </div>
                      </div>
                    </div>
                  ) : alertsError ? (
                    <div className="home-alert-overlay-state">
                      <p className="home-alert-error">{alertsError}</p>
                    </div>
                  ) : alerts.length > 0 ? (
                    <div className="home-alert-marquee-track">
                      {[...alerts, ...alerts].map((alert, index) => (
                        <button
                          key={`${alert.id}-${index}`}
                          type="button"
                          className="home-alert-card"
                          onClick={() => handleAlertTap(alert)}
                        >
                          <div
                            className={`home-alert-icon home-tone-${alert.tone}`}
                          >
                            {alert.iconType === 'image' ? (
                              <img
                                src={alert.icon as string}
                                alt=""
                                className="home-custom-icon is-basket"
                              />
                            ) : (
                              <IonIcon icon={alert.icon as any} />
                            )}
                          </div>
                          <div className="home-alert-content">
                            <span className="home-alert-title">
                              {alert.title}
                            </span>
                            <span className="home-alert-subtitle">
                              {alert.subtitle}
                            </span>
                          </div>
                          <div
                            className={`home-alert-chevron-chip home-tone-${alert.tone}`}
                          >
                            <IonIcon icon={chevronForwardOutline} />
                          </div>
                        </button>
                      ))}
                    </div>
                  ) : null}
                </div>
              </>
            )}

            <div className="home-section-row home-section-row-spaced">
              <h2 className="home-section-heading">Your Loved Ones</h2>
              <button
                type="button"
                className="home-section-link"
                onClick={handleRecipientsClick}
              >
                View all
              </button>
            </div>

            <div className="home-loved-ones-scroll">
              {lovedOnesLoading && lovedOnes.length === 0 ? (
                <div
                  className="home-person-card home-person-card-lavender"
                  style={{ opacity: 0.5 }}
                >
                  <div className="home-person-header">
                    <div className="home-person-meta">
                      <div className="home-person-avatar-shell"></div>
                      <div>
                        <p className="home-person-name">Loading...</p>
                      </div>
                    </div>
                  </div>
                </div>
              ) : lovedOnesError ? (
                <p className="home-alert-error">{lovedOnesError}</p>
              ) : lovedOnes.length === 0 ? (
                <div
                  className="home-empty-alerts"
                  style={{ margin: '0 20px', width: 'auto' }}
                >
                  <div className="home-empty-alerts-icon">
                    <IonIcon icon={heart} />
                  </div>
                  <h3 className="home-empty-alerts-msg">No loved ones yet</h3>
                  <p className="home-empty-alerts-helper">
                    Add family members to start supporting them.
                  </p>
                  <button
                    className="home-empty-alerts-cta"
                    onClick={handleRecipientsClick}
                  >
                    Add loved one
                  </button>
                </div>
              ) : (
                lovedOnes.map((person) => (
                  <div
                    key={person.id}
                    className={`home-person-card home-person-card-${person.cardTone}`}
                  >
                    <div className="home-person-header">
                      <div className="home-person-meta">
                        <div className="home-person-avatar-shell">
                          {person.avatar ? (
                            <img
                              src={person.avatar}
                              alt={person.name}
                              className="home-person-avatar"
                            />
                          ) : (
                            <span className="home-person-initial">
                              {person.fallbackInitial}
                            </span>
                          )}
                          <span className="home-person-online" />
                        </div>

                        <div>
                          <p className="home-person-name">
                            {person.name} <span>{person.emoji}</span>
                          </p>
                          <p className="home-person-location">
                            {person.lastSupportLabel}
                          </p>
                        </div>
                      </div>

                      <button
                        type="button"
                        className="home-card-menu"
                        aria-label="More options"
                      >
                        <IonIcon icon={ellipsisVertical} />
                      </button>
                    </div>

                    <div className="home-status-stack">
                      {person.statuses.length > 0 ? (
                        person.statuses.slice(0, 3).map((item: any) => {
                          const isSuccess = item.status === 'success';
                          return (
                            <div
                              key={`${person.id}-${item.label}`}
                              className="home-status-row"
                            >
                              <div
                                className={`home-status-icon home-tone-${item.iconTone}`}
                              >
                                {renderHomeIcon(item)}
                              </div>
                              <div className="home-status-copy">
                                <p className="home-status-label">
                                  {item.label}
                                </p>
                                <p
                                  className={`home-status-detail ${isSuccess ? 'is-success' : 'is-warning'}`}
                                >
                                  {item.detail}
                                </p>
                              </div>
                              <IonIcon
                                icon={
                                  isSuccess
                                    ? checkmarkCircleOutline
                                    : timeOutline
                                }
                                className={`home-status-trailing ${isSuccess ? 'is-success' : 'is-warning'}`}
                              />
                            </div>
                          );
                        })
                      ) : (
                        <div className="home-status-empty-row">
                          <IonIcon icon={heart} />
                          <span>No support sent yet</span>
                        </div>
                      )}
                    </div>

                    <button
                      type="button"
                      className={`home-send-button home-tone-${person.repeatAction.tone}`}
                      onClick={() =>
                        history.push('/support/new', {
                          recipientId: person.id,
                          serviceType: person.primaryServiceType,
                          parentRoot: '/home',
                        })
                      }
                    >
                      <span className="home-send-button-icon">
                        {renderHomeIcon(person.repeatAction)}
                      </span>
                      <span>{person.repeatCta}</span>
                    </button>
                  </div>
                ))
              )}
            </div>

            <div className="home-carousel-indicator">
              <span className="home-dot-active" />
              <span className="home-dot-inactive" />
              <span className="home-dot-inactive" />
            </div>

            <div className="home-section-row home-section-row-spaced">
              <h2 className="home-section-heading">Send Support</h2>
            </div>

            <div className="home-action-grid">
              {quickActions.map((action) => (
                <button
                  key={action.label}
                  type="button"
                  className="home-action-card"
                  onClick={() => handleSupportClick(action.tone)}
                >
                  <div className={`home-action-icon home-tone-${action.tone}`}>
                    {renderHomeIcon(action)}
                  </div>
                  <div className="home-action-text-block">
                    <span className="home-action-label">{action.label}</span>
                    <span className="home-action-helper">{action.helper}</span>
                  </div>
                </button>
              ))}
            </div>

            <div className="home-section-row">
              <h2 className="home-section-heading">Family Updates</h2>
              <button
                type="button"
                className="home-section-link"
                onClick={() => history.push('/activity')}
              >
                View all
              </button>
            </div>

            <div className="home-activity-card">
              {activitiesLoading && activities.length === 0 ? (
                <div
                  style={{
                    padding: '20px',
                    textAlign: 'center',
                    color: 'var(--ion-color-medium)',
                  }}
                >
                  Loading activity...
                </div>
              ) : activitiesError ? (
                <div style={{ padding: '20px', textAlign: 'center' }}>
                  <p className="home-alert-error">{activitiesError}</p>
                </div>
              ) : activities.length === 0 ? (
                <div
                  className="home-empty-alerts"
                  style={{ boxShadow: 'none' }}
                >
                  <div
                    className="home-empty-alerts-icon"
                    style={{
                      background: 'rgba(23, 24, 39, 0.04)',
                      color: 'var(--ion-color-medium)',
                    }}
                  >
                    <IonIcon icon={timeOutline} />
                  </div>
                  <h3 className="home-empty-alerts-msg">No recent activity</h3>
                  <p className="home-empty-alerts-helper">
                    Support history will appear here once you send support.
                  </p>
                  <button
                    className="home-empty-alerts-cta"
                    onClick={() => handleSupportClick()}
                  >
                    Send first support
                  </button>
                </div>
              ) : (
                activities.map((activity, index) => (
                  <button
                    key={activity.id}
                    type="button"
                    className={`home-activity-row home-activity-row-button ${
                      index === activities.length - 1 ? 'is-last' : ''
                    }`}
                    onClick={() =>
                      history.push(`/recipients/${activity.recipientId}`)
                    }
                  >
                    <div className="home-activity-avatar-shell">
                      {activity.avatar ? (
                        <img
                          src={activity.avatar}
                          alt=""
                          className="home-activity-avatar"
                        />
                      ) : (
                        <div className="home-activity-avatar home-activity-avatar-fallback">
                          <span>{activity.fallbackInitial}</span>
                        </div>
                      )}
                      <div
                        className={`home-activity-avatar-badge home-tone-${activity.iconTone}`}
                      >
                        {renderHomeIcon(activity.icon)}
                      </div>
                    </div>

                    <div className="home-activity-copy">
                      <div className="home-activity-head-row">
                        <div className="home-activity-text-block">
                          <p className="home-activity-title">
                            {activity.title}
                          </p>
                          <p className="home-activity-subtitle">
                            {activity.subtitle}
                          </p>
                        </div>

                        <div className="home-activity-right">
                          <p className="home-activity-amount">
                            {formatMoney(Number(activity.amount), 'USD')}
                          </p>
                          <div
                            className={`home-activity-badge home-badge-${activity.tone}`}
                          >
                            <span>{activity.status}</span>
                          </div>
                        </div>
                      </div>
                    </div>
                  </button>
                ))
              )}
            </div>
          </div>
        )}
      </IonContent>
    </IonPage>
  );
};

export default HomePage;
