import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { useQueryClient } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed";
import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed";
import { useHaptic } from "./useHaptic";

export const useMarkAsPlayed = (items: BaseItemDto[]) => {
  const [api] = useAtom(apiAtom);
  const [user] = useAtom(userAtom);
  const queryClient = useQueryClient();
  const lightHapticFeedback = useHaptic("light");

  const invalidateQueries = () => {
    const queriesToInvalidate = [
      ["resumeItems"],
      ["continueWatching"],
      ["nextUp-all"],
      ["nextUp"],
      ["episodes"],
      ["seasons"],
      ["home"],
    ];

    items.forEach((item) => {
      if (!item.Id) return;
      queriesToInvalidate.push(["item", item.Id]);
    });

    queriesToInvalidate.forEach((queryKey) => {
      queryClient.invalidateQueries({ queryKey });
    });
  };

  const markAsPlayedStatus = async (played: boolean) => {
    lightHapticFeedback();

    items.forEach((item) => {
      // Optimistic update
      queryClient.setQueryData(
        ["item", item.Id],
        (oldData: BaseItemDto | undefined) => {
          if (oldData) {
            return {
              ...oldData,
              UserData: {
                ...oldData.UserData,
                Played: played,
              },
            };
          }
          return oldData;
        },
      );
    });

    try {
      // Process all items
      await Promise.all(
        items.map((item) =>
          played
            ? markAsPlayed({ api, item, userId: user?.Id })
            : markAsNotPlayed({ api, itemId: item?.Id, userId: user?.Id }),
        ),
      );

      // Bulk invalidate
      queryClient.invalidateQueries({
        queryKey: [
          "resumeItems",
          "continueWatching",
          "nextUp-all",
          "nextUp",
          "episodes",
          "seasons",
          "home",
          ...items.map((item) => ["item", item.Id]),
        ].flat(),
      });
    } catch (error) {
      // Revert all optimistic updates on any failure
      items.forEach((item) => {
        queryClient.setQueryData(
          ["item", item.Id],
          (oldData: BaseItemDto | undefined) =>
            oldData
              ? {
                  ...oldData,
                  UserData: { ...oldData.UserData, Played: played },
                }
              : oldData,
        );
      });
      console.error("Error updating played status:", error);
    }

    invalidateQueries();
  };

  return markAsPlayedStatus;
};
