# -*- coding: utf-8 -*-

# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code

from ccxt.async_support.base.exchange import Exchange
from ccxt.abstract.bit24 import ImplicitAPI
from ccxt.base.types import Any, Market, Strings, Ticker, Tickers
from typing import List


class bit24(Exchange, ImplicitAPI):

    def describe(self) -> Any:
        return self.deep_extend(super(bit24, self).describe(), {
            'id': 'bit24',
            'name': 'Bit24',
            'countries': ['IR'],
            'rateLimit': 1000,
            'version': '1',
            'certified': False,
            'pro': False,
            'has': {
                'CORS': None,
                'spot': True,
                'margin': False,
                'swap': False,
                'future': False,
                'option': False,
                'addMargin': False,
                'cancelAllOrders': False,
                'cancelOrder': False,
                'cancelOrders': False,
                'createDepositAddress': False,
                'createOrder': False,
                'createStopLimitOrder': False,
                'createStopMarketOrder': False,
                'createStopOrder': False,
                'editOrder': False,
                'fetchBalance': False,
                'fetchBorrowInterest': False,
                'fetchBorrowRateHistories': False,
                'fetchBorrowRateHistory': False,
                'fetchClosedOrders': False,
                'fetchCrossBorrowRate': False,
                'fetchCrossBorrowRates': False,
                'fetchCurrencies': False,
                'fetchDepositAddress': False,
                'fetchDeposits': False,
                'fetchFundingHistory': False,
                'fetchFundingRate': False,
                'fetchFundingRateHistory': False,
                'fetchFundingRates': False,
                'fetchIndexOHLCV': False,
                'fetchIsolatedBorrowRate': False,
                'fetchIsolatedBorrowRates': False,
                'fetchL2OrderBook': False,
                'fetchL3OrderBook': False,
                'fetchLedger': False,
                'fetchLedgerEntry': False,
                'fetchLeverageTiers': False,
                'fetchMarkets': True,
                'fetchMarkOHLCV': False,
                'fetchMyTrades': False,
                'fetchOHLCV': False,
                'fetchOpenInterestHistory': False,
                'fetchOpenOrders': False,
                'fetchOrder': False,
                'fetchOrderBook': False,
                'fetchOrders': False,
                'fetchOrderTrades': 'emulated',
                'fetchPositions': False,
                'fetchPremiumIndexOHLCV': False,
                'fetchTicker': True,
                'fetchTickers': True,
                'fetchTime': False,
                'fetchTrades': False,
                'fetchTradingFee': False,
                'fetchTradingFees': False,
                'fetchWithdrawals': False,
                'setLeverage': False,
                'setMarginMode': False,
                'transfer': False,
                'withdraw': False,
            },
            'comment': 'This comment is optional',
            'urls': {
                'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/bit24/64x64.png',
                'api': {
                    'public': 'https://bit24.cash/api/',
                },
                'www': 'https://bit24.cash/',
                'doc': [
                    'https://bit24.cash/',
                ],
            },
            'api': {
                'public': {
                    'get': {
                        'pro/v3/markets': 1,
                    },
                },
            },
            'fees': {
            },
        })

    async def fetch_markets(self, params={}) -> List[Market]:
        """
        retrieves data on all markets for bit24 with pagination
        https://bit24.cash/api/pro/v3/markets
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict[]: an array of objects representing market data
        """
        result = []
        page = 1
        limit = 100  # check Bit24 docs for max allowed per page
        while(True):
            response = await self.publicGetProV3Markets(self.extend(params, {
                'page': page,
                'per_page': limit,
            }))
            markets = self.safe_dict(response, 'data')
            marketList = self.safe_list(markets, 'results', [])
            for i in range(0, len(marketList)):
                marketdata = marketList[i]
                market = self.parse_market(marketdata)
                result.append(market)
            # stop condition: if fewer results than limit, last page reached
            if len(marketList) < limit:
                break
            page += 1
        return result

    def parse_market(self, market) -> Market:
        # {
        # id: 59,
        # market_name: "FTT/IRT",
        # quote_coin_decimal: 0,
        # base_coin_decimal: 2,
        # each_price: "83669.0000000000000000",
        # is_favorite: False,
        # max_leverage: null,
        # margin_profit_retention_fee: null,
        # margin_order_expire_days: null,
        # max_long_margin_leverage: null,
        # max_short_margin_leverage: null,
        # base_coin: {
        # symbol: "FTT",
        # name: "FTX Token",
        # fa_name: "اف تی ایکس توکن",
        # logo: "https://exchange-storage.bit24.cash/exchange/icons/ftt.png",
        # coin_type: 0
        # },
        # quote_coin: {
        # symbol: "IRT",
        # name: "Toman",
        # fa_name: "تومان",
        # logo: "https://exchange-storage.bit24.cash/exchange/icons/IRT.png",
        # coin_type: 1
        # },
        # margin_order_status: {
        # index: 0,
        # name: "غیرفعال"
        # },
        # bot_order_status: {
        # index: 1,
        # name: "فعال"
        # },
        # market_24h_information: {
        # base_volume: "467.86",
        # quote_volume: "39880070",
        # change_percent: "-1.687",
        # change_amount: "-1436",
        # min_price: "83137",
        # max_price: "87128",
        # first_price: "85105",
        # last_price: "83669"
        # }
        # }
        base_coin = self.safe_dict(market, 'base_coin')
        baseId = self.safe_string(base_coin, 'symbol')
        quote_coin = self.safe_dict(market, 'quote_coin')
        quoteId = self.safe_string(quote_coin, 'symbol')
        base = self.safe_currency_code(baseId)
        quote = self.safe_currency_code(quoteId)
        baseId = baseId.lower()
        quoteId = quoteId.lower()
        id = baseId + '-' + quoteId
        return {
            'id': id,
            'symbol': base + '/' + quote,
            'base': base,
            'quote': quote,
            'settle': None,
            'baseId': baseId,
            'quoteId': quoteId,
            'settleId': None,
            'type': 'spot',
            'spot': True,
            'margin': False,
            'swap': False,
            'future': False,
            'option': False,
            'active': True,
            'contract': False,
            'linear': None,
            'inverse': None,
            'contractSize': None,
            'expiry': None,
            'expiryDatetime': None,
            'strike': None,
            'optionType': None,
            'precision': {
                'amount': None,
                'price': None,
            },
            'limits': {
                'leverage': {
                    'min': None,
                    'max': None,
                },
                'amount': {
                    'min': None,
                    'max': None,
                },
                'price': {
                    'min': None,
                    'max': None,
                },
                'cost': {
                    'min': None,
                    'max': None,
                },
            },
            'created': None,
            'info': market,
        }

    async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
        """
        fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
        https://bit24.com/pro/v3/tickers
        :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
        """
        await self.load_markets()
        if symbols is not None:
            symbols = self.market_symbols(symbols)
        page = 1
        limit = 100  # adjust if Bit24 docs show a different default
        result = {}
        while(True):
            response = await self.publicGetProV3Markets(self.extend(params, {
                'page': page,
                'per_page': limit,
            }))
            data = self.safe_dict(response, 'data', {})
            tickerList = self.safe_list(data, 'results', [])
            for i in range(0, len(tickerList)):
                tickerData = tickerList[i]
                ticker = self.parse_ticker(tickerData)
                symbol = ticker['symbol']
                result[symbol] = ticker
            if len(tickerList) < limit:
                break
            page += 1
        return self.filter_by_array_tickers(result, 'symbol', symbols)

    async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
        """
        fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
        https://bit24.com/management/all-coins/?format=json
        :param str symbol: unified symbol of the market to fetch the ticker for
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
        """
        ticker = await self.fetch_tickers([symbol])
        return ticker[symbol]

    def parse_ticker(self, ticker, market: Market = None) -> Ticker:
        # {
        # id: 59,
        # market_name: "FTT/IRT",
        # quote_coin_decimal: 0,
        # base_coin_decimal: 2,
        # each_price: "83669.0000000000000000",
        # is_favorite: False,
        # max_leverage: null,
        # margin_profit_retention_fee: null,
        # margin_order_expire_days: null,
        # max_long_margin_leverage: null,
        # max_short_margin_leverage: null,
        # base_coin: {
        # symbol: "FTT",
        # name: "FTX Token",
        # fa_name: "اف تی ایکس توکن",
        # logo: "https://exchange-storage.bit24.cash/exchange/icons/ftt.png",
        # coin_type: 0
        # },
        # quote_coin: {
        # symbol: "IRT",
        # name: "Toman",
        # fa_name: "تومان",
        # logo: "https://exchange-storage.bit24.cash/exchange/icons/IRT.png",
        # coin_type: 1
        # },
        # margin_order_status: {
        # index: 0,
        # name: "غیرفعال"
        # },
        # bot_order_status: {
        # index: 1,
        # name: "فعال"
        # },
        # market_24h_information: {
        # base_volume: "467.86",
        # quote_volume: "39880070",
        # change_percent: "-1.687",
        # change_amount: "-1436",
        # min_price: "83137",
        # max_price: "87128",
        # first_price: "85105",
        # last_price: "83669"
        # }
        # },
        marketType = 'spot'
        base_coin = self.safe_dict(ticker, 'base_coin', {})
        base_symbol = self.safe_string(base_coin, 'symbol')
        base_symbol = base_symbol.lower()
        quote_coin = self.safe_dict(ticker, 'quote_coin', {})
        quote_symbol = self.safe_string(quote_coin, 'symbol')
        quote_symbol = quote_symbol.lower()
        marketId = base_symbol + '-' + quote_symbol
        symbol = self.safe_symbol(marketId, market, None, marketType)
        last = self.safe_float(ticker, 'each_price', 0)
        markerInfo = self.safe_dict(ticker, 'market_24h_information', {})
        change = self.safe_float(markerInfo, 'change_percent', 0)
        minPrice = self.safe_float(markerInfo, 'min_price', 0)
        maxPrice = self.safe_float(markerInfo, 'max_price', 0)
        baseVolume = self.safe_float(markerInfo, 'base_volume', 0)
        quoteVolume = self.safe_float(markerInfo, 'quote_volume', 0)
        return self.safe_ticker({
            'symbol': symbol,
            'timestamp': None,
            'datetime': None,
            'high': maxPrice,
            'low': minPrice,
            'bid': None,
            'bidVolume': None,
            'ask': None,
            'askVolume': None,
            'vwap': None,
            'open': None,
            'close': last,
            'last': last,
            'previousClose': None,
            'change': change,
            'percentage': None,
            'average': None,
            'baseVolume': baseVolume,
            'quoteVolume': quoteVolume,
            'info': ticker,
        }, market)

    def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
        query = self.omit(params, self.extract_params(path))
        url = self.urls['api'][api] + '/' + self.implode_params(path, params)
        url = url + '?' + self.urlencode(query)
        headers = {'Content-Type': 'application/json'}
        return {'url': url, 'method': method, 'body': body, 'headers': headers}
