# -*- 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.pro.kucoin import kucoin
from ccxt.base.types import Any, Strings, TransferEntry
from ccxt.base.errors import BadRequest


class kucoinfutures(kucoin):

    def describe(self) -> Any:
        return self.deep_extend(super(kucoinfutures, self).describe(), {
            'id': 'kucoinfutures',
            'name': 'KuCoin Futures',
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/147508995-9e35030a-d046-43a1-a006-6fabd981b554.jpg',
                'www': 'https://futures.kucoin.com/',
                'referral': 'https://futures.kucoin.com/?rcode=E5wkqe',
            },
            'has': {
                'CORS': None,
                'spot': False,
                'margin': False,
                'swap': True,
                'future': True,
                'option': None,
                'fetchBidsAsks': True,
            },
            'options': {
                'fetchMarkets': {
                    'types': ['swap', 'future', 'contract'],
                    'fetchTickersFees': False,
                },
                'defaultType': 'swap',
                'defaultAccountType': 'contract',
                'uta': False,
            },
        })

    async def fetch_bids_asks(self, symbols: Strings = None, params={}):
        """
        fetches the bid and ask price and volume for multiple markets
        :param str[] [symbols]: unified symbols of the markets to fetch the bids and asks for, all markets 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>`
        """
        request = {
            'method': 'futuresPublicGetAllTickers',
        }
        return await self.fetch_tickers(symbols, self.extend(request, params))

    async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
        """
        transfer currency internally between wallets on the same account
        :param str code: unified currency code
        :param float amount: amount to transfer
        :param str fromAccount: account to transfer from
        :param str toAccount: account to transfer to
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a `transfer structure <https://docs.ccxt.com/?id=transfer-structure>`
        """
        await self.load_markets()
        currency = self.currency(code)
        amountToPrecision = self.currency_to_precision(code, amount)
        request: dict = {
            'currency': self.safe_string(currency, 'id'),
            'amount': amountToPrecision,
        }
        toAccountString = self.parse_transfer_type(toAccount)
        response = None
        if toAccountString == 'TRADE' or toAccountString == 'MAIN':
            request['recAccountType'] = toAccountString
            response = await self.futuresPrivatePostTransferOut(self.extend(request, params))
            #
            #     {
            #         "code": "200000",
            #         "data": {
            #             "applyId": "6738754373ceee00011ec3f8",
            #             "bizNo": "6738754373ceee00011ec3f7",
            #             "payAccountType": "CONTRACT",
            #             "payTag": "DEFAULT",
            #             "remark": "",
            #             "recAccountType": "MAIN",
            #             "recTag": "DEFAULT",
            #             "recRemark": "",
            #             "recSystem": "KUCOIN",
            #             "status": "PROCESSING",
            #             "currency": "USDT",
            #             "amount": "5",
            #             "fee": "0",
            #             "sn": 1519769124846692,
            #             "reason": "",
            #             "createdAt": 1731753283000,
            #             "updatedAt": 1731753283000
            #         }
            #     }
            #
        elif toAccount == 'future' or toAccount == 'swap' or toAccount == 'contract':
            request['payAccountType'] = self.parse_transfer_type(fromAccount)
            response = await self.futuresPrivatePostTransferIn(self.extend(request, params))
            #
            #    {
            #        "code": "200000",
            #        "data": {
            #            "applyId": "5bffb63303aa675e8bbe18f9"  # Transfer-out request ID
            #        }
            #    }
            #
        else:
            raise BadRequest(self.id + ' transfer() only supports transfers between future/swap, spot and funding accounts')
        data = self.safe_dict(response, 'data', {})
        return self.extend(self.parse_transfer(data, currency), {
            'amount': self.parse_number(amountToPrecision),
            'fromAccount': fromAccount,
            'toAccount': toAccount,
        })

    def parse_transfer_type(self, transferType):
        transferTypes: dict = {
            'spot': 'TRADE',
            'funding': 'MAIN',
        }
        return self.safe_string_upper(transferTypes, transferType, transferType)
