import * as Data from 'effect/Data';
import * as Option from 'effect/Option';
import * as Schema from 'effect/Schema';
import * as SchemaAST from 'effect/SchemaAST';
import { PropertyIdSymbol, TypeIdsSymbol } from '../constants.js';
/**
 * Entity function for creating schemas with a nicer API.
 * Takes a schema configuration object and a property ID mapping object.
 *
 * @example
 * ```typescript
 * const User = EntityDefinition({
 *   name: Type.String,
 *   age: Type.Number,
 * }, {
 *   name: "grc-20-name",
 *   age: "grc-20-age"
 * });
 * ```
 */
export function EntitySchema(schemaTypes, mapping) {
  // biome-ignore lint/suspicious/noExplicitAny: any
  const properties = {};
  for (const [key, schemaType] of Object.entries(schemaTypes)) {
    const propertyId = mapping.properties[key];
    properties[key] = schemaType(propertyId);
  }
  // biome-ignore lint/suspicious/noExplicitAny: any
  return Schema.Struct(properties).pipe(Schema.annotations({
    [TypeIdsSymbol]: mapping.types
  }));
}
export function encodeToGrc20Json(schema, value) {
  const ast = schema.ast;
  const out = {};
  for (const prop of ast.propertySignatures) {
    const propType = prop.isOptional && SchemaAST.isUnion(prop.type) ? prop.type.types.find(member => !SchemaAST.isUndefinedKeyword(member)) ?? prop.type : prop.type;
    const result = SchemaAST.getAnnotation(PropertyIdSymbol)(propType);
    // biome-ignore lint/suspicious/noExplicitAny: any
    const propertyValue = value[prop.name];
    if (Option.isSome(result) && propertyValue !== undefined) {
      out[result.value] = propertyValue;
    }
  }
  const typeIds = SchemaAST.getAnnotation(TypeIdsSymbol)(ast).pipe(Option.getOrElse(() => []));
  out['@@types@@'] = typeIds;
  return out;
}
export function decodeFromGrc20Json(schema, grc20Data) {
  const ast = schema.ast;
  const out = {};
  for (const prop of ast.propertySignatures) {
    const propType = prop.isOptional && SchemaAST.isUnion(prop.type) ? prop.type.types.find(member => !SchemaAST.isUndefinedKeyword(member)) ?? prop.type : prop.type;
    const result = SchemaAST.getAnnotation(PropertyIdSymbol)(propType);
    if (Option.isSome(result)) {
      const grc20Key = result.value;
      if (grc20Key in grc20Data && typeof prop.name === 'string') {
        // biome-ignore lint/suspicious/noExplicitAny: any
        out[prop.name] = grc20Data[grc20Key];
      }
    }
  }
  out.id = grc20Data.id;
  out.__deleted = grc20Data.__deleted ?? false;
  return out;
}
export class EntityNotFoundError extends /*#__PURE__*/Data.TaggedError('EntityNotFoundError') {}
//# sourceMappingURL=entity.js.map