import { useCallback, useEffect, useMemo, useState } from "react";
import { fetchMyAssignments } from "../services/swiApi.js";
import {
  assignmentNotifyKey,
  getUnreadAssignments,
  loadSeenAssignmentKeys,
  saveSeenAssignmentKeys,
  sortByAssignedAt,
} from "../utils/assignmentNotifications.js";

const DEFAULT_POLL_MS = 45000;

export function useAssignmentNotifications(userId, { pollMs = DEFAULT_POLL_MS } = {}) {
  const [assignments, setAssignments] = useState([]);
  const [seenKeys, setSeenKeys] = useState(() => loadSeenAssignmentKeys(userId));
  const [loading, setLoading] = useState(true);

  const refresh = useCallback(async () => {
    const rows = await fetchMyAssignments();
    setAssignments(Array.isArray(rows) ? rows : []);
    return rows;
  }, []);

  useEffect(() => {
    if (userId == null || userId === "") {
      setAssignments([]);
      setLoading(false);
      return;
    }

    setSeenKeys(loadSeenAssignmentKeys(userId));
    let cancelled = false;

    refresh()
      .catch(() => {
        if (!cancelled) setAssignments([]);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    const timer = setInterval(() => {
      refresh().catch(() => {});
    }, pollMs);

    return () => {
      cancelled = true;
      clearInterval(timer);
    };
  }, [userId, refresh, pollMs]);

  const sortedAssignments = useMemo(
    () => sortByAssignedAt(assignments),
    [assignments]
  );

  const unread = useMemo(
    () => getUnreadAssignments(sortedAssignments, seenKeys),
    [sortedAssignments, seenKeys]
  );

  const markRead = useCallback(
    (row) => {
      if (!userId || !row) return;
      const key = assignmentNotifyKey(row);
      setSeenKeys((prev) => {
        if (prev.has(key)) return prev;
        const next = new Set(prev);
        next.add(key);
        saveSeenAssignmentKeys(userId, next);
        return next;
      });
    },
    [userId]
  );

  const markAllRead = useCallback(() => {
    if (!userId) return;
    setSeenKeys((prev) => {
      const next = new Set(prev);
      for (const row of assignments) {
        if (row.assigned_at) next.add(assignmentNotifyKey(row));
      }
      saveSeenAssignmentKeys(userId, next);
      return next;
    });
  }, [assignments, userId]);

  const isUnread = useCallback(
    (row) => Boolean(row?.assigned_at && !seenKeys.has(assignmentNotifyKey(row))),
    [seenKeys]
  );

  return {
    assignments: sortedAssignments,
    unread,
    unreadCount: unread.length,
    seenKeys,
    loading,
    refresh,
    markRead,
    markAllRead,
    isUnread,
  };
}
