import { Effect as Eff, Equal, FastCheck, Hash, Inspectable, ParseResult, Schema } from "effect";
import * as Bytes from "./Bytes.js";
import * as CBOR from "./CBOR.js";
import * as Coin from "./Coin.js";
import * as CommitteeColdCredential from "./CommitteeColdCredential.js";
import * as Constitution from "./Constitution.js";
import * as Credential from "./Credential.js";
import * as EpochNo from "./EpochNo.js";
import * as ProtocolParamUpdate from "./ProtocolParamUpdate.js";
import * as ProtocolVersion from "./ProtocolVersion.js";
import * as RewardAccount from "./RewardAccount.js";
import * as ScriptHash from "./ScriptHash.js";
import * as TransactionHash from "./TransactionHash.js";
import * as TransactionIndex from "./TransactionIndex.js";
import * as UnitInterval from "./UnitInterval.js";
/**
 * Helper for array equality using element-by-element comparison.
 */
const arrayEquals = (a, b) => {
  if (a === b) return true;
  if (a === undefined || b === undefined) return false;
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) {
    if (!Equal.equals(a[i], b[i])) return false;
  }
  return true;
};
/**
 * Helper for array hashing using element hashes.
 */
const arrayHash = arr => {
  let hash = 0;
  for (const item of arr) {
    hash = Hash.combine(hash)(Hash.hash(item));
  }
  return hash;
};
/**
 * Content-based Map equality helper.
 * Compares two Maps by content, handling nested Maps recursively.
 * Uses Equal.equals for key comparison since Map.has uses reference equality.
 */
const mapEquals = (a, b) => {
  if (a.size !== b.size) return false;
  for (const [keyA, valueA] of a) {
    // Find matching key in b using Equal.equals
    let found = false;
    for (const [keyB, valueB] of b) {
      if (Equal.equals(keyA, keyB)) {
        found = true;
        // Handle nested Map values
        if (valueA instanceof Map && valueB instanceof Map) {
          if (!mapEquals(valueA, valueB)) return false;
        } else if (!Equal.equals(valueA, valueB)) {
          return false;
        }
        break;
      }
    }
    if (!found) return false;
  }
  return true;
};
/**
 * Content-based Map hash helper.
 * XORs hashes of all entries for order-independent content-based hash.
 */
const mapHash = map => {
  let hash = 0;
  for (const [key, value] of map) {
    const entryHash = Hash.combine(Hash.hash(key))(value instanceof Map ? mapHash(value) : Hash.hash(value));
    hash ^= entryHash;
  }
  return hash;
};
/**
 * GovActionId schema representing a governance action identifier.
 * ```
 * According to Conway CDDL: gov_action_id = [transaction_id : transaction_id, gov_action_index : uint .size 2]
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class GovActionId extends /*#__PURE__*/Schema.TaggedClass()("GovActionId", {
  transactionId: TransactionHash.TransactionHash,
  // transaction_id (hash32)
  govActionIndex: TransactionIndex.TransactionIndex // uint .size 2 (governance action index)
}) {
  toJSON() {
    return {
      _tag: this._tag,
      transactionId: this.transactionId,
      govActionIndex: this.govActionIndex
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof GovActionId && Equal.equals(this.transactionId, that.transactionId) && Equal.equals(this.govActionIndex, that.govActionIndex);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(Hash.hash(this.transactionId))(Hash.hash(this.govActionIndex)));
  }
}
/**
 * CDDL schema for GovActionId tuple structure.
 * ```
 * For CBOR encoding: [transaction_id: bytes, gov_action_index: uint]
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const GovActionIdCDDL = /*#__PURE__*/Schema.Tuple(CBOR.ByteArray,
// transaction_id as bytes
CBOR.Integer // gov_action_index as uint
);
/**
 * CDDL transformation schema for GovActionId.
 *
 * @since 2.0.0
 * @category schemas
 */
