import { useEffectEvent } from "react";
import type { LegacyTalentChoice } from "../legacy/interop.js";
import type { DraftStatKey } from "./legacySessionTypes";
import {
  clamp,
  getRemainingPoints,
  randomizeDraftAllocation,
  shuffleEntries,
} from "./legacySessionUtils";
import type {
  LegacySessionActionBaseProps,
  LegacySessionActions,
} from "./legacySessionActionTypes";
import {
  createAllocationLimitMessage,
  createSelectionLimitMessage,
  createTalentConflictMessage,
} from "./legacySessionMessages";
import { transitionLegacySessionToDraft } from "./legacySessionTransitions";

interface UseLegacyDraftActionsProps extends LegacySessionActionBaseProps {}

export function useLegacyDraftActions({
  feedback,
  lifeRef,
  refreshMeta,
  setters,
  state,
}: UseLegacyDraftActionsProps): Pick<
  LegacySessionActions,
  | "randomizeAllocation"
  | "refreshDraft"
  | "reshuffleSpecialThanks"
  | "setAllocationValue"
  | "toggleTalent"
> {
  const refreshDraft = useEffectEvent(() => {
    const life = lifeRef.current;
    if (!life) {
      return;
    }

    feedback.clearError();
    transitionLegacySessionToDraft(setters, life.talentRandom());
    refreshMeta();
  });

  const reshuffleSpecialThanks = useEffectEvent(() => {
    setters.setSpecialThanks((current) => shuffleEntries(current));
  });

  const toggleTalent = useEffectEvent((talent: LegacyTalentChoice) => {
    const life = lifeRef.current;
    if (!life || state.stage !== "talent") {
      return;
    }

    const current = state.selectedTalentIds;
    feedback.clearError();
    if (current.includes(talent.id)) {
      setters.setSelectedTalentIds(current.filter((id) => id !== talent.id));
      return;
    }

    if (current.length >= 3) {
      feedback.showValidation(createSelectionLimitMessage());
      return;
    }

    const exclusive = life.exclusive(current, talent.id);
    if (exclusive != null) {
      const blocked = state.availableTalents.find(
        (entry) => entry.id === exclusive,
      );
      feedback.showValidation(
        createTalentConflictMessage(blocked?.name ?? exclusive),
      );
      return;
    }

    setters.setSelectedTalentIds([...current, talent.id]);
  });

  const setAllocationValue = useEffectEvent(
    (stat: DraftStatKey, value: number) => {
      if (state.stage !== "property" || !state.allocation) {
        return;
      }

      const nextValue = clamp(Math.round(value), 0, 10);
      const delta = nextValue - state.allocation[stat];
      const nextRemaining = getRemainingPoints(state.allocation) - delta;

      if (nextRemaining < 0) {
        feedback.showValidation(createAllocationLimitMessage());
        return;
      }

      feedback.clearError();
      setters.setAllocation({
        ...state.allocation,
        [stat]: nextValue,
      });
    },
  );

  const randomizeAllocation = useEffectEvent(() => {
    if (!state.allocation) {
      return;
    }

    feedback.clearError();
    setters.setAllocation(randomizeDraftAllocation(state.allocation.total));
  });

  return {
    randomizeAllocation,
    refreshDraft,
    reshuffleSpecialThanks,
    setAllocationValue,
    toggleTalent,
  };
}
