import { Router } from 'express';
import axios from 'axios';
import { CONSTANTS_BN, TEXT_CONSTANTS } from '../constants';
import { Ticker, PayType, OrderStatus, User } from '../models_nosql';
import { getSignature_BN } from '../utilities';
import {
	getBalance,
	handlerTotalBalance,
	getMerchantOrders,
	transferAsset,
	getUserPayMethods,
	getMerchantAdvs,
	getArraySortedByProp,
	getResultAdvUpdate,
	getOrderDetails,
	getTickerPriceUSDT,
	checkOrderInDB,
	checkOrderInDB_spot,
	insertOrderToDB,
	getP2POrders,
	getSpotOrders,
	getP2POrdersNomalized,
	getSpotOrdersNomalized,
	getMerchantAdvsNomalized,
	getMerchantOrdersNomalized,
	getBalancesNormalized,
	getValuationUSDT,
	getSingleUserProperty,
	getPayMethodProps,
	getPayMethodPropsReverse,
	getPaySubAccount,
	consoleProcessed,
	getOrderDetailsNomalized,
	getObjectRequestParams,
} from '../common';
const {
	SHORT_NAME,
	GET_SPOT_BALANCE,
	GET_P2P_BALANCE,
	GET_FUT_BALANCE,
	GET_EARN_BALANCE,
	GET_DATA_LOCKED,
	TRANSFER_ASSET_FROM_P2P,
	TRANSFER_ASSET_FROM_SPOT,
	GET_P2P_ORDERS,
	GET_MERCHANT_ORDERS,
	GET_MERCHANT_ORDERS_BY_API,
	GET_MERCHANT_ORDER_DETAILS,
	GET_MERCHANT_ADVS,
	CHANGE_STATUS_ADVS,
	GET_ADV_DETAIL,
	UPDATE_DETAILS_ADV,
	GET_HISTORY_SPOT_ORDERS,
	GET_ACTIVE_SPOT_ORDERS,
	GET_ACTIVE_SPOT_ORDERS_BY_API,
	GET_MERCHANT_ADV_PAYMENTS,
	GET_MERCHANT_DETAILS,
} = CONSTANTS_BN;

export const ordersRouter_BN = Router();

// получение балансов
ordersRouter_BN.post('/get-balances', async (req, res) => {
	const { userId, exchangeId, shortName } = req.body;
	const user = await User.findOne({ _id: userId });

	const objParams = {
		userId,
		shortName,
		prefix: `balance_${shortName}`,
		constants: CONSTANTS_BN,
		// apiKeys,
		requestHeader: getSingleUserProperty(
			'requestHeader',
			exchangeId,
			user.properties
		),
		additionals: {},
	};

	const totalBalance = await handlerTotalBalance(objParams);

	return res.status(200).json({
		success: totalBalance.spotBalance.length === 0 ? false : true,
		balances: totalBalance,
		message:
			totalBalance.spotBalance.length === 0
				? `${shortName}: ${TEXT_CONSTANTS.BALANCE_ER}`
				: `${shortName}: ${TEXT_CONSTANTS.BALANCE_OK}`,
	});
});

