import { NEEDS_COMPUTATION, STORE_ALL_PROPS } from '../../reactive-primitives/types';
import { _UNINITIALIZED } from '../utils/constants';
import { EMPTY_ARRAY, EMPTY_OBJ } from '../utils/flyweight';
// Keep last
import { Slot } from '../jsx/slot.public';
import { Fragment } from '../jsx/jsx-runtime';

/** Used to represent an undefined value that must be serialized */
export const explicitUndefined = Symbol('undefined');
export const EMPTY_OBJECT_PAYLOAD = 0;

export const enum Constants {
  Undefined,
  Null,
  True,
  False,
  EmptyString,
  EMPTY_ARRAY,
  EMPTY_OBJ,
  NEEDS_COMPUTATION,
  STORE_ALL_PROPS,
  UNINITIALIZED,
  Slot,
  Fragment,
  NaN,
  PositiveInfinity,
  NegativeInfinity,
  MaxSafeInt,
  // used for close fragment
  AlmostMaxSafeInt,
  MinSafeInt,
  Colon,
  Dot,
  Id,
  Ref,
}

// Used for allocate, make sure they are in sync with Constants
export const _constants = [
  undefined,
  null,
  true,
  false,
  '',
  EMPTY_ARRAY,
  EMPTY_OBJ,
  NEEDS_COMPUTATION,
  STORE_ALL_PROPS,
  _UNINITIALIZED,
  Slot,
  Fragment,
  NaN,
  Infinity,
  -Infinity,
  Number.MAX_SAFE_INTEGER,
  Number.MAX_SAFE_INTEGER - 1,
  Number.MIN_SAFE_INTEGER,
  ':',
  '.',
  'id',
  'ref',
] as const;

// Used for dumpState, make sure they are in sync with Constants
export const _constantNames = [
  'undefined',
  'null',
  'true',
  'false',
  "''",
  'EMPTY_ARRAY',
  'EMPTY_OBJ',
  'NEEDS_COMPUTATION',
  'STORE_ALL_PROPS',
  '_UNINITIALIZED',
  'Slot',
  'Fragment',
  'NaN',
  'Infinity',
  '-Infinity',
  'MAX_SAFE_INTEGER',
  'MAX_SAFE_INTEGER-1',
  'MIN_SAFE_INTEGER',
  "':'",
  "'.'",
  "'id'",
  "'ref'",
] as const;

export const enum TypeIds {
  Plain,
  RootRef,
  ForwardRef,
  /** Undefined, null, true, false, NaN, +Inf, -Inf, Slot, Fragment */
  Constant,
  Array,
  Object,
  URL,
  Date,
  Regex,
  QRL,
  /// ^ single-digit types ^
  VNode,
  RefVNode,
  BigInt,
  URLSearchParams,
  ForwardRefs,
  TemporalDuration,
  TemporalInstant,
  TemporalPlainDate,
  TemporalPlainDateTime,
  TemporalPlainMonthDay,
  TemporalPlainTime,
  TemporalPlainYearMonth,
  TemporalZonedDateTime,
  /// All types below will be inflate()d
  Error,
  Promise,
  Set,
  Map,
  Uint8Array,
  Task,
  Component,
  Signal,
  WrappedSignal,
  ComputedSignal,
  AsyncSignal,
  SerializerSignal,
  Store,
  FormData,
  JSXNode,
  PropsProxy,
  SubscriptionData,
  EffectSubscription,
  SubscriptionPatch,
  SubscriptionDataConstTrue,
  SubscriptionDataConstFalse,
  EffectSubscriptionNoData,
}

// Used for dumpState, make sure they are in sync with TypeIds
export const _typeIdNames = [
  'Plain',
  'RootRef',
  'ForwardRef',
  'Constant',
  'Array',
  'Object',
  'URL',
  'Date',
  'Regex',
  'QRL',
  'VNode',
  'RefVNode',
  'BigInt',
  'URLSearchParams',
  'ForwardRefs',
  'TemporalDuration',
  'TemporalInstant',
  'TemporalPlainDate',
  'TemporalPlainDateTime',
  'TemporalPlainMonthDay',
  'TemporalPlainTime',
  'TemporalPlainYearMonth',
  'TemporalZonedDateTime',
  'Error',
  'Promise',
  'Set',
  'Map',
  'Uint8Array',
  'Task',
  'Component',
  'Signal',
  'WrappedSignal',
  'ComputedSignal',
  'AsyncSignal',
  'SerializerSignal',
  'Store',
  'FormData',
  'JSXNode',
  'PropsProxy',
  'SubscriptionData',
  'EffectSubscription',
  'SubscriptionPatch',
  'SubscriptionDataConstTrue',
  'SubscriptionDataConstFalse',
  'EffectSubscriptionNoData',
];
