using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Predictalytics.Domain.Entities;
using Predictalytics.Domain.Interfaces;
using Predictalytics.Infrastructure.Data;

namespace Predictalytics.Api.Endpoints;

public static class DevEndpoints
{
    public static void MapDevEndpoints(this IEndpointRouteBuilder routes)
    {
        var group = routes.MapGroup("/api/dev").WithTags("Dev");

        group.MapGet("/verify-positions/{traderId:int}", async (int traderId, AppDbContext db, IEnumerable<IPlatformProvider> providers, CancellationToken ct) =>
        {
            var trader = await db.Traders.FindAsync(new object[] { traderId }, ct);
            if (trader == null) return Results.NotFound("Trader not found");

            var provider = providers.FirstOrDefault(p => p.Platform == trader.Platform && p.IsImplemented);
            if (provider == null) return Results.BadRequest("Platform provider not found");

            var apiPositions = await provider.GetTraderPositionsAsync(trader.PlatformUserId, ct);
            var dbPositions = await db.TraderPositions
                .Include(p => p.MarketOutcome)
                .Where(p => p.TraderId == traderId && p.SharesHeld > 0)
                .ToListAsync(ct);

            var apiPosDict = apiPositions.ToDictionary(p => p.AssetId ?? "");
            var dbPosDict = dbPositions.ToDictionary(p => p.MarketOutcome?.TokenId ?? "");

            var mismatches = new List<object>();

            // Check DB -> API
            foreach (var kvp in dbPosDict)
            {
                if (string.IsNullOrEmpty(kvp.Key)) continue;
                if (!apiPosDict.TryGetValue(kvp.Key, out var apiPos))
                {
                    mismatches.Add(new { Token = kvp.Key, DB = kvp.Value.SharesHeld, API = 0, Reason = "Missing in API" });
                }
                else if (Math.Abs(kvp.Value.SharesHeld - apiPos.Size) > 0.01m)
                {
                    mismatches.Add(new { Token = kvp.Key, DB = kvp.Value.SharesHeld, API = apiPos.Size, Reason = "Size mismatch" });
                }
            }

            // Check API -> DB
            foreach (var kvp in apiPosDict)
            {
                if (string.IsNullOrEmpty(kvp.Key)) continue;
                if (!dbPosDict.ContainsKey(kvp.Key))
                {
                    mismatches.Add(new { Token = kvp.Key, DB = 0, API = kvp.Value.Size, Reason = "Missing in DB" });
                }
            }

            return Results.Ok(new
            {
                TraderId = traderId,
                Mismatches = mismatches,
                Match = mismatches.Count == 0,
                DbPositionsCount = dbPosDict.Count,
                ApiPositionsCount = apiPosDict.Count
            });
        });

        // NOTE: a former POST /repair-db endpoint was removed here on purpose:
        // its raw SQL referenced non-existent columns/tables (Trades.Type/Payout,
        // Traders.LastPositionsUpdatedAt, table "Jobs") and would have deleted ALL
        // TraderPositions including the pruned-history conserves. The supported
        // repair path is the "Recalculate All Traders" action in the WinForms
        // Development menu (EmbeddedWebServer.RunRecalculateAllTradersAsync).
    }
}
