import { useMemo, useState } from 'react';

import { useCommunicationEvents } from '@/business/communications/hooks';
import { filterCommunicationEventsByRole } from '@/business/communications/selectors';
import { useContentCatalogPayload } from '@/business/content-catalog/hooks';
import {
  getDashboardGreeting,
  selectDashboardActiveZone,
  selectDashboardQuickActions,
  selectDashboardQuote,
  selectDashboardUpcomingEvents,
} from '@/business/dashboard/selectors';
import type {
  DashboardPage,
  DashboardProps,
} from '@/business/dashboard/types';
import { useFrameEntries } from '@/business/frame/hooks';
import { useZoneCheckIn } from '@/business/user-progress/hooks';
import { CONTENT_CATALOG_TYPES } from '@/shared/constants/contentCatalog';
import { DASHBOARD_ZONE_OPTIONS } from '@/shared/constants/dashboard';
import { getOptionalErrorMessage } from '@/shared/errors/errorMessages';
import type { ZoneColor } from '@/shared/types/app';
import type {
  DashboardComplianceItem,
  DashboardEncouragingQuote,
  DashboardSignOfWeek,
} from '@/shared/types/dashboard';

export function useDashboardPage({
  userRole,
  userName,
  setCurrentModule,
  zoneCheckIn,
  setZoneCheckIn,
}: DashboardProps): DashboardPage {
  const [dashboardDate] = useState(() => new Date());
  const quotesQuery = useContentCatalogPayload<readonly DashboardEncouragingQuote[]>(
    CONTENT_CATALOG_TYPES.dashboardEncouragingQuotes,
    [],
  );
  const complianceItemsQuery = useContentCatalogPayload<readonly DashboardComplianceItem[]>(
    CONTENT_CATALOG_TYPES.dashboardComplianceItems,
    [],
  );
  const signOfWeekQuery = useContentCatalogPayload<DashboardSignOfWeek | null>(
    CONTENT_CATALOG_TYPES.dashboardSignOfWeek,
    null,
  );
  const frameEntriesQuery = useFrameEntries();
  const zoneCheckInState = useZoneCheckIn();
  const communicationEventsQuery = useCommunicationEvents();
  const roleEvents = useMemo(
    () => filterCommunicationEventsByRole(communicationEventsQuery.data ?? [], userRole),
    [communicationEventsQuery.data, userRole],
  );
  const upcomingEvents = useMemo(
    () => selectDashboardUpcomingEvents(roleEvents),
    [roleEvents],
  );
  const activeZone = selectDashboardActiveZone(zoneCheckIn, zoneCheckInState.currentZone);
  const todayQuote = useMemo(
    () => selectDashboardQuote(quotesQuery.payload, dashboardDate),
    [dashboardDate, quotesQuery.payload],
  );

  async function checkInZone(zone: ZoneColor) {
    await zoneCheckInState.setZone(zone);
    setZoneCheckIn(zone);
  }

  async function resetZone() {
    await zoneCheckInState.resetZone();
    setZoneCheckIn(null);
  }

  return {
    userRole,
    userName,
    greeting: getDashboardGreeting(dashboardDate),
    latestFrame: frameEntriesQuery.data?.[0] ?? null,
    todayQuote,
    quoteState: {
      isLoading: quotesQuery.isLoading,
      isError: Boolean(quotesQuery.error),
    },
    zoneOptions: DASHBOARD_ZONE_OPTIONS,
    activeZone,
    isZoneSaving: zoneCheckInState.isSaving,
    zoneErrorMessage: getOptionalErrorMessage(zoneCheckInState.error),
    upcomingEvents,
    eventsState: {
      isLoading: communicationEventsQuery.isLoading,
      isError: communicationEventsQuery.isError,
    },
    complianceItems: complianceItemsQuery.payload,
    complianceState: {
      isLoading: complianceItemsQuery.isLoading,
      isError: Boolean(complianceItemsQuery.error),
    },
    signOfWeek: signOfWeekQuery.payload,
    signOfWeekState: {
      isLoading: signOfWeekQuery.isLoading,
      isError: Boolean(signOfWeekQuery.error),
    },
    quickActions: selectDashboardQuickActions(userRole),
    goToModule: setCurrentModule,
    checkInZone,
    resetZone,
  };
}
