import {
  applyHistoryLoadedOutput,
  applyNetworkHistoryLoadedOutput,
} from "../helper/history";
import {
  countLockedHistoryMessages,
  shouldPromptUnlockHistory,
} from "../helper/unlock";
import { baseChatMachineSetup } from "./setup";

const applyLocalHistoryLoadedAction = baseChatMachineSetup.assign(
  ({ event }) => {
    if (event.type !== "ChatLocalHistoryLoaded") return {};
    return applyHistoryLoadedOutput(event.output);
  },
);

const applyNetworkHistoryLoadedAction = baseChatMachineSetup.assign(
  ({ context, event }) => {
    if (event.type !== "ChatNetworkHistoryLoaded") return {};
    return applyNetworkHistoryLoadedOutput(context, event.output);
  },
);

const applyNetworkHistoryLoadedAndClearPaymentAction =
  baseChatMachineSetup.assign(({ context, event }) => {
    if (event.type !== "ChatNetworkHistoryLoaded") return {};
    return {
      ...applyNetworkHistoryLoadedOutput(context, event.output),
      paymentUnlockPending: false,
    };
  });

const showUnlockHistoryPromptFromNetworkAction = baseChatMachineSetup.assign(
  ({ context, event }) => {
    if (event.type !== "ChatNetworkHistoryLoaded") return {};
    const nextHistory = applyNetworkHistoryLoadedOutput(context, event.output);
    return {
      ...nextHistory,
      paymentUnlockPending: false,
      unlockHistoryPromptVisible: true,
      lockedHistoryCount: countLockedHistoryMessages(nextHistory.messages),
      unlockHistoryError: null,
    };
  },
);

const markHistoryLoadFailedAction = baseChatMachineSetup.assign({
  historyLoaded: true,
});

export const historyMachineSetup = baseChatMachineSetup.extend({
  actions: {
    applyLocalHistoryLoaded: applyLocalHistoryLoadedAction,
    applyNetworkHistoryLoaded: applyNetworkHistoryLoadedAction,
    applyNetworkHistoryLoadedAndClearPayment:
      applyNetworkHistoryLoadedAndClearPaymentAction,
    showUnlockHistoryPromptFromNetwork:
      showUnlockHistoryPromptFromNetworkAction,
    markHistoryLoadFailed: markHistoryLoadFailedAction,
  },
});

export const guestInitializingState = historyMachineSetup.createStateConfig({
  on: {
    ChatLocalHistoryLoaded: {
      target: "ready",
      actions: "applyLocalHistoryLoaded",
    },
    ChatNetworkHistoryLoaded: {
      target: "ready",
      actions: "applyNetworkHistoryLoaded",
    },
    ChatHistoryLoadFailed: {
      target: "ready",
      actions: "markHistoryLoadFailed",
    },
  },
});

export const userInitializingState = historyMachineSetup.createStateConfig({
  on: {
    ChatLocalHistoryLoaded: {
      target: "ready",
      actions: "applyLocalHistoryLoaded",
    },
    ChatNetworkHistoryLoaded: [
      {
        guard: ({ context, event }) =>
          event.type === "ChatNetworkHistoryLoaded" &&
          context.paymentUnlockPending &&
          shouldPromptUnlockHistory(event.output.messages),
        target: "ready",
        actions: "showUnlockHistoryPromptFromNetwork",
      },
      {
        target: "ready",
        actions: "applyNetworkHistoryLoadedAndClearPayment",
      },
    ],
    ChatHistoryLoadFailed: {
      target: "ready",
      actions: "markHistoryLoadFailed",
    },
  },
});