export const GovActionIdFromCDDL = /*#__PURE__*/Schema.transformOrFail(GovActionIdCDDL, /*#__PURE__*/Schema.typeSchema(GovActionId), {
  strict: true,
  encode: (_, __, ___, toA) => Eff.gen(function* () {
    // Convert domain types to CBOR types
    const transactionIdBytes = toA.transactionId.hash;
    const indexNumber = yield* ParseResult.encode(TransactionIndex.TransactionIndex)(toA.govActionIndex);
    return [transactionIdBytes, BigInt(indexNumber)];
  }),
  decode: fromA => Eff.gen(function* () {
    const [transactionIdBytes, govActionIndex] = fromA;
    // Convert CBOR types to domain types
    const transactionId = new TransactionHash.TransactionHash({
      hash: transactionIdBytes
    });
    const govActionIndexParsed = yield* ParseResult.decode(Schema.typeSchema(TransactionIndex.TransactionIndex))(govActionIndex);
    const govActionId = new GovActionId({
      transactionId,
      govActionIndex: govActionIndexParsed
    });
    return govActionId;
  })
});
/**
 * Parameter change governance action schema.
 * ```
 * According to Conway CDDL: parameter_change_action =
 *   (0, gov_action_id/ nil, protocol_param_update, policy_hash/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class ParameterChangeAction extends /*#__PURE__*/Schema.TaggedClass()("ParameterChangeAction", {
  govActionId: /*#__PURE__*/Schema.NullOr(GovActionId),
  // gov_action_id / nil
  protocolParamUpdate: ProtocolParamUpdate.ProtocolParamUpdate,
  // protocol_param_update
  policyHash: /*#__PURE__*/Schema.NullOr(ScriptHash.ScriptHash) // policy_hash / nil
}) {
  toJSON() {
    return {
      _tag: this._tag,
      govActionId: this.govActionId,
      protocolParamUpdate: this.protocolParamUpdate,
      policyHash: this.policyHash
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof ParameterChangeAction && Equal.equals(this.govActionId, that.govActionId) && Equal.equals(this.protocolParamUpdate, that.protocolParamUpdate) && Equal.equals(this.policyHash, that.policyHash);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(Hash.combine(Hash.hash(this.govActionId))(Hash.hash(this.protocolParamUpdate)))(Hash.hash(this.policyHash)));
  }
}
/**
 * CDDL schema for ParameterChangeAction tuple structure.
 * Maps to: (0, gov_action_id/ nil, protocol_param_update, policy_hash/ nil)
 *
 * @since 2.0.0
 * @category schemas
 */
