import { ClerkGlobalHookError } from "../errors/globalHookError.js";
import { SignInFutureResource } from "./signInFuture.js";
import { SignUpFutureResource } from "./signUpFuture.js";
import { WaitlistResource } from "./waitlist.js";

//#region src/types/state.d.ts
/**
 * Represents an error on a specific field.
 */
interface FieldError {
  /**
   * The error code of the error, returned by the Clerk API.
   */
  code: string;
  /**
   * A more detailed message that describes the error.
   */
  longMessage?: string;
  /**
   * A message that describes the error.
   */
  message: string;
}
/**
 * Represents the errors that occurred during the last fetch of the parent resource.
 */
interface Errors<T> {
  /**
   * Represents the collection of possible errors on known fields.
   */
  fields: T;
  /**
   * The raw, unparsed errors from the Clerk API.
   */
  raw: unknown[] | null;
  /**
   * Parsed errors that are not related to any specific field.
   * Does not include any errors that could be parsed as a field error
   */
  global: ClerkGlobalHookError[] | null;
}
/**
 * Fields available for SignIn errors.
 */
interface SignInFields {
  /**
   * The error for the identifier field.
   */
  identifier: FieldError | null;
  /**
   * The error for the password field.
   */
  password: FieldError | null;
  /**
   * The error for the code field.
   */
  code: FieldError | null;
}
/**
 * Fields available for SignUp errors.
 */
interface SignUpFields {
  /**
   * The error for the first name field.
   */
  firstName: FieldError | null;
  /**
   * The error for the last name field.
   */
  lastName: FieldError | null;
  /**
   * The error for the email address field.
   */
  emailAddress: FieldError | null;
  /**
   * The error for the phone number field.
   */
  phoneNumber: FieldError | null;
  /**
   * The error for the password field.
   */
  password: FieldError | null;
  /**
   * The error for the username field.
   */
  username: FieldError | null;
  /**
   * The error for the code field.
   */
  code: FieldError | null;
  /**
   * The error for the captcha field.
   */
  captcha: FieldError | null;
  /**
   * The error for the legal accepted field.
   */
  legalAccepted: FieldError | null;
}
/**
 * Fields available for Waitlist errors.
 */
interface WaitlistFields {
  /**
   * The error for the email address field.
   */
  emailAddress: FieldError | null;
}
/**
 * Errors type for SignIn operations.
 */
type SignInErrors = Errors<SignInFields>;
/**
 * Errors type for SignUp operations.
 */
type SignUpErrors = Errors<SignUpFields>;
/**
 * Errors type for Waitlist operations.
 */
type WaitlistErrors = Errors<WaitlistFields>;
/**
 * @inline
 *
 * The value returned by the `useSignIn` hook.
 */
interface SignInSignalValue {
  /**
   * The errors that occurred during the last fetch of the underlying `SignInFuture` resource.
   */
  errors: SignInErrors;
  /**
   * The fetch status of the underlying `SignInFuture` resource.
   */
  fetchStatus: 'idle' | 'fetching';
  /**
   * An instance representing the currently active `SignInFuture`, with new APIs designed specifically for custom flows.
   */
  signIn: SignInFutureResource;
}
type NullableSignInSignal = Omit<SignInSignalValue, 'signIn'> & {
  signIn: SignInFutureResource | null;
};
interface SignInSignal {
  (): NullableSignInSignal;
}
/**
 * @inline
 *
 * The value returned by the `useSignUp` hook.
 */
interface SignUpSignalValue {
  /**
   * The errors that occurred during the last fetch of the underlying `SignUpFuture` resource.
   */
  errors: SignUpErrors;
  /**
   * The fetch status of the underlying `SignUpFuture` resource.
   */
  fetchStatus: 'idle' | 'fetching';
  /**
   * The underlying `SignUpFuture` resource.
   */
  signUp: SignUpFutureResource;
}
type NullableSignUpSignal = Omit<SignUpSignalValue, 'signUp'> & {
  signUp: SignUpFutureResource | null;
};
interface SignUpSignal {
  (): NullableSignUpSignal;
}
interface WaitlistSignalValue {
  /**
   * The errors that occurred during the last fetch of the underlying `Waitlist` resource.
   */
  errors: WaitlistErrors;
  /**
   * The fetch status of the underlying `Waitlist` resource.
   */
  fetchStatus: 'idle' | 'fetching';
  /**
   * The underlying `Waitlist` resource.
   */
  waitlist: WaitlistResource;
}
type NullableWaitlistSignal = Omit<WaitlistSignalValue, 'waitlist'> & {
  waitlist: WaitlistResource | null;
};
interface WaitlistSignal {
  (): NullableWaitlistSignal;
}
interface State {
  /**
   * A Signal that updates when the underlying `SignIn` resource changes, including errors.
   */
  signInSignal: SignInSignal;
  /**
   * A Signal that updates when the underlying `SignUp` resource changes, including errors.
   */
  signUpSignal: SignUpSignal;
  /**
   * A Signal that updates when the underlying `Waitlist` resource changes, including errors.
   */
  waitlistSignal: WaitlistSignal;
  /**
   * An alias for `effect()` from `alien-signals`, which can be used to subscribe to changes from Signals.
   *
   * @see https://github.com/stackblitz/alien-signals#usage
   *
   * @experimental This experimental API is subject to change.
   */
  __internal_effect: (callback: () => void) => () => void;
  /**
   * An alias for `computed()` from `alien-signals`, which can be used to create a computed Signal that updates when
   * its dependencies change.
   *
   * @see https://github.com/stackblitz/alien-signals#usage
   *
   * @experimental This experimental API is subject to change.
   */
  __internal_computed: <T>(getter: (previousValue?: T) => T) => () => T;
  /**
   * An instance of the Waitlist resource.
   */
  __internal_waitlist: WaitlistResource;
}
//#endregion
export { Errors, FieldError, NullableSignInSignal, NullableSignUpSignal, NullableWaitlistSignal, SignInErrors, SignInFields, SignInSignal, SignInSignalValue, SignUpErrors, SignUpFields, SignUpSignal, SignUpSignalValue, State, WaitlistErrors, WaitlistFields, WaitlistSignal, WaitlistSignalValue };