// Copyright 2025-present 650 Industries. All rights reserved.

import ExpoModulesJSI

// Every `Enumerable` is `JavaScriptCodable`: an enum converts as its raw value. The witnesses are
// provided for `RawRepresentable` enums whose `RawValue` is itself `JavaScriptCodable` (in practice
// `String` or an integer type), delegating the actual conversion to that raw value's conformance.

extension Enumerable where Self: RawRepresentable, RawValue: JavaScriptCodable {
  // An enum decodes through its raw value, so it accepts what the raw value accepts.
  @inlinable
  public static var decodableKinds: JavaScriptValueKinds {
    return RawValue.decodableKinds
  }

  @JavaScriptActor
  @inlinable
  public static func decode(_ value: borrowing JavaScriptValue, in runtime: borrowing JavaScriptRuntime) throws -> Self
  {
    let rawValue = try RawValue.decode(value, in: runtime)
    return try create(fromRawValue: rawValue)
  }

  @JavaScriptActor
  @inlinable
  public static func decode(_ value: borrowing JavaScriptUnownedValue, in runtime: borrowing JavaScriptRuntime) throws
    -> Self
  {
    let rawValue = try RawValue.decode(value, in: runtime)
    return try create(fromRawValue: rawValue)
  }

  @JavaScriptActor
  @inlinable
  public static func encode(_ value: Self, in runtime: borrowing JavaScriptRuntime) throws -> JavaScriptValue {
    return try RawValue.encode(value.rawValue, in: runtime)
  }
}
