import type { DoneActorEvent, ErrorActorEvent } from "xstate";

import type { LoginStatus } from "@/data/schemas/auth";

import { toAuthErrorMessage } from "../helper/error";
import {
  baseAuthMachineSetup,
  createAuthActorActionSetup,
} from "./setup";

const clearAuthErrorAction = baseAuthMachineSetup.assign({
  errorMessage: null,
});

export const credentialsMachineSetup = baseAuthMachineSetup.extend({
  actions: {
    clearAuthError: clearAuthErrorAction,
  },
});

const authSuccessActionSetup =
  createAuthActorActionSetup<DoneActorEvent<LoginStatus>>();
const authErrorActionSetup = createAuthActorActionSetup<ErrorActorEvent>();

const applyAuthSuccessAction = authSuccessActionSetup.assign(({ event }) => ({
  loginStatus: event.output,
  errorMessage: null,
  hasInitialized: true,
}));

const applyAuthErrorAction = authErrorActionSetup.assign(({ event }) => ({
  errorMessage: toAuthErrorMessage(event.error),
  hasInitialized: true,
}));

export const loadingEmailLoginState =
  credentialsMachineSetup.createStateConfig({
    entry: "clearAuthError",
    invoke: {
      src: "emailLogin",
      input: ({ event }) =>
        event.type === "AuthEmailLoginSubmitted"
          ? { email: event.email, password: event.password }
          : { email: "", password: "" },
      onDone: {
        target: "idle",
        actions: applyAuthSuccessAction,
      },
      onError: {
        target: "idle",
        actions: applyAuthErrorAction,
      },
    },
  });

export const loadingEmailRegisterState =
  credentialsMachineSetup.createStateConfig({
    entry: "clearAuthError",
    invoke: {
      src: "emailRegisterThenLogin",
      input: ({ event }) =>
        event.type === "AuthEmailRegisterSubmitted"
          ? {
              email: event.email,
              password: event.password,
              username: event.username,
              confirmPassword: event.confirmPassword,
            }
          : {
              email: "",
              password: "",
              username: "",
              confirmPassword: "",
            },
      onDone: {
        target: "idle",
        actions: applyAuthSuccessAction,
      },
      onError: {
        target: "idle",
        actions: applyAuthErrorAction,
      },
    },
  });
