"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});exports.metadata=void 0;const exchange_1=__importDefault(require("@b/utils/exchange")),index_get_1=require("./index.get"),db_1=require("@b/db"),utils_1=require("../utils"),query_1=require("@b/utils/query"),utils_2=require("@b/api/finance/wallet/utils"),index_ws_1=require("../index.ws"),error_1=require("@b/utils/error"),utils_3=require("../../utils"),console_1=require("@b/utils/console"),wallet_1=require("@b/services/wallet");exports.metadata={summary:"Cancel Order",operationId:"cancelOrder",tags:["Exchange","Orders"],description:"Cancels a specific order for the authenticated user.",parameters:[{index:0,name:"id",in:"path",required:!0,description:"ID of the order to cancel.",schema:{type:"string"}}],responses:{200:{description:"Order canceled successfully",content:{"application/json":{schema:{type:"object",properties:{message:{type:"string",example:"Order canceled successfully"}}}}}},401:query_1.unauthorizedResponse,404:(0,query_1.notFoundMetadataResponse)("Order"),500:query_1.serverErrorResponse},requiresAuth:!0,logModule:"EXCHANGE",logTitle:"Cancel exchange order"};exports.default=async e=>{const{user:r,params:t,ctx:a}=e;if(!(null==r?void 0:r.id))throw(0,error_1.createError)(401,"Unauthorized");const{id:s}=t;try{null==a||a.step("Checking service availability");const e=await(0,utils_3.loadBanStatus)();if(await(0,utils_3.handleBanStatus)(e)){const r=e-Date.now();throw(0,error_1.createError)(503,`Service temporarily unavailable. Please try again in ${(0,utils_3.formatWaitTime)(r)}.`)}null==a||a.step("Fetching order details");const t=await(0,index_get_1.getOrder)(s);if(!t)throw(0,error_1.createError)(404,"Order not found");if("CANCELED"===t.status)throw(0,error_1.createError)(400,"Order already canceled");if(t.userId!==r.id)throw(0,error_1.createError)(401,"Unauthorized");null==a||a.step("Connecting to exchange");const o=await exchange_1.default.startExchange(a);if(!o)throw(0,error_1.createError)(503,"Service currently unavailable");try{null==a||a.step("Fetching latest order status from exchange");let e;if(o.has.fetchOrder)e=await o.fetchOrder(t.referenceId,t.symbol);else{e=(await o.fetchOrders(t.symbol)).find(e=>e.id===t.referenceId)}if(!e||!e.id)throw(0,error_1.createError)(404,"Order not found");null==a||a.step("Updating local order status");await(0,utils_1.updateOrderData)(s,{status:e.status.toUpperCase(),filled:e.filled,remaining:e.remaining,cost:e.cost,fee:e.fee,trades:JSON.stringify(e.trades)});if("open"!==e.status)throw(0,error_1.createError)(400,"Order is not open");const[i,n]=t.symbol.split("/");null==a||a.step(`Fetching wallets for ${i} and ${n}`);const l=await(0,utils_2.getWalletSafe)(r.id,"SPOT",i,!1,a),c=await(0,utils_2.getWalletSafe)(r.id,"SPOT",n,!1,a);if(!l||!c)throw(0,error_1.createError)(500,"Failed to fetch wallets");null==a||a.step("Cancelling order on exchange");await o.cancelOrder(t.referenceId,t.symbol);null==a||a.step("Refunding wallet balance and removing order");const d=`exchange_cancel_${s}`;await db_1.sequelize.transaction(async e=>{if("BUY"===t.side.toUpperCase()){const a=Number(t.amount)*Number(t.price);await wallet_1.walletService.credit({idempotencyKey:`${d}_refund`,userId:r.id,walletId:c.id,walletType:"SPOT",currency:n,amount:a,operationType:"EXCHANGE_ORDER_CANCEL",description:`Refund for cancelled buy order ${t.symbol}`,metadata:{orderId:s,referenceId:t.referenceId,symbol:t.symbol,side:t.side},transaction:e})}else await wallet_1.walletService.credit({idempotencyKey:`${d}_refund`,userId:r.id,walletId:l.id,walletType:"SPOT",currency:i,amount:Number(t.amount),operationType:"EXCHANGE_ORDER_CANCEL",description:`Refund for cancelled sell order ${t.symbol}`,metadata:{orderId:s,referenceId:t.referenceId,symbol:t.symbol,side:t.side},transaction:e});await db_1.models.exchangeOrder.destroy({where:{id:s},force:!0,transaction:e})});(0,index_ws_1.removeOrderFromTrackedOrders)(r.id,s);null==a||a.success(`Order cancelled successfully: ${t.side} ${t.amount} ${t.symbol}`);return{message:"Order cancelled successfully"}}catch(e){console_1.logger.error("EXCHANGE","Error cancelling order",e);throw(0,error_1.createError)({statusCode:500,message:e.message})}}catch(e){console_1.logger.error("EXCHANGE","Error processing order cancellation",e);throw 503===e.statusCode?e:(0,error_1.createError)(500,"Unable to process your request at this time")}};