// перевод крипты spot <=> p2p
ordersRouter_BN.post('/transferAsset', async (req, res) => {
	const { userId, exchange, shortName, toNameAccount } = req.body;
	const user = await User.findOne({ _id: userId });
	const requestHeaderBN = getSingleUserProperty(
		'requestHeader',
		exchange,
		user.properties
	);

	const objParams = {
		userId,
		prefix: `balance_${shortName}`,
		constants: CONSTANTS_BN,
		// apiKeys,
		requestHeader: requestHeaderBN,
		additionals: {},
	};

	const spotBalance = await getBalance(
		getObjectRequestParams({
			...objParams,
			additionals: { typeBalance: 'SPOT' },
		})
	);
	const p2pBalance = await getBalance(
		getObjectRequestParams({
			...objParams,
			additionals: { typeBalance: 'P2P' },
		})
	);
	const futBalance = await getBalance(
		getObjectRequestParams({
			...objParams,
			additionals: { typeBalance: 'FUT' },
		})
	);
	const earnBalance = await getBalance(
		getObjectRequestParams({
			...objParams,
			additionals: { typeBalance: 'EARN' },
		})
	);
	const lockedData = await getBalance(
		getObjectRequestParams({
			...objParams,
			additionals: { typeBalance: 'LOCK' },
		})
	);

	let message;
	const headers = {
		'access-control-allow-credentials': true,
		'Access-Control-Allow-Origin': '*',
		'content-type': 'application/json;charset=UTF-8',
		clienttype: 'web',
		cookie: requestHeaderBN.cookie,
		csrftoken: requestHeaderBN.csrftoken,
		'device-info': requestHeaderBN.deviceInfo,
		'user-agent': requestHeaderBN.userAgent,
	};

	// "fromSPOT" --> "toP2P"
	if (toNameAccount === 'SPOT') {
		// получаем количество USDT !==0 на spot-балансе
		const spotBalanceFiltered = spotBalance.filter((item) => {
			return item.asset === 'USDT' && +item.free !== 0;
		});
		if (spotBalanceFiltered.length !== 0) {
			// ---> transferRequest "fromSPOT" --> "toP2P"
			const config_fromSPOTtoP2P = {
				withCredentials: true,
				method: TRANSFER_ASSET_FROM_SPOT.method,
				url: TRANSFER_ASSET_FROM_SPOT.url,
				data: {
					amount: '',
					asset: '',
					kindType: 'MAIN_FIAT',
				},
				headers,
			};
			const params = {
				shortName,
				nameAccount: toNameAccount,
				balances: spotBalanceFiltered,
			};
			const result = await transferAsset(config_fromSPOTtoP2P, params);
			message = result
				? `${shortName}: USDTs ${TEXT_CONSTANTS.TRANSFER_OK} ${toNameAccount}!`
				: `${shortName}:  USDTs ${TEXT_CONSTANTS.TRANSFER_ER} ${toNameAccount}!`;
		} else {
			message = `${shortName}: Nothing to transfer. USDT Spot-Balance equals 0`;
		}
	}
	// "fromP2P" --> "toSPOT"
	else if (toNameAccount === 'P2P') {
		// получаем количество Assets !==USDT !==0 на p2p-балансе
		const p2pBalanceFiltered = p2pBalance.filter((item) => {
			return item.asset !== 'USDT' && +item.free !== 0;
		});
		if (p2pBalanceFiltered.length !== 0) {
			// ---> transferRequest "fromSPOT" --> "toP2P"
			const config_fromP2PtoSPOT = {
				withCredentials: true,
				method: TRANSFER_ASSET_FROM_P2P.method,
				url: TRANSFER_ASSET_FROM_P2P.url,
				data: {
					asset: '',
					amount: '',
					authType: null,
					code: null,
					transferType: 'FIAT_OUT',
				},
				headers,
			};
			const params = {
				shortName,
				nameAccount: toNameAccount,
				balances: p2pBalanceFiltered,
			};
			const result = await transferAsset(config_fromP2PtoSPOT, params);
			message = result
				? `${shortName}: Assets ${TEXT_CONSTANTS.TRANSFER_OK} ${toNameAccount}!`
				: `${shortName}: Assets ${TEXT_CONSTANTS.TRANSFER_ER} ${toNameAccount}!`;
		} else {
			message = `${shortName}: Nothing to transfer. Asset's P2P-Balance equals 0`;
		}
	}

	return res.status(200).json({
		success: true,
		tickers: await Ticker.find(),
		balances: {
			spotBalance: getBalancesNormalized(
				spotBalance.filter((item) => {
					return +item.free + +item.freeze + +item.locked !== 0;
				}),
				`${shortName}_spot`
			),
			p2pBalance: getBalancesNormalized(
				p2pBalance.filter((item) => {
					return +item.free + +item.freeze !== 0;
				}),
				`${shortName}_otc`
			),
			futBalance: getBalancesNormalized(
				futBalance.filter((item) => {
					return +item.walletBalance + +item.unrealizedProfit !== 0;
				}),
				`${shortName}_fut`
			),
			earnBalance: [
				{
					currency: 'USDT',
					available: earnBalance.totalInterestInUsdt,
					frozen: earnBalance.todayInterestInUsdt,
				},
			],
			lockedData: lockedData.total,
		},
		message,
	});
});

