import * as Notifications from "expo-notifications";
import { router } from "expo-router";
import { useEffect, useRef } from "react";
import { AppState, type AppStateStatus } from "react-native";

import { syncInvoiceSendReminders } from "@/lib/invoice-send-reminders";
import { api } from "@/lib/trpc";

function openInvoiceFromNotification(data: Record<string, unknown> | undefined) {
  if (data?.type !== "invoice-send-reminder") return;
  const invoiceId = data.invoiceId;
  if (typeof invoiceId !== "string" || !invoiceId) return;
  router.push(`/(app)/invoices/${invoiceId}`);
}

/** Schedules local iOS/Android notifications for draft invoice send reminders. */
export function InvoiceReminderSync() {
  const utils = api.useUtils();
  const invoicesQuery = api.invoices.getAll.useQuery(
    { status: "draft" },
    { staleTime: 60_000 },
  );
  const wasBackgrounded = useRef(false);

  useEffect(() => {
    if (!invoicesQuery.data) return;
    void syncInvoiceSendReminders(invoicesQuery.data);
  }, [invoicesQuery.data]);

  useEffect(() => {
    const subscription = AppState.addEventListener("change", (nextState: AppStateStatus) => {
      if (nextState === "background" || nextState === "inactive") {
        wasBackgrounded.current = true;
        return;
      }

      if (nextState !== "active" || !wasBackgrounded.current) return;
      wasBackgrounded.current = false;
      void utils.invoices.getAll.invalidate({ status: "draft" });
    });

    return () => subscription.remove();
  }, [utils.invoices.getAll]);

  useEffect(() => {
    const responseSubscription = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        openInvoiceFromNotification(
          response.notification.request.content.data as Record<string, unknown>,
        );
      },
    );

    void Notifications.getLastNotificationResponseAsync().then((response) => {
      if (!response) return;
      openInvoiceFromNotification(
        response.notification.request.content.data as Record<string, unknown>,
      );
    });

    return () => responseSubscription.remove();
  }, []);

  return null;
}
