"use client";
import { createContext, useCallback, useContext, useMemo, useState } from "react";

type Ctx = {
  ids: Set<number>;
  has: (id: number) => boolean;
  toggle: (id: number) => void;
  selectMany: (ids: number[]) => void;
  setMany: (ids: number[]) => void;
  selectRangeTo: (id: number, orderedIds: number[]) => void;
  clear: () => void;
  lastClickedId: number | null;
};

const ActressSelectCtx = createContext<Ctx | null>(null);

export function ActressSelectionProvider({ children }: { children: React.ReactNode }) {
  const [ids, setIds] = useState<Set<number>>(new Set());
  const [lastClickedId, setLastClickedId] = useState<number | null>(null);

  const toggle = useCallback((id: number) => {
    setIds((cur) => {
      const next = new Set(cur);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
    setLastClickedId(id);
  }, []);

  const selectMany = useCallback((newIds: number[]) => {
    setIds((cur) => {
      const next = new Set(cur);
      newIds.forEach((i) => next.add(i));
      return next;
    });
  }, []);

  const setMany = useCallback((newIds: number[]) => {
    setIds(new Set(newIds));
  }, []);

  const selectRangeTo = useCallback((id: number, orderedIds: number[]) => {
    const last = lastClickedId;
    if (last == null) {
      setIds((cur) => {
        const next = new Set(cur);
        next.add(id);
        return next;
      });
      setLastClickedId(id);
      return;
    }
    const a = orderedIds.indexOf(last);
    const b = orderedIds.indexOf(id);
    if (a === -1 || b === -1) {
      setIds((cur) => {
        const next = new Set(cur);
        next.add(id);
        return next;
      });
      setLastClickedId(id);
      return;
    }
    const [start, end] = a < b ? [a, b] : [b, a];
    const range = orderedIds.slice(start, end + 1);
    setIds((cur) => {
      const next = new Set(cur);
      range.forEach((i) => next.add(i));
      return next;
    });
    setLastClickedId(id);
  }, [lastClickedId]);

  const clear = useCallback(() => {
    setIds(new Set());
    setLastClickedId(null);
  }, []);

  const value = useMemo<Ctx>(() => ({
    ids,
    has: (id) => ids.has(id),
    toggle,
    selectMany,
    setMany,
    selectRangeTo,
    clear,
    lastClickedId,
  }), [ids, toggle, selectMany, setMany, selectRangeTo, clear, lastClickedId]);

  return <ActressSelectCtx.Provider value={value}>{children}</ActressSelectCtx.Provider>;
}

export function useActressSelection() {
  const ctx = useContext(ActressSelectCtx);
  if (!ctx) throw new Error("useActressSelection must be used within ActressSelectionProvider");
  return ctx;
}