// получение массива объявлений
ordersRouter_BN.post('/merchant-advs', async (req, res) => {
	const { userId, shortName, exchangeId, objParams } = req.body;
	const user = await User.findOne({ _id: userId });
	const requestHeaderBN = getSingleUserProperty(
		'requestHeader',
		exchangeId,
		user.properties
	);

	const headers = {
		'access-control-allow-credentials': true,
		'Access-Control-Allow-Origin': '*',
		'content-type': 'application/json;charset=UTF-8',
		c2ctype: 'c2c_merchant',
		clienttype: 'web',
		cookie: requestHeaderBN.cookie,
		csrftoken: requestHeaderBN.csrftoken,
		'device-info': requestHeaderBN.deviceInfo,
		'user-agent': requestHeaderBN.userAgent,
	};

	const userPayRequestConfig = {
		withCredentials: true,
		method: GET_MERCHANT_ADV_PAYMENTS.method,
		url: GET_MERCHANT_ADV_PAYMENTS.url,
		data: {},
		headers,
	};

	const params = {
		userId,
		prefix: shortName,
		config: {
			withCredentials: true,
			method: GET_MERCHANT_ADVS.method,
			url: GET_MERCHANT_ADVS.url,
			data: {
				page: objParams.page,
				rows: objParams.rows,
				inDeal: 1,
			},
			headers,
		},
	};

	const userPayMethods = await getUserPayMethods(
		userPayRequestConfig,
		shortName
	);
	const arrData = await getMerchantAdvs(params);
	const arrPayTypes = await PayType.find();

	return res.status(200).json({
		success: arrData.length !== 0 ? true : false,
		data: {
			// merchantAdvs: [],
			merchantAdvs:
				arrData.length !== 0
					? getMerchantAdvsNomalized(
							arrData,
							{
								userId,
								exchangeId,
								prefix: shortName,
							},
							arrPayTypes
					  )
					: [],
			userPayMethods,
		},
		message:
			arrData.length !== 0
				? `${shortName}: ${TEXT_CONSTANTS.USER_ADVS_OK}`
				: `${shortName}: ${TEXT_CONSTANTS.USER_ADVS_ER}`,
	});
});

// изменение статуса объявления (-ий) мерчанта
ordersRouter_BN.post('/adv-status', async (req, res) => {
	const axiosRequestConfig = {
		withCredentials: true,
		method: CHANGE_STATUS_ADVS.method,
		url: CHANGE_STATUS_ADVS.url,
		data: {
			advNos: req.body.arrayAdvNumbers,
			advStatus: req.body.advStatus === true ? 3 : 1,
		},
		headers: {
			'access-control-allow-credentials': true,
			'Access-Control-Allow-Origin': '*',
			'content-type': 'application/json;charset=UTF-8',
			c2ctype: 'c2c_merchant',
			clienttype: 'web',
			cookie: req.body.requestHeader.cookie,
			csrftoken: req.body.requestHeader.csrftoken,
			'device-info': req.body.requestHeader.deviceInfo,
			'user-agent': req.body.requestHeader.userAgent,
		},
	};

	await axios(axiosRequestConfig)
		.then((response) => {
			return res.status(200).json({
				success: true,
				data: response.data.data,
				arrayAdvNumbers: req.body.arrayAdvNumbers,
				advStatus: req.body.advStatus,
			});
		})
		.catch((error) => {
			res.status(400).json({
				error,
				message: `${SHORT_NAME}: ${TEXT_CONSTANTS.ADV_STATUS_ER}`,
			});
		});
});

