import { TSchema, Data } from '@evolution-sdk/evolution';
import { Schema } from 'effect';
import { RationalSchema } from '../../types/rational';

const OpaqueData = Schema.typeSchema(Data.DataSchema);

export const OracleIdxSchema = TSchema.Union(
  TSchema.Struct(
    {
      OracleRefInputIdx: TSchema.Integer,
    },
    { flatInUnion: true },
  ),
  TSchema.Struct(
    {
      OracleOutputIdx: TSchema.Integer,
    },
    { flatInUnion: true },
  ),
  TSchema.Literal('OracleVoid', { flatInUnion: true }),
);

export type OracleIdx = typeof OracleIdxSchema.Type;

const PriceOracleDatumSchema = TSchema.Struct({
  price: RationalSchema,
  expirationTime: TSchema.Integer,
  auxiliaryData: OpaqueData,
});

export type PriceOracleDatum = typeof PriceOracleDatumSchema.Type;

const PriceOracleRedeemerSchema = TSchema.Struct({
  currentTime: TSchema.Integer,
  newPrice: RationalSchema,
});

export type PriceOracleRedeemer = typeof PriceOracleRedeemerSchema.Type;

export function serialisePriceOracleRedeemer(r: PriceOracleRedeemer): string {
  return Data.withSchema(PriceOracleRedeemerSchema).toCBORHex(r);
}

export function serialisePriceOracleDatum(d: PriceOracleDatum): string {
  return Data.withSchema(PriceOracleDatumSchema).toCBORHex(d);
}

export function parsePriceOracleDatum(datum: string): PriceOracleDatum {
  return Data.withSchema(PriceOracleDatumSchema).fromCBORHex(datum);
}
