import { fromPromise } from "xstate";

import type { LoginStatus } from "@/data/dto/auth";
import { getAuthRepository } from "@/data/repositories/auth_repository";
import { Logger } from "@/utils/logger";
import { Result } from "@/utils/result";

import { readGuestId, readPsid } from "./storage";

const log = new Logger("AuthActors");

export const emailLoginActor = fromPromise<
  LoginStatus,
  { email: string; password: string }
>(async ({ input }) => {
  const authRepo = getAuthRepository();
  log.debug("[auth-machine] emailLoginActor ENTRY", {
    emailLength: input.email.length,
    emailPreview: input.email.slice(0, 8),
    passwordLength: input.password.length,
  });
  const guestId = await readGuestId();
  const psid = await readPsid();
  log.debug("[auth-machine] emailLoginActor calling authRepo.emailLogin", {
    hasGuestId: !!guestId,
    hasPsid: !!psid,
  });
  const result = await authRepo.emailLogin({ ...input, guestId, psid });
  log.debug("[auth-machine] emailLoginActor authRepo.emailLogin DONE", {
    success: result.success,
    hasData: result.success ? !!result.data : null,
    errorName: result.success ? null : result.error?.name,
    errorMessage: result.success ? null : result.error?.message,
  });
  if (Result.isErr(result)) throw result.error;
  return "email" as LoginStatus;
});

export const emailRegisterThenLoginActor = fromPromise<
  LoginStatus,
  {
    email: string;
    password: string;
    username: string;
    confirmPassword: string;
  }
>(async ({ input }) => {
  const authRepo = getAuthRepository();
  log.debug("[auth-machine] emailRegisterThenLoginActor ENTRY", {
    emailLength: input.email.length,
    usernameLength: input.username.length,
    passwordLength: input.password.length,
    confirmPasswordLength: input.confirmPassword.length,
  });
  const guestId = await readGuestId();

  log.debug("[auth-machine] emailRegisterThenLoginActor calling authRepo.register");
  const registerResult = await authRepo.register({ ...input, guestId });
  log.debug("[auth-machine] emailRegisterThenLoginActor authRepo.register DONE", {
    success: registerResult.success,
    errorName: registerResult.success ? null : registerResult.error?.name,
    errorMessage: registerResult.success ? null : registerResult.error?.message,
  });
  if (Result.isErr(registerResult)) throw registerResult.error;

  const psid = await readPsid();
  log.debug(
    "[auth-machine] emailRegisterThenLoginActor calling authRepo.emailLogin (post-register)",
  );
  const loginResult = await authRepo.emailLogin({
    email: input.email,
    password: input.password,
    guestId,
    psid,
  });
  log.debug(
    "[auth-machine] emailRegisterThenLoginActor authRepo.emailLogin DONE",
    {
      success: loginResult.success,
      errorName: loginResult.success ? null : loginResult.error?.name,
      errorMessage: loginResult.success ? null : loginResult.error?.message,
    },
  );
  if (Result.isErr(loginResult)) throw loginResult.error;
  return "email" as LoginStatus;
});