// получение редактируемого объявления мерчанта
ordersRouter_BN.post('/adv-edit', async (req, res) => {
	const headers = {
		'access-control-allow-credentials': true,
		'Access-Control-Allow-Origin': '*',
		'content-type': 'application/json;charset=UTF-8',
		c2ctype: 'c2c_merchant',
		clienttype: 'web',
		cookie: req.body.requestHeader.cookie,
		csrftoken: req.body.requestHeader.csrftoken,
		'device-info': req.body.requestHeader.deviceInfo,
		'user-agent': req.body.requestHeader.userAgent,
	};

	const advEditRequestConfig = {
		withCredentials: true,
		method: GET_ADV_DETAIL.method,
		url: GET_ADV_DETAIL.url,
		data: { advNo: req.body.advIdNumber },
		headers,
	};

	const p2pBalanceRequestConfig = {
		withCredentials: true,
		method: '',
		url: '',
		data: {},
		headers,
	};

	const userPayRequestConfig = {
		withCredentials: true,
		method: GET_MERCHANT_ADV_PAYMENTS.method,
		url: GET_MERCHANT_ADV_PAYMENTS.url,
		data: {},
		headers,
	};

	const userPayMethods = await getUserPayMethods(
		userPayRequestConfig,
		SHORT_NAME
	);
	const p2pBalance = await getBalance_BN(
		p2pBalanceRequestConfig,
		GET_P2P_BALANCE,
		'P2P',
		null
	);

	const arrTickers = await Ticker.find();
	await axios(advEditRequestConfig)
		.then((response) => {
			// console.log(response.data)
			return res.status(200).json({
				success: true,
				advDetails: response.data.data,
				userPayMethods,
				p2pBalance,
				tickers: arrTickers,
				message: `${SHORT_NAME}: ${TEXT_CONSTANTS.ADV_EDIT_OK}`,
			});
		})
		.catch((error) => {
			res.status(400).json({
				error,
				message: `${SHORT_NAME}: ${TEXT_CONSTANTS.ADV_EDIT_ER}`,
			});
		});
});

// обновление редактируемого объявления
ordersRouter_BN.post('/adv-update', async (req, res) => {
	const headers = {
		'access-control-allow-credentials': true,
		'Access-Control-Allow-Origin': '*',
		'content-type': 'application/json;charset=UTF-8',
		c2ctype: 'c2c_merchant',
		clienttype: 'web',
		cookie: req.body.requestHeader.cookie,
		csrftoken: req.body.requestHeader.csrftoken,
		'device-info': req.body.requestHeader.deviceInfo,
		'user-agent': req.body.requestHeader.userAgent,
	};

	const advUpdateRequestConfig = {
		withCredentials: true,
		method: UPDATE_DETAILS_ADV.method,
		url: UPDATE_DETAILS_ADV.url,
		data: req.body.advDetails,
		headers,
	};

	const getAdvsRequestConfig = {
		withCredentials: true,
		method: GET_MERCHANT_ADVS.method,
		url: GET_MERCHANT_ADVS.url,
		data: {
			page: req.body.objOrder.page,
			rows: req.body.objOrder.rows,
			inDeal: 1,
		},
		headers,
	};

	const p2pOrdersParams = {
		quantityPages: +req.body.objOrder.quantityPages / 20,
		payloadOrders: {
			page: req.body.objOrder.page,
			rows: req.body.objOrder.rows,
			fiat: req.body.objOrder.fiat,
			asset: req.body.objOrder.asset,
			tradeType: req.body.objOrder.tradeType,
			transAmount: req.body.objOrder.transAmount,
			payTypeList: req.body.objOrder.payTypeList,
		},
	};

	const isAdvUpdated = await getResultAdvUpdate(
		advUpdateRequestConfig,
		SHORT_NAME
	);
	const p2pOrders = [];
	const merchantAdvs = await getMerchantAdvs(
		getAdvsRequestConfig,
		SHORT_NAME
	);

	if (isAdvUpdated) {
		return res.status(200).json({
			success: true,
			data: {
				merchantAdvs,
				p2pOrders,
				tickers: await Ticker.find(),
			},
			message: `${SHORT_NAME}: ${TEXT_CONSTANTS.ADV_UPDATE_OK}`,
		});
	} else {
		res.status(400).json({
			message: `${SHORT_NAME}: ${TEXT_CONSTANTS.ADV_UPDATE_ER}`,
		});
	}
});

