import {
  addAssets,
  Emulator,
  fromHex,
  fromText,
  generateEmulatorAccount,
  generateEmulatorAccountFromPrivateKey,
  Lucid,
  paymentCredentialOf,
  PROTOCOL_PARAMETERS_DEFAULT,
  ProtocolParameters,
} from '@lucid-evolution/lucid';
import {
  AssetClass,
  mkAssetsOf,
  mkLovelacesOf,
} from '@3rd-eye-labs/cardano-offchain-common';
import { IndigoTestContext } from './test-helpers';
import { init } from './endpoints/initialize';
import { iusdInitialAssetCfg } from './mock/assets-mock';

export const MAINNET_PROTOCOL_PARAMETERS: ProtocolParameters = {
  ...PROTOCOL_PARAMETERS_DEFAULT,
  maxTxExMem: 16500000n,
};

export const EXAMPLE_TOKEN_1: AssetClass = {
  currencySymbol: fromHex(
    '00000000000000000000000000000000000000000000000000000000',
  ),
  tokenName: fromHex(fromText('example-token-1')),
};
export const EXAMPLE_TOKEN_2: AssetClass = {
  currencySymbol: fromHex(
    '00000000000000000000000000000000000000000000000000000001',
  ),
  tokenName: fromHex(fromText('example-token-2')),
};
export const EXAMPLE_TOKEN_3: AssetClass = {
  currencySymbol: fromHex(
    '00000000000000000000000000000000000000000000000000000002',
  ),
  tokenName: fromHex(fromText('example-token-3')),
};

export async function createIndigoTestContext(
  context: IndigoTestContext,
): Promise<void> {
  context.users = {
    admin: generateEmulatorAccount(
      addAssets(
        mkLovelacesOf(100_000_000_000_000n),
        mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000_000_000n),
      ),
    ),
    user: generateEmulatorAccount(
      addAssets(
        mkLovelacesOf(100_000_000_000_000n),
        mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000_000_000n),
        mkAssetsOf(EXAMPLE_TOKEN_2, 1_000_000_000_000_000n),
        mkAssetsOf(EXAMPLE_TOKEN_3, 1_000_000_000_000_000n),
      ),
    ),
    user2: generateEmulatorAccount({
      lovelace: BigInt(100_000_000_000_000),
    }),
    withdrawalAccount: generateEmulatorAccountFromPrivateKey({}),
  };

  context.emulator = new Emulator(
    [
      context.users.admin,
      context.users.user,
      context.users.user2,
      context.users.withdrawalAccount,
    ],
    MAINNET_PROTOCOL_PARAMETERS,
  );
  context.lucid = await Lucid(context.emulator, 'Custom');
  context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);

  const [systemParams, assetConfigs] = await init(
    context.lucid,
    [iusdInitialAssetCfg()],
    context.emulator.slot,
    () => [],
    {
      foundationMultisig: {
        Signature: {
          keyHash: fromHex(
            paymentCredentialOf(context.users.admin.address).hash,
          ),
        },
      },
    },
  );

  context.systemParams = systemParams;
  context.assetConfigs = assetConfigs;
}
