import { TSchema, Data } from '@evolution-sdk/evolution';
import {
  AssetClassSchema,
  OutputReferenceSchema,
} from '@3rd-eye-labs/cardano-offchain-common';
import { DEFAULT_SCHEMA_OPTIONS } from '../../types/evolution-schema-options';

const WithdrawalOutputDatumSchema = TSchema.Tuple([
  TSchema.ByteArray,
  OutputReferenceSchema,
]);

export type WithdrawalOutputDatum = typeof WithdrawalOutputDatumSchema.Type;

const TreasuryDatumSchema = TSchema.Struct(
  {
    treasuryInputOref: TSchema.NullOr(OutputReferenceSchema),
    actionInputOref: OutputReferenceSchema,
  },
  { flatFields: true },
);

export type TreasuryDatum = typeof TreasuryDatumSchema.Type;

const TreasuryRedeemerSchema = TSchema.Union(
  TSchema.Literal('Withdraw', { flatInUnion: true }),
  TSchema.Literal('PrepareWithdraw', { flatInUnion: true }),
  TSchema.Literal('Split', { flatInUnion: true }),
  TSchema.Literal('Merge', { flatInUnion: true }),
  TSchema.Struct(
    {
      Collect: TSchema.Struct(
        {
          assetToCollect: AssetClassSchema,
          amountToCollect: TSchema.Integer,
          extraLovelaces: TSchema.Integer,
          actionInputOref: OutputReferenceSchema,
        },
        { flatFields: true },
      ),
    },
    { flatInUnion: true },
  ),
  TSchema.Literal('UpgradeVersion', { flatInUnion: true }),
);

export type TreasuryRedeemer = typeof TreasuryRedeemerSchema.Type;

export function serialiseTreasuryRedeemer(r: TreasuryRedeemer): string {
  return Data.withSchema(
    TreasuryRedeemerSchema,
    DEFAULT_SCHEMA_OPTIONS,
  ).toCBORHex(r);
}

export function serialiseWithdrawalOutputDatum(
  d: WithdrawalOutputDatum,
): string {
  return Data.withSchema(
    WithdrawalOutputDatumSchema,
    DEFAULT_SCHEMA_OPTIONS,
  ).toCBORHex(d);
}

export function serialiseTreasuryDatum(d: TreasuryDatum): string {
  return Data.withSchema(TreasuryDatumSchema, DEFAULT_SCHEMA_OPTIONS).toCBORHex(
    d,
  );
}