// получение массива p2p-ордеров стакана
ordersRouter_BN.post('/p2p', async (req, res) => {
	const { userId, exchangeId, shortName } = req.body;
	const {
		asset,
		fiat,
		arrPayments,
		sideType,
		rows,
		page,
		amount,
	} = req.body.objParams;
	const quantityPages = +req.body.objParams.quantityPages / 20;
	const arrPayTypes = await PayType.find();
	// const tradeType = sideType === 'BUY' ? 'SELL' : 'BUY';
	const paymentNames =
		arrPayments.length === 0
			? []
			: arrPayments.map((item, index) => {
					return getPayMethodPropsReverse(
						exchangeId,
						'payName', // payId or payName
						item, // internalPayMethod
						arrPayTypes
					);
			  });

	const objParams = {
		userId,
		prefix: `p2p_${shortName}`,
		constants: CONSTANTS_BN,
		// apiKeys,
		// requestHeader: {},
		additionals: {
			page,
			rows,
			fiat,
			asset,
			tradeType: sideType,
			transAmount: amount,
			payTypes: paymentNames,
		},
	};

	let arrData = [];
	for (let i = page; i <= quantityPages; i++) {
		objParams.additionals.page = i;
		const objReqParams = getObjectRequestParams(objParams);
		const result = await getP2POrders(objReqParams);
		arrData = arrData.concat(result);
	}

	return res.status(200).json({
		success: arrData.length !== 0 ? true : false,
		data: {
			// p2pOrders: [],
			p2pOrders:
				arrData.length !== 0
					? getP2POrdersNomalized(
							arrData,
							{
								userId,
								exchangeId,
								prefix: shortName,
							},
							arrPayTypes
					  )
					: [],
			tickers: await Ticker.find(),
		},
		message:
			arrData.length !== 0
				? `${shortName}: ${arrData.length} ${TEXT_CONSTANTS.P2P_ORDERS_OK}`
				: `${shortName}: ${TEXT_CONSTANTS.P2P_ORDERS_ER}`,
	});
});

// получение массива текущих merchant-ордеров
ordersRouter_BN.post('/merchant-orders', async (req, res) => {
	const { userId, exchangeId, shortName } = req.body;

	const user = await User.findOne({ _id: userId });
	const requestHeader = getSingleUserProperty(
		'requestHeader',
		exchangeId,
		user.properties
	);
	const apiKeys = getSingleUserProperty(
		'apiKeys',
		exchangeId,
		user.properties
	);

	const arrSides = ['BUY', 'SELL'];
	let result_API = [];
	for (let i = 0; i < arrSides.length; i++) {
		const objParams = {
			userId,
			prefix: `otc_${shortName}_API`,
			apiKeys,
			constants: CONSTANTS_BN,
			// requestHeader: {},
			additionals: { side: arrSides[i] },
		};

		const objReqParamsAPI = getObjectRequestParams(objParams);
		const orders = await getMerchantOrders(objReqParamsAPI);
		result_API = result_API.concat(orders);
	}

	const arrData = result_API;
	const arrPayTypes = await PayType.find();
	const arrOrderStatus = await OrderStatus.find();

	return res.status(200).json({
		success: arrData.length !== 0 ? true : false,
		// data: [],
		data:
			arrData.length !== 0
				? getArraySortedByProp(
						'ALL',
						getMerchantOrdersNomalized(
							arrData,
							{
								userId,
								exchangeId,
								// prefix: shortName,
								prefix: `${shortName}_API`,
							},
							arrPayTypes,
							arrOrderStatus
						),
						'dateOrder'
				  )
				: [],
		message:
			arrData.length !== 0
				? `${shortName}: ${arrData.length} ${TEXT_CONSTANTS.USER_ORDERS_OK}`
				: `${shortName}: ${TEXT_CONSTANTS.USER_ORDERS_ER}`,
	});
});

// получение сведений об мерчанте и его объявлениях по id
ordersRouter_BN.get('/merchant-details/:id', async (req, res) => {
	const merchantId = req.params.id;
	const axiosRequestConfig = {
		method: GET_MERCHANT_DETAILS.method,
		url: `${GET_MERCHANT_DETAILS.url}?userNo=${merchantId}`,
		data: null,
		headers: null,
	};
	await axios(axiosRequestConfig)
		.then((response) => {
			// console.log(response.data)
			return res.status(200).json({
				success: true,
				data: response.data.data,
				message: `${SHORT_NAME}: ${TEXT_CONSTANTS.USER_DETAILS_OK}`,
			});
		})
		.catch((error) => {
			res.status(400).json({
				error,
				message: `${SHORT_NAME}: ${TEXT_CONSTANTS.USER_DETAILS_ER}`,
			});
		});
});