export const ParameterChangeActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(0n),
/*#__PURE__*/
// action type
Schema.NullOr(GovActionIdCDDL),
// gov_action_id / nil
ProtocolParamUpdate.CDDLSchema,
/*#__PURE__*/
// protocol_param_update
Schema.NullOr(CBOR.ByteArray) // policy_hash / nil
);
/**
 * CDDL transformation schema for ParameterChangeAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const ParameterChangeActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(ParameterChangeActionCDDL, /*#__PURE__*/Schema.typeSchema(ParameterChangeAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const govActionId = action.govActionId ? yield* ParseResult.encode(GovActionIdFromCDDL)(action.govActionId) : null;
    const protocolParamUpdateRO = yield* ParseResult.encode(ProtocolParamUpdate.FromCDDL)(action.protocolParamUpdate);
    const protocolParamUpdate = new Map();
    for (const [k, v] of protocolParamUpdateRO) protocolParamUpdate.set(k, v);
    const policyHash = action.policyHash ? yield* ParseResult.encode(ScriptHash.FromBytes)(action.policyHash) : null;
    // Return as CBOR tuple
    return [0n, govActionId, protocolParamUpdate, policyHash];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, govActionIdCDDL, protocolParamUpdateCDDL, policyHash] = cddl;
    const govActionId = govActionIdCDDL ? yield* ParseResult.decode(GovActionIdFromCDDL)(govActionIdCDDL) : null;
    const protocolParamUpdate = yield* ParseResult.decode(ProtocolParamUpdate.FromCDDL)(protocolParamUpdateCDDL);
    const policyHashValue = policyHash ? yield* ParseResult.decode(ScriptHash.FromBytes)(policyHash) : null;
    return new ParameterChangeAction({
      govActionId,
      protocolParamUpdate,
      policyHash: policyHashValue
    });
  })
});
/**
 * Hard fork initiation governance action schema.
 * ```
 * According to Conway CDDL: hard_fork_initiation_action =
 *   (1, gov_action_id/ nil, protocol_version, policy_hash/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class HardForkInitiationAction extends /*#__PURE__*/Schema.TaggedClass()("HardForkInitiationAction", {
  govActionId: /*#__PURE__*/Schema.NullOr(GovActionId),
  // gov_action_id / nil
  protocolVersion: ProtocolVersion.ProtocolVersion // protocol_version = [major, minor]
}) {
  toJSON() {
    return {
      _tag: this._tag,
      govActionId: this.govActionId,
      protocolVersion: this.protocolVersion
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof HardForkInitiationAction && Equal.equals(this.govActionId, that.govActionId) && Equal.equals(this.protocolVersion, that.protocolVersion);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(Hash.hash(this.govActionId))(Hash.hash(this.protocolVersion)));
  }
}
/**
 * CDDL schema for HardForkInitiationAction tuple structure.
 * ```
 * Maps to: (1, gov_action_id/ nil, protocol_version, policy_hash/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const HardForkInitiationActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(1n),
/*#__PURE__*/
// action type
Schema.NullOr(GovActionIdCDDL),
// gov_action_id / nil
ProtocolVersion.CDDLSchema // protocol_version = [major, minor]
);
/**
 * CDDL transformation schema for HardForkInitiationAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const HardForkInitiationActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(HardForkInitiationActionCDDL, /*#__PURE__*/Schema.typeSchema(HardForkInitiationAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const govActionId = action.govActionId ? yield* ParseResult.encode(GovActionIdFromCDDL)(action.govActionId) : null;
    const protocolVersion = yield* ParseResult.encode(ProtocolVersion.FromCDDL)(action.protocolVersion);
    // Return as CBOR tuple
    return [1n, govActionId, protocolVersion];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, govActionIdCDDL, protocolVersion] = cddl;
    const govActionId = govActionIdCDDL ? yield* ParseResult.decode(GovActionIdFromCDDL)(govActionIdCDDL) : null;
    const protocolVersionValue = yield* ParseResult.decode(ProtocolVersion.FromCDDL)(protocolVersion);
    return new HardForkInitiationAction({
      govActionId,
      protocolVersion: protocolVersionValue
    });
  })
});
/**
 * Treasury withdrawals governance action schema.
 * ```
 * According to Conway CDDL: treasury_withdrawals_action =
 *   (2, { * reward_account => coin }, policy_hash/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class TreasuryWithdrawalsAction extends /*#__PURE__*/Schema.TaggedClass()("TreasuryWithdrawalsAction", {
  withdrawals: /*#__PURE__*/Schema.Map({
    key: RewardAccount.FromBech32,
    value: Coin.Coin
  }),
  policyHash: /*#__PURE__*/Schema.NullOr(ScriptHash.ScriptHash) // policy_hash / nil
}) {
  toJSON() {
    return {
      _tag: this._tag,
      withdrawals: this.withdrawals,
      policyHash: this.policyHash
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof TreasuryWithdrawalsAction && mapEquals(this.withdrawals, that.withdrawals) && Equal.equals(this.policyHash, that.policyHash);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(mapHash(this.withdrawals))(Hash.hash(this.policyHash)));
  }
}
/**
 * CDDL schema for TreasuryWithdrawalsAction tuple structure.
 * ```
 * Maps to: (2, { * reward_account => coin }, policy_hash/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const TreasuryWithdrawalsActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(2n),
/*#__PURE__*/
// action type
Schema.MapFromSelf({
  key: CBOR.ByteArray,
  // reward_account as bytes
  value: CBOR.Integer // coin as bigint
}), /*#__PURE__*/Schema.NullOr(CBOR.ByteArray) // policy_hash / nil
);
/**
 * CDDL transformation schema for TreasuryWithdrawalsAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const TreasuryWithdrawalsActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(TreasuryWithdrawalsActionCDDL, /*#__PURE__*/Schema.typeSchema(TreasuryWithdrawalsAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const withdrawals = new Map();
    for (const [rewardAccount, coin] of action.withdrawals) {
      const rewardAccountBytes = yield* ParseResult.encode(RewardAccount.FromBytes)(rewardAccount);
      withdrawals.set(rewardAccountBytes, coin);
    }
    const policyHash = action.policyHash ? yield* ParseResult.encode(ScriptHash.FromBytes)(action.policyHash) : null;
    // Return as CBOR tuple
    return [2n, withdrawals, policyHash];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, withdrawals, policyHash] = cddl;
    const policyHashValue = policyHash ? yield* ParseResult.decode(ScriptHash.FromBytes)(policyHash) : null;
    const withdrawalsMap = new Map();
    for (const [rewardAccountBytes, coin] of withdrawals) {
      const rewardAccount = yield* ParseResult.decode(RewardAccount.FromBytes)(rewardAccountBytes);
      withdrawalsMap.set(rewardAccount, coin);
    }
    return new TreasuryWithdrawalsAction({
      withdrawals: withdrawalsMap,
      policyHash: policyHashValue
    });
  })
});
/**
 * No confidence governance action schema.
 * ```
 * According to Conway CDDL: no_confidence =
 *   (3, gov_action_id/ nil)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class NoConfidenceAction extends /*#__PURE__*/Schema.TaggedClass()("NoConfidenceAction", {
  govActionId: /*#__PURE__*/Schema.NullOr(GovActionId) // gov_action_id / nil
}) {
  toJSON() {
    return {
      _tag: this._tag,
      govActionId: this.govActionId
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof NoConfidenceAction && Equal.equals(this.govActionId, that.govActionId);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.hash(this.govActionId));
  }
}
/**
 * CDDL schema for NoConfidenceAction tuple structure.
 * Maps to: (3, gov_action_id/ nil)
 *
 * @since 2.0.0
 * @category schemas
 */
