import type { DoneActorEvent } from "xstate";

import { initialState } from "../user-state";
import type { InitData } from "./actors/session";
import { fetchingState, profileMachineSetup } from "./profile-flow";
import { createUserActorActionSetup } from "./setup";

const clearUserAction = profileMachineSetup.assign(() => ({
  currentUser: null,
  avatarUrl: null,
  isVip: false,
  creditBalance: 0,
}));

export const userMachineSetup = profileMachineSetup.extend({
  actions: {
    clearUser: clearUserAction,
  },
});

const userInitDoneSetup =
  createUserActorActionSetup<DoneActorEvent<InitData>>();

const applyInitializedUserAction = userInitDoneSetup.assign(({ event }) => ({
  currentUser: event.output.user,
  avatarUrl: event.output.avatarUrl,
  isVip: event.output.snapshot?.isVip ?? initialState.isVip,
  creditBalance:
    event.output.snapshot?.creditBalance ?? initialState.creditBalance,
}));

const idleState = userMachineSetup.createStateConfig({
  on: {
    UserInit: "initializing",
    UserFetch: "fetching",
    UserUpdate: { actions: "updateUser" },
    UserClearLocal: { actions: "clearUser" },
    UserLogout: "loggingOut",
  },
});

const initializingState = userMachineSetup.createStateConfig({
  invoke: {
    src: "userInit",
    onDone: {
      target: "fetching",
      actions: applyInitializedUserAction,
    },
    onError: { target: "fetching" },
  },
});

const loggingOutState = userMachineSetup.createStateConfig({
  invoke: {
    src: "userLogout",
    onDone: {
      target: "idle",
      actions: "clearUser",
    },
    onError: {
      target: "idle",
      actions: "clearUser",
    },
  },
});

export const userRootStateConfig = userMachineSetup.createStateConfig({
  initial: "idle",
  states: {
    idle: idleState,
    initializing: initializingState,
    fetching: fetchingState,
    loggingOut: loggingOutState,
  },
});