// сохранение данных об merchant-ордере в БД по id
ordersRouter_BN.post('/save-user-orders', async (req, res) => {
	const { userId, orders, typeOrder, shortName, exchangeId } = req.body;
	const user = await User.findOne({ _id: userId });
	const arrTickers = await Ticker.find(); // тикеры и цены из БД
	const arrPayTypes = await PayType.find(); // типы оплаты из БД
	let countOrder = 0;

	const requestHeader = getSingleUserProperty(
		'requestHeader',
		exchangeId,
		user.properties
	);

	// проверка наличия ордера в БД
	for (let i = 0; i < orders.length; i++) {
		const result = await checkOrderInDB(
			userId,
			typeOrder,
			orders[i],
			shortName
		);

		// Если ордера нет в БД
		if (result.isUnique) {
			const objParams = {
				userId,
				prefix: `otcDetails_${shortName}`,
				// apiKeys,
				constants: CONSTANTS_BN,
				requestHeader,
				additionals: { order: orders[i] },
			};

			const objReqParams = getObjectRequestParams(objParams);
			// получение данных об ордере с биржи
			const orderDetails = await getOrderDetails(
				objReqParams.config,
				shortName,
				typeOrder
			);

			const params = {
				userId,
				shortName,
				exchangeId,
				arrTickers,
				arrPayTypes,
				orderDetails,
			};

			// если статус ордера "Completed" вставляем в БД
			const newOrder =
				orderDetails.orderStatus === 4
					? getOrderDetailsNomalized(params)
					: {};
			// если newOrder не пустой объект - сохраняем в БД
			if (Object.keys(newOrder).length !== 0) {
				await insertOrderToDB(typeOrder, newOrder);
				// console.log(`${countOrder} | Number: ${newOrder.orderId} | payMethodName: ${newOrder.payMethodName}`);
				++countOrder;
			}
		}
	}

	// log print
	consoleProcessed(userId, shortName, orders, countOrder, typeOrder);

	return res.status(200).json({
		success: true,
		message: `${shortName}: ${countOrder} inserted`,
	});
});

// получение массива активных spot-ордеров
ordersRouter_BN.post('/spot-orders-active', async (req, res) => {
	// const typeOrder = req.body.typeOrder;
	// const shortName = req.body.shortName;
	const { userId, exchange, exchangeId } = req.body;
	const arrTickers = await Ticker.find();
	let status = 200;

	const user = await User.findOne({ _id: userId });
	const requestHeader = getSingleUserProperty(
		'requestHeader',
		exchange,
		user.properties
	);
	const apiKeys = getSingleUserProperty(
		'apiKeys',
		exchange,
		user.properties
	);

	const params = {
		userId: req.body.userId,
		prefix: SHORT_NAME,
		config: {
			withCredentials: true,
			method: GET_ACTIVE_SPOT_ORDERS.method,
			url: GET_ACTIVE_SPOT_ORDERS.url,
			data: {},
			headers: {
				'access-control-allow-credentials': true,
				'Access-Control-Allow-Origin': '*',
				'content-type': 'application/json;charset=UTF-8',
				clienttype: 'web',
				cookie: requestHeader.cookie,
				csrftoken: requestHeader.csrftoken,
				'device-info': requestHeader.deviceInfo,
				'user-agent': requestHeader.userAgent,
			},
		},
	};

	const paramsAPI = {
		userId,
		prefix: `active_${SHORT_NAME}_API`,
		apiKeys,
		constants: CONSTANTS_BN,
		// requestHeader: {},
		additionals: {},
	};

	// const arrActiveSpots = await getSpotOrders(params);
	const objReqParamsAPI = getObjectRequestParams(paramsAPI);
	const arrActiveSpots = await getSpotOrders(objReqParamsAPI);

	return res.status(status).json({
		success: arrActiveSpots.length === 0 ? false : true,
		message:
			arrActiveSpots.length === 0
				? `${SHORT_NAME}: ${TEXT_CONSTANTS.SPOT_ORDERS_ER}`
				: `${SHORT_NAME}: ${arrActiveSpots.length} ${TEXT_CONSTANTS.SPOT_ORDERS_OK}`,
		spotOrders:
			arrActiveSpots.length === 0
				? arrActiveSpots
				: // : getSpotOrdersNomalized(arrActiveSpots, SHORT_NAME),
				  getSpotOrdersNomalized(
						arrActiveSpots,
						{
							flag: 'active_BN_API',
							userId,
							shortName: SHORT_NAME,
							exchangeId,
						},
						arrTickers
				  ),
		tickers: arrTickers,
	});
});