export const NoConfidenceActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(3n),
/*#__PURE__*/
// action type
Schema.NullOr(GovActionIdCDDL) // gov_action_id / nil
);
/**
 * CDDL transformation schema for NoConfidenceAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const NoConfidenceActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(NoConfidenceActionCDDL, /*#__PURE__*/Schema.typeSchema(NoConfidenceAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const govActionId = action.govActionId ? yield* ParseResult.encode(GovActionIdFromCDDL)(action.govActionId) : null;
    // Return as CBOR tuple
    return [3n, govActionId];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, govActionIdCDDL] = cddl;
    const govActionId = govActionIdCDDL ? yield* ParseResult.decode(GovActionIdFromCDDL)(govActionIdCDDL) : null;
    return new NoConfidenceAction({
      govActionId
    });
  })
});
/**
 * Update committee governance action schema.
 * ```
 * According to Conway CDDL: update_committee =
 *   (4, gov_action_id/ nil, set<committee_cold_credential>, { * committee_cold_credential => committee_hot_credential }, unit_interval)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class UpdateCommitteeAction extends /*#__PURE__*/Schema.TaggedClass()("UpdateCommitteeAction", {
  govActionId: /*#__PURE__*/Schema.NullOr(GovActionId),
  // gov_action_id / nil
  membersToRemove: /*#__PURE__*/Schema.Array(CommitteeColdCredential.CommitteeColdCredential.Credential),
  // set<committee_cold_credential>
  membersToAdd: /*#__PURE__*/Schema.Map({
    key: CommitteeColdCredential.CommitteeColdCredential.Credential,
    // committee_cold_credential
    value: EpochNo.EpochNoSchema // epoch_no
  }),
  threshold: UnitInterval.UnitInterval
}) {
  toJSON() {
    return {
      _tag: this._tag,
      govActionId: this.govActionId,
      membersToRemove: this.membersToRemove,
      membersToAdd: this.membersToAdd,
      threshold: this.threshold
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof UpdateCommitteeAction && Equal.equals(this.govActionId, that.govActionId) && arrayEquals(this.membersToRemove, that.membersToRemove) && mapEquals(this.membersToAdd, that.membersToAdd) && Equal.equals(this.threshold, that.threshold);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(Hash.combine(Hash.combine(Hash.hash(this.govActionId))(arrayHash(this.membersToRemove)))(mapHash(this.membersToAdd)))(Hash.hash(this.threshold)));
  }
}
/**
 * CDDL schema for UpdateCommitteeAction tuple structure.
 * ```
 * Maps to: (4, gov_action_id/ nil, set<committee_cold_credential>, { * committee_cold_credential => committee_hot_credential }, unit_interval)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const UpdateCommitteeActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(4n),
/*#__PURE__*/
// action type
Schema.NullOr(GovActionIdCDDL),
/*#__PURE__*/
// gov_action_id / nil
// set<committee_cold_credential> = #6.258([* a0]) / [* a0]
Schema.Union(/*#__PURE__*/CBOR.tag(258, /*#__PURE__*/Schema.Array(CommitteeColdCredential.CommitteeColdCredential.CDDLSchema)), /*#__PURE__*/Schema.Array(CommitteeColdCredential.CommitteeColdCredential.CDDLSchema)),
/*#__PURE__*/
// { * committee_cold_credential => epoch_no }
Schema.MapFromSelf({
  key: CommitteeColdCredential.CommitteeColdCredential.CDDLSchema,
  value: EpochNo.CDDLSchema
}), UnitInterval.CDDLSchema // unit_interval
);
/**
 * CDDL transformation schema for UpdateCommitteeAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const UpdateCommitteeActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(UpdateCommitteeActionCDDL, /*#__PURE__*/Schema.typeSchema(UpdateCommitteeAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const govActionId = action.govActionId ? yield* ParseResult.encode(GovActionIdFromCDDL)(action.govActionId) : null;
    // Encode membersToRemove as tagged set (tag 258) per CDDL
    const removeArr = [];
    for (const cred of action.membersToRemove) {
      const coldCred = yield* ParseResult.encode(CommitteeColdCredential.CommitteeColdCredential.FromCDDL)(cred);
      removeArr.push(coldCred);
    }
    const membersToRemove = CBOR.Tag.make({
      tag: 258,
      value: removeArr
    }, {
      disableValidation: true
    });
    // Encode membersToAdd as map<committee_cold_credential => epoch_no>
    const membersToAdd = new Map();
    for (const [coldCred, epoch] of action.membersToAdd) {
      const coldCredBytes = yield* ParseResult.encode(CommitteeColdCredential.CommitteeColdCredential.FromCDDL)(coldCred);
      const epochNo = yield* ParseResult.encode(EpochNo.FromCDDL)(epoch);
      membersToAdd.set(coldCredBytes, epochNo);
    }
    // Encode threshold as UnitInterval
    const threshold = yield* ParseResult.encode(UnitInterval.FromCDDL)(action.threshold);
    // Return as CBOR tuple
    return [4n, govActionId, membersToRemove, membersToAdd, threshold];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, govActionIdCDDL, membersToRemoveCDDL, membersToAddCDDL, thresholdCDDL] = cddl;
    const govActionId = govActionIdCDDL ? yield* ParseResult.decode(GovActionIdFromCDDL)(govActionIdCDDL) : null;
    const threshold = yield* ParseResult.decode(UnitInterval.FromCDDL)(thresholdCDDL);
    // Decode set into an array of credentials (accept tag 258 or plain array)
    const membersToRemove = [];
    const removeArr = CBOR.isTag(membersToRemoveCDDL) ? membersToRemoveCDDL.tag === 258 ? membersToRemoveCDDL.value : [] : membersToRemoveCDDL;
    for (const coldCredCDDL of removeArr) {
      const coldCred = yield* ParseResult.decode(CommitteeColdCredential.CommitteeColdCredential.FromCDDL)(coldCredCDDL);
      membersToRemove.push(coldCred);
    }
    const membersToAdd = new Map();
    for (const [coldCredCDDL, epochNoCDDL] of membersToAddCDDL) {
      const coldCred = yield* ParseResult.decode(CommitteeColdCredential.CommitteeColdCredential.FromCDDL)(coldCredCDDL);
      const epoch = yield* ParseResult.decode(EpochNo.FromCDDL)(epochNoCDDL);
      membersToAdd.set(coldCred, epoch);
    }
    return new UpdateCommitteeAction({
      govActionId,
      membersToRemove,
      membersToAdd,
      threshold
    });
  })
});
/**
 * New constitution governance action schema.
 * According to Conway CDDL: new_constitution =
 *   (5, gov_action_id/ nil, constitution)
 *
 * @since 2.0.0
 * @category schemas
 */
