"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformApiClient = void 0;
const HttpClient_js_1 = require("./HttpClient.js");
const unwrap = (payload) => {
    if (payload && typeof payload === "object" && "data" in payload)
        return payload.data;
    return payload;
};
class PlatformApiClient {
    http;
    constructor(baseUrl) {
        this.http = new HttpClient_js_1.HttpClient({ baseUrl });
    }
    async listNetworks() {
        const response = await this.http.get("/api/v1/networks");
        return unwrap(response).map((network) => this.mapNetwork(network));
    }
    async listTokens() {
        const networks = await this.listNetworks();
        const tokenGroups = await Promise.all(networks.map(async (network) => {
            const response = await this.http.get(`/api/v1/tokens?networkId=${encodeURIComponent(network.id)}`);
            return unwrap(response).map((token) => this.mapToken(token, network.name));
        }));
        return tokenGroups.flat();
    }
    async listLiquidityPools() {
        const [networks, response] = await Promise.all([
            this.listNetworks(),
            this.http.get("/api/v1/liquidity/pools")
        ]);
        const networkMap = new Map(networks.map((network) => [network.id, network.name]));
        return unwrap(response).map((pool) => this.mapLiquidityPool(pool, networkMap));
    }
    async getTokenPrice(tokenId, networkId) {
        const query = networkId ? `?networkId=${encodeURIComponent(networkId)}` : "";
        const response = await this.http.get(`/api/v1/tokens/${tokenId}/price${query}`);
        const payload = unwrap(response);
        const value = payload.priceUsd ?? payload.price ?? payload.usdPrice ?? payload.currentPrice;
        return typeof value === "number" ? value : undefined;
    }
    async updateTokenPrice(tokenId, priceUsd, jwt) {
        // server/README.md documents PUT /api/v1/tokens/:id/price as the admin token price route.
        await this.http.put(`/api/v1/tokens/${tokenId}/price`, { price: priceUsd }, { Authorization: `Bearer ${jwt}` });
    }
    async syncTopTokens(networkId, jwt) {
        // server/README.md does not document a single token import/create route; sync is the only documented admin token import-like route.
        await this.http.post("/api/v1/tokens/sync", { networkId }, { Authorization: `Bearer ${jwt}` });
    }
    async importToken(networkId, address, jwt, logoUrl) {
        const response = await this.http.post(`/api/v1/tokens/import?networkId=${encodeURIComponent(networkId)}`, { address, logoUrl }, { Authorization: `Bearer ${jwt}` });
        const payload = response.token ?? response.data;
        if (!payload) {
            throw new Error("Token import response did not include token data.");
        }
        return this.mapToken(payload);
    }
    async setCustomPrice(tokenId, price, priceType, jwt, priceGap, reason) {
        await this.http.post(`/api/v1/tokens/${tokenId}/custom-price`, { price, priceType, priceGap, reason }, { Authorization: `Bearer ${jwt}` });
    }
    async clearCustomPrice(tokenId, jwt) {
        await this.http.delete(`/api/v1/tokens/${tokenId}/custom-price`, undefined, { Authorization: `Bearer ${jwt}` });
    }
    async getCustomPrices(jwt) {
        const response = await this.http.get("/api/v1/tokens/custom-prices", { Authorization: `Bearer ${jwt}` });
        const items = unwrap(response);
        return items.map((raw) => {
            const item = raw;
            return {
                tokenId: String(item.tokenId ?? item.id ?? ""),
                priceType: String(item.priceType ?? ""),
                priceGap: typeof item.priceGap === "number" ? item.priceGap : undefined,
                updatedAt: item.updatedAt ? new Date(String(item.updatedAt)) : new Date()
            };
        });
    }
    async getWalletBalances(walletId) {
        return this.http.get(`/api/v1/wallets/${walletId}/balances`);
    }
    async listStrategies() {
        // server/README.md does not document a strategies route. The application layer supplies known platform strategy names.
        return [];
    }
    mapNetwork(raw) {
        const item = raw;
        return {
            id: String(item.id ?? item._id ?? ""),
            name: String(item.name ?? ""),
            chainId: typeof item.chainId === "number" ? item.chainId : undefined
        };
    }
    mapToken(raw, fallbackNetworkName) {
        const item = raw;
        const network = item.network;
        const marketData = item.marketData;
        const price = typeof item.priceUsd === "number"
            ? item.priceUsd
            : typeof item.price === "number"
                ? item.price
                : typeof item.currentPrice === "number"
                    ? item.currentPrice
                    : typeof item.customPrice === "number"
                        ? item.customPrice
                        : typeof marketData?.priceUsd === "number"
                            ? marketData.priceUsd
                            : undefined;
        return {
            id: String(item.id ?? item._id ?? ""),
            name: String(item.name ?? ""),
            symbol: String(item.symbol ?? "").toUpperCase(),
            networkId: String(item.networkId ?? network?.id ?? network?._id ?? ""),
            networkName: typeof item.networkName === "string" ? item.networkName : typeof network?.name === "string" ? network.name : fallbackNetworkName,
            contractAddress: typeof item.contractAddress === "string"
                ? item.contractAddress
                : typeof item.address === "string"
                    ? item.address
                    : undefined,
            priceUsd: price,
            logoUrl: typeof item.logoUrl === "string" ? item.logoUrl : undefined,
            isTopToken: typeof item.isTopToken === "boolean" ? item.isTopToken : undefined
        };
    }
    mapLiquidityPool(raw, networkMap) {
        const item = raw;
        const networkId = String(item.networkId ?? "");
        return {
            id: String(item.id ?? item._id ?? ""),
            address: String(item.address ?? ""),
            networkId,
            networkName: networkMap.get(networkId) ?? (typeof item.networkName === "string" ? item.networkName : undefined),
            token0Address: String(item.token0Address ?? ""),
            token0Symbol: String(item.token0Symbol ?? "").toUpperCase(),
            token0Name: String(item.token0Name ?? ""),
            token0Decimals: typeof item.token0Decimals === "number" ? item.token0Decimals : 18,
            token0LogoUrl: typeof item.token0LogoUrl === "string" ? item.token0LogoUrl : undefined,
            token1Address: String(item.token1Address ?? ""),
            token1Symbol: String(item.token1Symbol ?? "").toUpperCase(),
            token1Name: String(item.token1Name ?? ""),
            token1Decimals: typeof item.token1Decimals === "number" ? item.token1Decimals : 18,
            token1LogoUrl: typeof item.token1LogoUrl === "string" ? item.token1LogoUrl : undefined,
            apr: typeof item.apr === "number" ? item.apr : 0,
            tvl: typeof item.tvl === "number" ? item.tvl : 0,
            volume24h: typeof item.volume24h === "number" ? item.volume24h : 0,
            fee: typeof item.fee === "number" ? item.fee : 0.3,
            isStablePool: typeof item.isStablePool === "boolean" ? item.isStablePool : false,
            isActive: typeof item.isActive === "boolean" ? item.isActive : true
        };
    }
}
exports.PlatformApiClient = PlatformApiClient;
