using System.Text.Json.Serialization;
using Prospect.Server.Api.Services.CloudScript;
using Prospect.Server.Api.Services.Auth.Extensions;
using Prospect.Server.Api.Services.Database;
using Prospect.Server.Api.Services.Database.Models;
using Prospect.Server.Api.Services.Squad;
using Microsoft.AspNetCore.SignalR;
using Prospect.Server.Api.Hubs;

public class SquadMemberReadyForMatchRequest
{
    [JsonPropertyName("squadId")]
    public string SquadID { get; set; }
    [JsonPropertyName("matchmakingSettings")]
	public FYUserMatchmakingSettings matchmakingSettings { get; set; }
}

public class SquadMemberReadyForMatchResponse
{
    [JsonPropertyName("result")]
	public int Result { get; set; } // EYSquadActionResult
    [JsonPropertyName("squad")]
	public FYPlayFabSquad Squad { get; set; }
    [JsonPropertyName("isSquadReadyForMatch")]
	public bool IsSquadReadyForMatch { get; set; }
}

[CloudScriptFunction("SquadMemberReadyForMatch")]
public class SquadMemberReadyForMatchFunction : ICloudScriptFunction<SquadMemberReadyForMatchRequest, SquadMemberReadyForMatchResponse>
{
    private readonly ILogger<SquadMemberReadyForMatchFunction> _logger;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly IHubContext<CycleHub> _hubContext;
    private readonly SquadService _squadService;
    private readonly DbUserService _userService;

    public SquadMemberReadyForMatchFunction(ILogger<SquadMemberReadyForMatchFunction> logger, IHttpContextAccessor httpContextAccessor, IHubContext<CycleHub> hubContext, SquadService squadService, DbUserService userService)
    {
        _httpContextAccessor = httpContextAccessor;
        _logger = logger;
        _hubContext = hubContext;
        _squadService = squadService;
        _userService = userService;
    }

    public async Task<SquadMemberReadyForMatchResponse> ExecuteAsync(SquadMemberReadyForMatchRequest request)
    {
        var context = _httpContextAccessor.HttpContext;
        if (context == null)
        {
            throw new CloudScriptException("CloudScript was not called within a http request");
        }
        var userId = context.User.FindAuthUserId();
        var squadId = string.IsNullOrEmpty(request.SquadID) ? userId : request.SquadID;

        // Register the caller into the squad (party is formed client-side; each member's client
        // calls this with the shared squadId) and record their readiness / selected map.
        var displayName = (await _userService.FindByIdAsync(userId))?.DisplayName ?? "";
        _squadService.JoinOrCreate(squadId, userId, displayName);
        var ready = request.matchmakingSettings?.isReadyForMatch ?? false;
        _squadService.SetReady(squadId, userId, ready, request.matchmakingSettings?.selectedMapName);

        var squad = _squadService.Get(squadId)!;
        var isSquadReady = _squadService.IsSquadReady(squadId);
        _logger.LogInformation("SquadMemberReadyForMatch: {User} ready={Ready} in squad {Squad} ({Count} member(s), squadReady={SquadReady})",
            userId, ready, squadId, squad.Members.Count, isSquadReady);

        return new SquadMemberReadyForMatchResponse
        {
            Result = 0, // EYSquadActionResult::OK
            Squad = _squadService.ToClientSquad(squad),
            IsSquadReadyForMatch = isSquadReady,
        };
    }
}