export class NewConstitutionAction extends /*#__PURE__*/Schema.TaggedClass()("NewConstitutionAction", {
  govActionId: /*#__PURE__*/Schema.NullOr(GovActionId),
  // gov_action_id / nil
  constitution: Constitution.Constitution // constitution as CBOR
}) {
  toJSON() {
    return {
      _tag: this._tag,
      govActionId: this.govActionId,
      constitution: this.constitution
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof NewConstitutionAction && Equal.equals(this.govActionId, that.govActionId) && Equal.equals(this.constitution, that.constitution);
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.combine(Hash.hash(this.govActionId))(Hash.hash(this.constitution)));
  }
}
/**
 * CDDL schema for NewConstitutionAction tuple structure.
 * ```
 * Maps to: (5, gov_action_id/ nil, constitution)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const NewConstitutionActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(5n),
/*#__PURE__*/
// action type
Schema.NullOr(GovActionIdCDDL),
// gov_action_id / nil
Constitution.CDDLSchema // constitution as CBOR
);
/**
 * CDDL transformation schema for NewConstitutionAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const NewConstitutionActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(NewConstitutionActionCDDL, /*#__PURE__*/Schema.typeSchema(NewConstitutionAction), {
  strict: true,
  encode: action => Eff.gen(function* () {
    const govActionId = action.govActionId ? yield* ParseResult.encode(GovActionIdFromCDDL)(action.govActionId) : null;
    const constitution = yield* ParseResult.encode(Constitution.FromCDDL)(action.constitution);
    // Return as CBOR tuple
    return [5n, govActionId, constitution];
  }),
  decode: cddl => Eff.gen(function* () {
    const [, govActionIdCDDL, constitutionCDDL] = cddl;
    const govActionId = govActionIdCDDL ? yield* ParseResult.decode(GovActionIdFromCDDL)(govActionIdCDDL) : null;
    const constitution = yield* ParseResult.decode(Constitution.FromCDDL)(constitutionCDDL);
    return new NewConstitutionAction({
      govActionId,
      constitution
    });
  })
});
/**
 * Info governance action schema.
 * ```
 * According to Conway CDDL: info_action = (6)
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export class InfoAction extends /*#__PURE__*/Schema.TaggedClass()("InfoAction", {
  // Info action has no additional data
}) {
  toJSON() {
    return {
      _tag: this._tag
    };
  }
  toString() {
    return Inspectable.format(this.toJSON());
  }
  [Inspectable.NodeInspectSymbol]() {
    return this.toJSON();
  }
  [Equal.symbol](that) {
    return that instanceof InfoAction;
  }
  [Hash.symbol]() {
    return Hash.cached(this, Hash.string("InfoAction"));
  }
}
/**
 * CDDL schema for InfoAction tuple structure.
 * Maps to: (6)
 *
 * @since 2.0.0
 * @category schemas
 */
