import { FetchHttpClient } from "@effect/platform";
import { Effect, pipe, Schema } from "effect";
import * as CoreAddress from "../../../Address.js";
import * as CoreAssets from "../../../Assets.js";
import * as Bytes from "../../../Bytes.js";
import * as PlutusData from "../../../Data.js";
import * as DatumHash from "../../../DatumHash.js";
import * as InlineDatum from "../../../InlineDatum.js";
import * as NativeScripts from "../../../NativeScripts.js";
import * as PlutusV1 from "../../../PlutusV1.js";
import * as PlutusV2 from "../../../PlutusV2.js";
import * as PlutusV3 from "../../../PlutusV3.js";
import * as TransactionHash from "../../../TransactionHash.js";
import * as CoreUTxO from "../../../UTxO.js";
import * as HttpUtils from "./HttpUtils.js";
export const ProtocolParametersSchema = /*#__PURE__*/Schema.Struct({
  pvt_motion_no_confidence: Schema.Number,
  pvt_committee_normal: Schema.Number,
  pvt_committee_no_confidence: Schema.Number,
  pvt_hard_fork_initiation: Schema.Number,
  pvtpp_security_group: Schema.Number,
  dvt_motion_no_confidence: Schema.Number,
  dvt_committee_normal: Schema.Number,
  dvt_committee_no_confidence: Schema.Number,
  dvt_update_to_constitution: Schema.Number,
  dvt_hard_fork_initiation: Schema.Number,
  dvt_p_p_network_group: Schema.Number,
  dvt_p_p_economic_group: Schema.Number,
  dvt_p_p_technical_group: Schema.Number,
  dvt_p_p_gov_group: Schema.Number,
  dvt_treasury_withdrawal: Schema.Number,
  committee_min_size: Schema.Number,
  committee_max_term_length: Schema.Number,
  gov_action_lifetime: Schema.Number,
  gov_action_deposit: Schema.NumberFromString,
  drep_deposit: Schema.NumberFromString,
  drep_activity: Schema.Number,
  min_fee_ref_script_cost_per_byte: Schema.Number,
  epoch_no: Schema.Number,
  min_fee_a: Schema.Number,
  min_fee_b: Schema.Number,
  max_block_size: Schema.Number,
  max_tx_size: Schema.Number,
  max_bh_size: Schema.Number,
  key_deposit: Schema.BigInt,
  pool_deposit: Schema.BigInt,
  max_epoch: Schema.Number,
  optimal_pool_count: Schema.Number,
  influence: Schema.Number,
  monetary_expand_rate: Schema.Number,
  treasury_growth_rate: Schema.Number,
  decentralisation: Schema.Number,
  extra_entropy: /*#__PURE__*/Schema.NullOr(Schema.String),
  protocol_major: Schema.Number,
  protocol_minor: Schema.Number,
  min_utxo_value: Schema.String,
  min_pool_cost: Schema.String,
  nonce: /*#__PURE__*/Schema.NullOr(Schema.String),
  block_hash: /*#__PURE__*/Schema.NullOr(Schema.String),
  cost_models: /*#__PURE__*/Schema.Struct({
    PlutusV1: /*#__PURE__*/Schema.Array(Schema.Number),
    PlutusV2: /*#__PURE__*/Schema.Array(Schema.Number),
    PlutusV3: /*#__PURE__*/Schema.Array(Schema.Number)
  }),
  price_mem: Schema.Number,
  price_step: Schema.Number,
  max_tx_ex_mem: Schema.BigIntFromNumber,
  max_tx_ex_steps: Schema.BigIntFromNumber,
  max_block_ex_mem: Schema.Number,
  max_block_ex_steps: Schema.Number,
  max_val_size: Schema.Number,
  collateral_percent: Schema.Number,
  max_collateral_inputs: Schema.Number,
  coins_per_utxo_size: Schema.BigInt
});
export const AssetSchema = /*#__PURE__*/Schema.Struct({
  policy_id: Schema.String,
  asset_name: /*#__PURE__*/Schema.NullOr(Schema.String),
  fingerprint: Schema.String,
  decimals: Schema.Number,
  quantity: Schema.String
});
const ReferenceScriptSchema = /*#__PURE__*/Schema.Struct({
  hash: /*#__PURE__*/Schema.NullOr(Schema.String),
  size: /*#__PURE__*/Schema.NullOr(Schema.Number),
  type: /*#__PURE__*/Schema.NullOr(Schema.String),
  bytes: /*#__PURE__*/Schema.NullOr(Schema.String),
  value: Schema.Unknown
});
export const UTxOSchema = /*#__PURE__*/Schema.Struct({
  tx_hash: Schema.String,
  tx_index: Schema.Number,
  block_time: Schema.Number,
  block_height: /*#__PURE__*/Schema.NullOr(Schema.Number),
  value: Schema.String,
  datum_hash: /*#__PURE__*/Schema.NullOr(Schema.String),
  inline_datum: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Struct({
    bytes: /*#__PURE__*/Schema.NullOr(Schema.String),
    value: Schema.Unknown
  })),
  reference_script: /*#__PURE__*/Schema.NullOr(ReferenceScriptSchema),
  asset_list: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(AssetSchema))
});
export const AddressInfoSchema = /*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.NullishOr(/*#__PURE__*/Schema.Struct({
  address: Schema.String,
  balance: Schema.String,
  stake_address: /*#__PURE__*/Schema.NullOr(Schema.String),
  script_address: Schema.Boolean,
  utxo_set: /*#__PURE__*/Schema.Array(UTxOSchema)
})));
export const InputOutputSchema = /*#__PURE__*/Schema.Struct({
  payment_addr: /*#__PURE__*/Schema.Struct({
    bech32: Schema.String,
    cred: Schema.String
  }),
  stake_addr: /*#__PURE__*/Schema.NullOr(Schema.String),
  tx_hash: Schema.String,
  tx_index: Schema.Number,
  value: Schema.String,
  datum_hash: /*#__PURE__*/Schema.NullOr(Schema.String),
  inline_datum: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Struct({
    bytes: /*#__PURE__*/Schema.NullOr(Schema.String),
    value: Schema.Unknown
  })),
  reference_script: /*#__PURE__*/Schema.NullOr(ReferenceScriptSchema),
  // Koios can return asset_list as a Haskell show-formatted string on some endpoints (e.g. collateral
  // outputs with many assets). Treat any string as null to avoid a parse failure in those cases.
  asset_list: /*#__PURE__*/Schema.Union(/*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(AssetSchema)), /*#__PURE__*/Schema.transform(Schema.String, Schema.Null, {
    decode: () => null,
    encode: () => ""
  }))
});
export const TxInfoSchema = /*#__PURE__*/Schema.Struct({
  tx_hash: Schema.String,
  block_hash: Schema.String,
  block_height: Schema.Number,
  epoch_no: Schema.Number,
  epoch_slot: Schema.Number,
  absolute_slot: Schema.Number,
  tx_timestamp: Schema.Number,
  tx_block_index: Schema.Number,
  tx_size: Schema.Number,
  total_output: Schema.String,
  fee: Schema.String,
  treasury_donation: Schema.String,
  deposit: Schema.String,
  invalid_before: /*#__PURE__*/Schema.NullOr(Schema.String),
  invalid_after: /*#__PURE__*/Schema.NullOr(Schema.String),
  collateral_inputs: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(InputOutputSchema)),
  collateral_output: /*#__PURE__*/Schema.NullOr(InputOutputSchema),
  reference_inputs: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(InputOutputSchema)),
  inputs: /*#__PURE__*/Schema.Array(InputOutputSchema),
  outputs: /*#__PURE__*/Schema.Array(InputOutputSchema),
  withdrawals: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
    amount: Schema.String,
    stake_addr: Schema.String
  }))),
  assets_minted: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(AssetSchema)),
  metadata: /*#__PURE__*/Schema.NullOr(Schema.Object),
  certificates: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
    index: Schema.Number,
    type: Schema.String,
    info: /*#__PURE__*/Schema.NullOr(Schema.Object)
  }))),
  native_scripts: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
    script_hash: Schema.String,
    script_json: Schema.Object
  }))),
  plutus_contracts: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
    address: Schema.String,
    spends_input: /*#__PURE__*/Schema.NullOr(/*#__PURE__*/Schema.Struct({
      tx_hash: Schema.String,
      tx_index: Schema.Number
    })),
    script_hash: Schema.String,
    bytecode: Schema.String,
    size: Schema.Number,
    valid_contract: Schema.Boolean,
    input: /*#__PURE__*/Schema.Struct({
      redeemer: /*#__PURE__*/Schema.Struct({
        purpose: /*#__PURE__*/Schema.Literal("spend", "mint", "cert", "reward"),
        fee: Schema.String,
        unit: /*#__PURE__*/Schema.Struct({
          steps: Schema.String,
          mem: Schema.String
        }),
        datum: /*#__PURE__*/Schema.Struct({
          hash: /*#__PURE__*/Schema.NullOr(Schema.String),
          value: /*#__PURE__*/Schema.NullOr(Schema.Object)
        })
      }),
      datum: /*#__PURE__*/Schema.Struct({
        hash: /*#__PURE__*/Schema.NullOr(Schema.String),
        value: /*#__PURE__*/Schema.NullOr(Schema.Object)
      })
    })
  }))),
  //TODO: add Schema.Struct
  // https://preprod.koios.rest/#post-/tx_info
  voting_procedures: /*#__PURE__*/Schema.Array(Schema.Object),
  //TODO: add Schema.Struct
  // https://preprod.koios.rest/#post-/tx_info
  proposal_procedures: /*#__PURE__*/Schema.Array(Schema.Object)
});
export const TxHashSchema = Schema.String;
export const AssetAddressSchema = /*#__PURE__*/Schema.Struct({
  payment_address: Schema.String,
  stake_address: /*#__PURE__*/Schema.NullOr(Schema.String),
  quantity: Schema.String
});
//NOTE: account_info schema is not complete
// https://preprod.koios.rest/#post-/account_info
export const AccountInfoSchema = /*#__PURE__*/Schema.Struct({
  delegated_pool: /*#__PURE__*/Schema.NullOr(Schema.String),
  rewards_available: Schema.NumberFromString
});
//NOTE: datum_info schema is not complete
// https://preprod.koios.rest/#post-/datum_info
export const DatumInfo = /*#__PURE__*/Schema.Struct({
  bytes: Schema.String
});
export const getHeadersWithToken = (token, headers = {}) => {
  if (token) {
    return {
      ...headers,
      Authorization: `Bearer ${token}`
    };
  }
  return headers;
};
export const toUTxO = (koiosUTxO, addressStr) => {
  // Build Core Assets
  const lovelace = BigInt(koiosUTxO.value);
  let assets = CoreAssets.fromLovelace(lovelace);
  if (koiosUTxO.asset_list) {
    for (const am of koiosUTxO.asset_list) {
      // policy_id is hex (56 chars), asset_name is hex
      assets = CoreAssets.addByHex(assets, am.policy_id, am.asset_name || "", BigInt(am.quantity));
    }
  }
  const address = CoreAddress.fromBech32(addressStr);
  const transactionId = TransactionHash.fromHex(koiosUTxO.tx_hash);
  let datumOption;
  if (koiosUTxO.inline_datum?.bytes) {
    datumOption = new InlineDatum.InlineDatum({
      data: PlutusData.fromCBORHex(koiosUTxO.inline_datum.bytes)
    });
  } else if (koiosUTxO.datum_hash) {
    datumOption = DatumHash.fromHex(koiosUTxO.datum_hash);
  }
  let scriptRef;
  const rs = koiosUTxO.reference_script;
  if (rs?.bytes && rs.type) {
    const scriptBytes = Bytes.fromHex(rs.bytes);
    switch (rs.type) {
      case "plutusV1":
        scriptRef = new PlutusV1.PlutusV1({
          bytes: scriptBytes
        });
        break;
      case "plutusV2":
        scriptRef = new PlutusV2.PlutusV2({
          bytes: scriptBytes
        });
        break;
      case "plutusV3":
        scriptRef = new PlutusV3.PlutusV3({
          bytes: scriptBytes
        });
        break;
      case "timelock":
        scriptRef = NativeScripts.fromCBORHex(rs.bytes);
        break;
    }
  }
  return new CoreUTxO.UTxO({
    transactionId,
    index: BigInt(koiosUTxO.tx_index),
    address,
    assets,
    datumOption,
    scriptRef
  });
};
export const getUtxosEffect = (baseUrl, addressOrCredential, headers) => {
  const url = `${baseUrl}/address_info`;
  const body = {
    _addresses: [addressOrCredential]
  };
  const schema = AddressInfoSchema;
  const result = pipe(Effect.if(typeof addressOrCredential === "string", {
    onFalse: () => Effect.fail("Credential Type is not supported in Koios yet."),
    onTrue: () => HttpUtils.postJson(url, body, schema, headers)
  }), Effect.map(([result]) => result ? result.utxo_set.map(koiosUtxo => toUTxO(koiosUtxo, result.address)) : []), Effect.provide(FetchHttpClient.layer));
  return result;
};
//# sourceMappingURL=Koios.js.map