import { ss58ToV1Pubkey } from '~/utils/ss58';
import type { DuniterAdapter, MonetaryData } from './types';

const SQUID_URL = 'https://gt-squid.axiom-team.fr/v1/graphql';

async function gql<T>(query: string): Promise<T> {
  const res = await fetch(SQUID_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  });
  const json = await res.json();
  if (json.errors) throw new Error(json.errors[0].message);
  return json.data;
}

export const v2Adapter: DuniterAdapter = {
  async fetchMonetary(): Promise<MonetaryData> {
    const data = await gql<{
      universalDividends: { nodes: (Omit<MonetaryData, 'udBlockNumbers'> & Record<string, unknown>)[] };
    }>(`{
      universalDividends(first: 1, orderBy: BLOCK_NUMBER_DESC) {
        nodes { monetaryMass membersCount amount timestamp blockNumber }
      }
    }`);
    return { ...data.universalDividends.nodes[0], udBlockNumbers: [] };
  },

  async fetchMemberPubkeys(): Promise<string[]> {
    const accountIds: string[] = [];
    let offset = 0;
    const pageSize = 1000;

    while (true) {
      const data = await gql<{
        identities: { nodes: { accountId: string }[] };
      }>(`{
        identities(first: ${pageSize}, offset: ${offset}, filter: { isMember: { equalTo: true } }) {
          nodes { accountId }
        }
      }`);

      const nodes = data.identities.nodes;
      for (const node of nodes) {
        accountIds.push(node.accountId);
      }

      if (nodes.length < pageSize) break;
      offset += pageSize;
    }

    // Convert SS58 accountIds to Cesium+ v1 base58 pubkeys
    const pubkeys: string[] = [];
    for (const id of accountIds) {
      try {
        pubkeys.push(ss58ToV1Pubkey(id));
      } catch {
        // Skip invalid addresses
      }
    }
    return pubkeys;
  },

  async fetchMemberJoinBlocks(_pubkeys: string[]): Promise<Map<string, number>> {
    // TODO: implement using squid GraphQL after v2 migration
    return new Map();
  },
};