export const InfoActionCDDL = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Literal(6n) // action type
);
/**
 * CDDL transformation schema for InfoAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const InfoActionFromCDDL = /*#__PURE__*/Schema.transformOrFail(InfoActionCDDL, /*#__PURE__*/Schema.typeSchema(InfoAction), {
  strict: true,
  encode: _action => Eff.gen(function* () {
    // Return as CBOR tuple
    return [6n];
  }),
  decode: _cddl => Eff.gen(function* () {
    return new InfoAction({});
  })
});
/**
 * GovernanceAction union schema based on Conway CDDL specification.
 *
 * ```
 * governance_action =
 *   [ 0, parameter_change_action ]
 * / [ 1, hard_fork_initiation_action ]
 * / [ 2, treasury_withdrawals_action ]
 * / [ 3, no_confidence ]
 * / [ 4, update_committee ]
 * / [ 5, new_constitution ]
 * / [ 6, info_action ]
 * ```
 *
 * @since 2.0.0
 * @category schemas
 */
export const GovernanceAction = /*#__PURE__*/Schema.Union(ParameterChangeAction, HardForkInitiationAction, TreasuryWithdrawalsAction, NoConfidenceAction, UpdateCommitteeAction, NewConstitutionAction, InfoAction);
/**
 * CDDL schema for GovernanceAction tuple structure.
 * Maps action types to their data according to Conway specification.
 *
 * @since 2.0.0
 * @category schemas
 */
