"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.metadata=void 0;const db_1=require("@b/db"),sequelize_1=require("sequelize"),query_1=require("@b/utils/query"),error_1=require("@b/utils/error");exports.metadata={summary:"Get User's Leaderboard Position",operationId:"getUserLeaderboardPosition",tags:["Exchange","Binary","Leaderboard"],description:"Retrieves the authenticated user's ranking and trading statistics for the leaderboard.",parameters:[{name:"period",in:"query",description:"Time period for the ranking: daily, weekly, monthly, alltime",schema:{type:"string",enum:["daily","weekly","monthly","alltime"]}},{name:"metric",in:"query",description:"Ranking metric: profit (total profit), winRate (win percentage), volume (trade count)",schema:{type:"string",enum:["profit","winRate","volume"]}}],responses:{200:{description:"User's leaderboard position and stats",content:{"application/json":{schema:{type:"object",properties:{rank:{type:"number"},totalTraders:{type:"number"},percentile:{type:"number"},stats:{type:"object",properties:{totalProfit:{type:"number"},winRate:{type:"number"},totalTrades:{type:"number"},wins:{type:"number"},losses:{type:"number"},bestStreak:{type:"number"},avgProfit:{type:"number"}}}}}}}},401:query_1.unauthorizedResponse,404:(0,query_1.notFoundMetadataResponse)("User stats"),500:query_1.serverErrorResponse},requiresAuth:!0};exports.default=async e=>{const{user:t,query:r,ctx:s}=e;if(!(null==t?void 0:t.id))throw(0,error_1.createError)({statusCode:401,message:"Unauthorized"});const{period:a="weekly",metric:i="profit"}=r;null==s||s.step(`Fetching leaderboard position for user ${t.id}`);const o=new Date;let n;switch(a){case"daily":n=new Date(o.getFullYear(),o.getMonth(),o.getDate());break;case"weekly":const e=o.getDay();n=new Date(o);n.setDate(o.getDate()-e);n.setHours(0,0,0,0);break;case"monthly":n=new Date(o.getFullYear(),o.getMonth(),1);break;default:n=new Date(0)}const l={status:{[sequelize_1.Op.in]:["WIN","LOSS"]},isDemo:!1};"alltime"!==a&&(l.closedAt={[sequelize_1.Op.gte]:n});try{const e=(await db_1.models.binaryOrder.findAll({attributes:[[(0,sequelize_1.fn)("COUNT",(0,sequelize_1.col)("id")),"totalTrades"],[(0,sequelize_1.fn)("SUM",(0,sequelize_1.literal)("CASE WHEN status = 'WIN' THEN 1 ELSE 0 END")),"wins"],[(0,sequelize_1.fn)("SUM",(0,sequelize_1.literal)("CASE WHEN status = 'LOSS' THEN 1 ELSE 0 END")),"losses"],[(0,sequelize_1.fn)("SUM",(0,sequelize_1.literal)("CASE WHEN status = 'WIN' THEN profit WHEN status = 'LOSS' THEN -amount ELSE 0 END")),"totalProfit"],[(0,sequelize_1.fn)("AVG",(0,sequelize_1.literal)("CASE WHEN status = 'WIN' THEN profit ELSE NULL END")),"avgProfit"]],where:{...l,userId:t.id},raw:!0}))[0];if(!e||0===Number(e.totalTrades)){null==s||s.success("No trades found for this period");return{rank:null,totalTraders:0,percentile:null,qualified:!1,minTradesRequired:5,stats:{totalProfit:0,winRate:0,totalTrades:0,wins:0,losses:0,avgProfit:0}}}const r=Number(e.wins)||0,a=Number(e.losses)||0,o=Number(e.totalTrades)||0,n=o>0?r/o*100:0,u=parseFloat(Number(e.totalProfit||0).toFixed(2)),d=parseFloat(Number(e.avgProfit||0).toFixed(2)),p=o>=5;let m=null,c=0;if(p){const e=await db_1.models.binaryOrder.findAll({attributes:["userId",[(0,sequelize_1.fn)("COUNT",(0,sequelize_1.col)("id")),"totalTrades"],[(0,sequelize_1.fn)("SUM",(0,sequelize_1.literal)("CASE WHEN status = 'WIN' THEN 1 ELSE 0 END")),"wins"],[(0,sequelize_1.fn)("SUM",(0,sequelize_1.literal)("CASE WHEN status = 'WIN' THEN profit WHEN status = 'LOSS' THEN -amount ELSE 0 END")),"totalProfit"]],where:l,group:["userId"],having:(0,sequelize_1.literal)("COUNT(id) >= 5"),raw:!0});c=e.length;const r=e.map(e=>{const t=Number(e.wins)||0,r=Number(e.totalTrades)||0,s=r>0?t/r*100:0,a=Number(e.totalProfit)||0;return{userId:e.userId,profit:a,winRate:s,volume:r}}).sort((e,t)=>{switch(i){case"winRate":return t.winRate-e.winRate;case"volume":return t.volume-e.volume;default:return t.profit-e.profit}}).findIndex(e=>e.userId===t.id);m=r>=0?r+1:null}const f=m&&c>0?parseFloat(((c-m+1)/c*100).toFixed(1)):null;null==s||s.success(`User rank: ${m||"N/A"}`);return{rank:m,totalTraders:c,percentile:f,qualified:p,minTradesRequired:5,stats:{totalProfit:u,winRate:parseFloat(n.toFixed(1)),totalTrades:o,wins:r,losses:a,avgProfit:d}}}catch(e){null==s||s.fail(e.message);throw(0,error_1.createError)({statusCode:500,message:`Failed to fetch user position: ${e.message}`})}};