/* eslint-disable @typescript-eslint/no-var-requires */

import { expect } from "chai";
import { RequestError } from "@altangent/lib-http";
import { BlockbookClient } from "../lib/BlockbookClient";
import { expectBlockEqual } from "./Utils";

describe("BlockbookClient", () => {
    let sut: BlockbookClient;

    before(() => {
        sut = new BlockbookClient("https://bb.altangent.com");
    });

    describe(".status()", () => {
        it("returns result", async () => {
            const result = await sut.status();
            expect(result.blockbook.coin).to.equal("Bitcoin");
        });
    });

    describe(".blockhash()", () => {
        it("returns result", async () => {
            const result = await sut.blockhash(0);
            expect(result.blockHash).to.equal(
                "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
            );
        });
    });

    describe(".tx()", () => {
        it("returns tx", async () => {
            const tx = await sut.tx(
                "ed25927576988e38e4cc8e4b19d1272c480f113fb605271b190df05aa983714e",
            );
            expect(tx.txid).to.equal(
                "ed25927576988e38e4cc8e4b19d1272c480f113fb605271b190df05aa983714e",
            );
            expect(tx.version).to.equal(1);
            expect(tx.blockHash).to.equal(
                "0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959",
            );
            expect(tx.blockHeight).to.equal(700000);
            expect(tx.confirmations).to.be.gte(12095);
            expect(tx.blockTime).to.equal(1631333672);
            expect(tx.value).to.equal("333459");
            expect(tx.valueIn).to.equal("383459");
            expect(tx.fees).to.equal("50000");
            expect(tx.hex).to.equal(
                "01000000000101f057df1cb733e48ee88a73ff66948896b002616cab442b40eb557d6eab0786620100000000ffffffff02c8a901000000000017a914e2674c704f478f20a18282eb00cb5a4b4bd6fe8987cb6c030000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d040047304402207baadc4b646b9214554c195f8b03e0ef1813343888a01e654b718c9d8dbae4870220454d18d6d5fc5f04ce7b3973534328390602b707dcdc75cac4024740e1e7c92b0147304402201a2edad7aeb85cca3d20514da7ee6ae15d6bb957aa8c11a623cd6f88595fdaad022013847f3361abe78a88107fb8d77d671b3505c5c8041f7a03be3142c21080d155016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000",
            );

            expect(tx.vin.length).to.equal(1);
            expect(tx.vin[0].txid).to.equal(
                "628607ab6e7d55eb402b44ab6c6102b096889466ff738ae88ee433b71cdf57f0",
            );
            expect(tx.vin[0].vout).to.equal(1);
            expect(tx.vin[0].sequence).to.equal(4294967295);
            expect(tx.vin[0].n).to.equal(0);
            expect(tx.vin[0].addresses[0]).to.equal(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(tx.vin[0].isAddress).to.equal(true);
            expect(tx.vin[0].value).to.equal("383459");

            expect(tx.vout.length).to.equal(2);
            expect(tx.vout[0].value).to.equal("109000");
            expect(tx.vout[0].n).to.equal(0);
            expect(tx.vout[0].spent).to.be.a("boolean");
            expect(tx.vout[0].hex).to.equal("a914e2674c704f478f20a18282eb00cb5a4b4bd6fe8987");
            expect(tx.vout[0].addresses[0]).to.equal("3NL8PD5zsy8Xp396E951C5UuFVtK6dAJNt");
            expect(tx.vout[0].isAddress).to.equal(true);

            expect(tx.vout[1].value).to.equal("224459");
            expect(tx.vout[1].n).to.equal(1);
            expect(tx.vout[1].spent).to.be.a("boolean");
            expect(tx.vout[1].hex).to.equal(
                "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d",
            );
            expect(tx.vout[1].addresses[0]).to.equal(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(tx.vout[1].isAddress).to.equal(true);
        });

        it("not found", done => {
            sut.tx("ed25927576988e38e4cc8e4b19d1272c480f113fb605271b190df05aa983714f")
                .then(() => {
                    done(new Error("expected failure"));
                })
                .catch(ex => {
                    expect(ex).to.be.instanceOf(RequestError);
                    done();
                });
        });
    });

    describe(".address()", () => {
        it("returns results", async () => {
            const result = await sut.address(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(result.page).to.equal(1);
            expect(result.totalPages).to.be.gte(902);
            expect(result.itemsOnPage).to.equal(1000);
            expect(result.address).to.equal(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(result.balance).to.be.a("string");
            expect(Number(result.totalReceived)).to.be.gte(300675773149927);
            expect(Number(result.totalSent)).to.be.gte(300672999991857);
            expect(result.unconfirmedBalance).to.be.a("string");
            expect(result.unconfirmedTxs).to.be.a("number");
            expect(result.txs).to.be.gte(901158);
            expect(result.txids.length).to.be.gte(1000);
            expect(result.txids[0]).to.be.a("string");
            expect(result.txids[999]).to.be.a("string");
        });

        it("returns results with pagesize", async () => {
            const result = await sut.address(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
                { page: 1, pageSize: 1 },
            );
            expect(result.page).to.equal(1);
            expect(result.totalPages).to.be.gte(901160);
            expect(result.itemsOnPage).to.equal(1);
            expect(result.address).to.equal(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(result.balance).to.be.a("string");
            expect(Number(result.totalReceived)).to.be.gte(300675773149927);
            expect(Number(result.totalSent)).to.be.gte(300672999991857);
            expect(result.unconfirmedBalance).to.be.a("string");
            expect(result.unconfirmedTxs).to.be.a("number");
            expect(result.txs).to.be.gte(901158);
            expect(result.txids.length).to.be.gte(1);
            expect(result.txids[0]).to.be.a("string");
        });

        it("returns results with blockheight range", async () => {
            const result = await sut.address(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
                { from: 700000, to: 700000 },
            );
            expect(result.page).to.equal(1);
            expect(result.totalPages).to.be.gte(1);
            expect(result.itemsOnPage).to.equal(1000);
            expect(result.address).to.equal(
                "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
            );
            expect(result.balance).to.be.a("string");
            expect(Number(result.totalReceived)).to.be.gte(300675773149927);
            expect(Number(result.totalSent)).to.be.gte(300672999991857);
            expect(result.unconfirmedBalance).to.equal("0");
            expect(result.unconfirmedTxs).to.equal(0);
            expect(result.txs).to.be.gte(901158);
            expect(result.txids.length).to.equal(6);
            expect(result.txids[0]).to.equal(
                "bd0157f2057bcc604c263ec76dfe321e55fe92b0acbdaaccc09cc131b780b997",
            );
            expect(result.txids[5]).to.equal(
                "ed25927576988e38e4cc8e4b19d1272c480f113fb605271b190df05aa983714e",
            );
        });
    });

    describe(".block()", () => {
        const fixture_700000_1 = require("../__fixtures__/v2_block_700000_1.json");
        const fixture_700000_2 = require("../__fixtures__/v2_block_700000_2.json");

        it("finds by height", () => async () => {
            const actual = await sut.block(700000);
            expectBlockEqual(actual, fixture_700000_1);
        });

        it("finds by hash", () => async () => {
            const actual = await sut.block(
                "0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959",
            );
            expectBlockEqual(actual, fixture_700000_1);
        });

        it("find page of transactions", async () => {
            const actual = await sut.block(
                "0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959",
                { page: 2 },
            );
            expectBlockEqual(actual, fixture_700000_2);
        });
    });
});
