import axios from 'axios'
import { buildWhereQuery } from './utils'

export interface SubgraphAPIConfig {
  apiUrl: string
}

export interface CommonEventProps {
  id: string
  marketId: string
  transactionHash: string
  blockNumber: string
  blockTimestamp: string
  owner: string
}

export interface TradeEvent extends CommonEventProps {
  futureId: string
  initiator: string
  notional: bigint
  openInterest: bigint
  direction: number
  tradeRate: bigint
  protocolFee: bigint
  lpFee: bigint
}

export interface EventsFilter {
  userAddress?: string
  marketIds?: string[]
  futureIds?: string[]
  timestampFrom?: number
  timestampTo?: number
  offset?: number
  limit?: number
}

export class SubgraphAPI {
  private readonly config: SubgraphAPIConfig
  constructor(config: SubgraphAPIConfig) {
    this.config = config
  }

  public async getTrades(filter: EventsFilter = {}): Promise<TradeEvent[]> {
    const { offset = 0, limit = 100 } = filter

    const query = `
      query {
          trades (first: ${limit}, skip: ${offset}, where: ${buildWhereQuery(
            filter
          )} orderBy: blockNumber, orderDirection: desc) {
            id
            marketId
            futureId
            initiator
            owner
            notional
            openInterest
            tradeInfo_direction
            tradeInfo_tradeRate
            tradeInfo_protocolFee
            tradeInfo_lpFee
            blockNumber
            blockTimestamp
            transactionHash
          }
      }
    `

    const { data } = await axios.post(this.config.apiUrl, {
      query
    })

    if (data && data.errors && typeof data.errors === 'object') {
      const [error] = data.errors
      if (error && error.message) {
        throw new Error(error.message)
      }
    }

    const tradeEvents = data.data.trades.map((trade: any) => {
      const data = {
        ...trade,
        notional: BigInt(trade.notional),
        openInterest: BigInt(trade.openInterest),
        direction: trade.tradeInfo_direction,
        tradeRate: BigInt(trade.tradeInfo_tradeRate),
        protocolFee: BigInt(trade.tradeInfo_protocolFee),
        lpFee: BigInt(trade.tradeInfo_lpFee)
      }

      delete data.tradeInfo_direction
      delete data.tradeInfo_tradeRate
      delete data.tradeInfo_protocolFee
      delete data.tradeInfo_lpFee

      return data
    })

    return tradeEvents
  }
}