export const CDDLSchema = /*#__PURE__*/Schema.Union(ParameterChangeActionCDDL, HardForkInitiationActionCDDL, TreasuryWithdrawalsActionCDDL, NoConfidenceActionCDDL, UpdateCommitteeActionCDDL, NewConstitutionActionCDDL, InfoActionCDDL);
/**
 * CDDL transformation schema for GovernanceAction.
 *
 * @since 2.0.0
 * @category schemas
 */
export const FromCDDL = /*#__PURE__*/Schema.Union(ParameterChangeActionFromCDDL, HardForkInitiationActionFromCDDL, TreasuryWithdrawalsActionFromCDDL, NoConfidenceActionFromCDDL, UpdateCommitteeActionFromCDDL, NewConstitutionActionFromCDDL, InfoActionFromCDDL);
/**
 * FastCheck arbitrary for GovernanceAction.
 *
 * @since 2.0.0
 * @category arbitrary
 */
// Per-variant arbitraries and main arbitrary
export const infoArbitrary = /*#__PURE__*/FastCheck.constant(/*#__PURE__*/new InfoAction({}));
export const govActionIdArbitrary = /*#__PURE__*/FastCheck.tuple(TransactionHash.arbitrary, TransactionIndex.arbitrary).map(([transactionId, govActionIndex]) => new GovActionId({
  transactionId,
  govActionIndex
}));
export const parameterChangeArbitrary = /*#__PURE__*/FastCheck.tuple(FastCheck.option(govActionIdArbitrary, {
  nil: null
}), ProtocolParamUpdate.arbitrary, FastCheck.option(ScriptHash.arbitrary, {
  nil: null
})).map(([govActionId, protocolParamUpdate, policyHash]) => new ParameterChangeAction({
  govActionId,
  protocolParamUpdate,
  policyHash
}));
export const hardForkInitiationArbitrary = /*#__PURE__*/FastCheck.tuple(FastCheck.option(govActionIdArbitrary, {
  nil: null
}), ProtocolVersion.arbitrary).map(([govActionId, protocolVersion]) => new HardForkInitiationAction({
  govActionId,
  protocolVersion
}));
const withdrawalsMapArbitrary = /*#__PURE__*/FastCheck.uniqueArray(RewardAccount.arbitrary, {
  maxLength: 5,
  selector: ra => RewardAccount.toHex(ra)
}).chain(accounts => FastCheck.array(Coin.arbitrary, {
  minLength: accounts.length,
  maxLength: accounts.length
}).map(coins => new Map(accounts.map((a, i) => [a, coins[i]]))));
export const treasuryWithdrawalsArbitrary = /*#__PURE__*/FastCheck.tuple(withdrawalsMapArbitrary, FastCheck.option(ScriptHash.arbitrary, {
  nil: null
})).map(([withdrawals, policyHash]) => new TreasuryWithdrawalsAction({
  withdrawals,
  policyHash
}));
export const noConfidenceArbitrary = /*#__PURE__*/FastCheck.option(govActionIdArbitrary, {
  nil: null
}).map(govActionId => new NoConfidenceAction({
  govActionId
}));
const uniqueCredArray = /*#__PURE__*/FastCheck.uniqueArray(Credential.arbitrary, {
  maxLength: 5,
  selector: c => `${c._tag}:${Bytes.toHex(c.hash)}`
});
const membersToAddMapArbitrary = /*#__PURE__*/uniqueCredArray.chain(colds => FastCheck.array(EpochNo.arbitrary, {
  minLength: colds.length,
  maxLength: colds.length
}).map(epochsRaw => {
  const epochs = epochsRaw;
  const m = new Map();
  for (let i = 0; i < colds.length; i++) m.set(colds[i], epochs[i]);
  return m;
}));
export const updateCommitteeArbitrary = /*#__PURE__*/FastCheck.tuple(FastCheck.option(govActionIdArbitrary, {
  nil: null
}), uniqueCredArray, membersToAddMapArbitrary, UnitInterval.arbitrary).map(([govActionId, membersToRemove, membersToAdd, threshold]) => new UpdateCommitteeAction({
  govActionId,
  membersToRemove,
  membersToAdd,
  threshold
}));
export const newConstitutionArbitrary = /*#__PURE__*/FastCheck.tuple(FastCheck.option(govActionIdArbitrary, {
  nil: null
}), Constitution.arbitrary).map(([govActionId, constitution]) => new NewConstitutionAction({
  govActionId,
  constitution
}));
export const arbitrary = /*#__PURE__*/FastCheck.oneof(parameterChangeArbitrary, hardForkInitiationArbitrary, updateCommitteeArbitrary, treasuryWithdrawalsArbitrary, noConfidenceArbitrary, newConstitutionArbitrary, infoArbitrary);
/**
 * Check if a value is a valid GovernanceAction.
 *
 * @since 2.0.0
 * @category predicates
 */
