import * as Data from 'effect/Data';
import * as Option from 'effect/Option';
import * as EffectSchema from 'effect/Schema';
import * as SchemaAST from 'effect/SchemaAST';
import { PropertyIdSymbol, TypeIdsSymbol } from '../constants.js';
import { relationSchemaBrand } from '../type/type.js';
const relationTotalCountSchema = /*#__PURE__*/EffectSchema.optional(EffectSchema.Number);
export function Schema(schemaTypes, mapping) {
  const properties = {};
  for (const [key, schemaType] of Object.entries(schemaTypes)) {
    const propertyMapping = mapping.properties[key];
    const builtSchema = schemaType(propertyMapping);
    properties[key] = builtSchema;
    if (relationSchemaBrand in builtSchema) {
      const totalCountKey = `${key}TotalCount`;
      properties[totalCountKey] = relationTotalCountSchema;
    }
  }
  // biome-ignore lint/suspicious/noExplicitAny: any
  return EffectSchema.Struct(properties).pipe(EffectSchema.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=schema.js.map