// сохранение spot-ордеров в БД
ordersRouter_BN.post('/spot-orders-history', async (req, res) => {
	let message;
	let success = true;
	let status = 200;
	let countOrder = 0;
	const {
		userId,
		exchange,
		exchangeId,
		shortName,
		typeOrder,
		params,
	} = req.body;

	const user = await User.findOne({ _id: userId });
	const requestHeader = getSingleUserProperty(
		'requestHeader',
		exchange,
		user.properties
	);

	let spotArray = [];
	const page = +params.quantityPages / 20;
	for (let i = 1; i <= page; i++) {
		const objParams = {
			userId,
			prefix: shortName,
			config: {
				withCredentials: true,
				method: GET_HISTORY_SPOT_ORDERS.method,
				url: GET_HISTORY_SPOT_ORDERS.url,
				data: {
					baseAsset: '',
					direction: '',
					endTime: params.endTime,
					hideCancel: false,
					page: i,
					quoteAsset: '',
					rows: params.rows,
					startTime: params.startTime,
				},
				headers: {
					'access-control-allow-credentials': true,
					'Access-Control-Allow-Origin': '*',
					'content-type': 'application/json;charset=UTF-8',
					c2ctype: 'c2c_merchant',
					clienttype: 'web',
					cookie: requestHeader.cookie,
					csrftoken: requestHeader.csrftoken,
					'device-info': requestHeader.deviceInfo,
					'user-agent': requestHeader.userAgent,
				},
			},
		};
		const result = await getSpotOrders(objParams);
		// console.log('page: ' + i);
		spotArray = spotArray.concat(result);
	}

	const arrTickers = await Ticker.find();
	const spotOrders = getSpotOrdersNomalized(
		spotArray,
		{
			userId,
			shortName: SHORT_NAME,
			exchangeId,
			flag: 'history_BN',
		},
		arrTickers
	);

	if (spotOrders.length !== 0) {
		// проверка наличия ордера в БД
		for (let i = 0; i < spotOrders.length; i++) {
			const result = await checkOrderInDB(
				spotOrders[i].userId,
				typeOrder,
				spotOrders[i].orderId,
				spotOrders[i].exchange
			);

			// Если ордера нет в БД вставляем
			if (result.isUnique) {
				// если newSpotOrder не пустой объект - сохраняем в БД
				if (Object.keys(spotOrders[i]).length !== 0) {
					await insertOrderToDB('SPOT', spotOrders[i]);
					// console.log(
					// 	`${countOrder} | tradeIdStr: ${spotOrders[i].tradeIdStr} inserted`
					// );
					++countOrder;
				}
			}
		}
		if (countOrder === 0) {
			success = false;
			message = `${SHORT_NAME}: ${countOrder} | ${TEXT_CONSTANTS.SPOT_ORDERS_DB_NO}`;
		} else {
			success = true;
			message = `${SHORT_NAME}: ${countOrder} | ${TEXT_CONSTANTS.SPOT_ORDERS_DB_OK}`;
		}
	} else {
		success = false;
		message = `${SHORT_NAME}: ${TEXT_CONSTANTS.SPOT_ORDERS_ER}`;
	}

	// log print
	consoleProcessed(userId, shortName, spotOrders, countOrder, typeOrder);

	return res.status(status).json({
		success,
		message,
	});
});