export const is = /*#__PURE__*/Schema.is(GovernanceAction);
/**
 * Type guards for each governance action variant.
 *
 * @since 2.0.0
 * @category type guards
 */
export const isParameterChangeAction = /*#__PURE__*/Schema.is(ParameterChangeAction);
export const isHardForkInitiationAction = /*#__PURE__*/Schema.is(HardForkInitiationAction);
export const isTreasuryWithdrawalsAction = /*#__PURE__*/Schema.is(TreasuryWithdrawalsAction);
export const isNoConfidenceAction = /*#__PURE__*/Schema.is(NoConfidenceAction);
export const isUpdateCommitteeAction = /*#__PURE__*/Schema.is(UpdateCommitteeAction);
export const isNewConstitutionAction = /*#__PURE__*/Schema.is(NewConstitutionAction);
export const isInfoAction = /*#__PURE__*/Schema.is(InfoAction);
/**
 * Pattern matching utility for GovernanceAction.
 *
 * @since 2.0.0
 * @category pattern matching
 */
export const match = (action, patterns) => {
  switch (action._tag) {
    case "ParameterChangeAction":
      return patterns.ParameterChangeAction(action.govActionId, action.protocolParamUpdate, action.policyHash);
    case "HardForkInitiationAction":
      return patterns.HardForkInitiationAction(action.govActionId, action.protocolVersion);
    case "TreasuryWithdrawalsAction":
      return patterns.TreasuryWithdrawalsAction(action.withdrawals, action.policyHash);
    case "NoConfidenceAction":
      return patterns.NoConfidenceAction(action.govActionId);
    case "UpdateCommitteeAction":
      return patterns.UpdateCommitteeAction(action.govActionId, action.membersToRemove, action.membersToAdd, action.threshold);
    case "NewConstitutionAction":
      return patterns.NewConstitutionAction(action.govActionId, action.constitution);
    case "InfoAction":
      return patterns.InfoAction();
  }
};
/**
 * Parse GovernanceAction from CBOR hex string.
 *
 * @since 2.0.0
 * @category parsing
 */
export const fromCBORHex = (hex, options = CBOR.CML_DEFAULT_OPTIONS) => {
  const bytes = Bytes.fromHex(hex);
  return fromCBOR(bytes, options);
};
/**
 * Encode GovernanceAction to CBOR hex string.
 *
 * @since 2.0.0
 * @category encoding
 */
export const toCBORHex = (data, options = CBOR.CML_DEFAULT_OPTIONS) => {
  const bytes = toCBOR(data, options);
  return Bytes.toHex(bytes);
};
/**
 * Parse GovernanceAction from CBOR bytes.
 *
 * @since 2.0.0
 * @category parsing
 */
export const fromCBOR = (bytes, options = CBOR.CML_DEFAULT_OPTIONS) => {
  const cddl = CBOR.fromCBORBytes(bytes, options);
  return Schema.decodeSync(FromCDDL)(cddl);
};
/**
 * Encode GovernanceAction to CBOR bytes.
 *
 * @since 2.0.0
 * @category encoding
 */
export const toCBOR = (data, options = CBOR.CML_DEFAULT_OPTIONS) => {
  const cddl = Schema.encodeSync(FromCDDL)(data);
  return CBOR.toCBORBytes(cddl, options);
};
//# sourceMappingURL=GovernanceAction.js.map