/*
 This file is part of GNU Taler
 (C) 2025 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

/**
 * Imports.
 */
import {
  j2s,
  Logger,
  MerchantAccountKycStatus,
  succeedOrThrow,
  TalerExchangeHttpClient,
  TalerMerchantInstanceHttpClient,
} from "@gnu-taler/taler-util";
import { GlobalTestState, harnessHttpLib } from "../harness/harness.js";
import { createTopsEnvironment, doTopsKycAuth } from "../harness/tops.js";

export const logger = new Logger("test-tops-aml.ts");

/**
 * Test for ToS acceptance by the merchant.
 * In particular, we test that long-polling works and
 * we do not manually have to run taler-merchant-kyccheck with the -t option.
 */
export async function runTopsMerchantTosTest(t: GlobalTestState) {
  // Set up test environment
  const {
    exchange,
    officerAcc,
    merchant,
    exchangeBankAccount,
    wireGatewayApi,
    merchantAdminAccessToken,
    bank,
  } = await createTopsEnvironment(t);

  const merchantClient = new TalerMerchantInstanceHttpClient(
    merchant.makeInstanceBaseUrl(),
  );
  const exchangeClient = new TalerExchangeHttpClient(exchange.baseUrl, {
    httpClient: harnessHttpLib,
  });

  // Do KYC auth transfer
  const { accessToken } = await doTopsKycAuth(t, {
    merchantClient,
    exchangeBankAccount,
    wireGatewayApi,
    merchantAdminAccessToken,
    bank,
  });

  {
    const kycInfo = await exchangeClient.checkKycInfo(
      accessToken,
      undefined,
      undefined,
    );
    console.log(j2s(kycInfo));

    t.assertDeepEqual(kycInfo.case, "ok");
    t.assertDeepEqual(kycInfo.body.requirements.length, 1);
    t.assertDeepEqual(kycInfo.body.requirements[0].form, "accept-tos");
    const requirementId = kycInfo.body.requirements[0].id;
    t.assertTrue(typeof requirementId === "string");

    const uploadRes = await exchangeClient.uploadKycForm(requirementId, {
      FORM_ID: "accept-tos",
      FORM_VERSION: 1,
      ACCEPTED_TERMS_OF_SERVICE: "v1",
      DOWNLOADED_TERMS_OF_SERVICE: true,
    });
    console.log("upload res", uploadRes);
    t.assertDeepEqual(uploadRes.case, "ok");
  }

  {
    const kycInfo = await exchangeClient.checkKycInfo(
      accessToken,
      undefined,
      undefined,
    );
    console.log(j2s(kycInfo));
  }

  {
    const kycStatus = succeedOrThrow(
      await merchantClient.getCurrentInstanceKycStatus(
        merchantAdminAccessToken,
        {
          exchangeURL: exchange.baseUrl,
          longpoll: {
            type: "state-enter",
            status: MerchantAccountKycStatus.READY,
            timeout: 10000,
          },
        },
      ),
    );
    logger.info(`kyc status after accept-tos: ${j2s(kycStatus)}`);
    const myRow = kycStatus.kyc_data.find(
      (x) => x.exchange_url === exchange.baseUrl,
    );
    t.assertTrue(myRow != null);
    t.assertDeepEqual(myRow.status, MerchantAccountKycStatus.READY);
  }
}

runTopsMerchantTosTest.suites = ["wallet"];
