using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
using RpgRoller.Contracts;

namespace RpgRoller.Components.Pages.HomeControls;

[ExcludeFromCodeCoverage]
public partial class CharacterFormModal
{
    protected override void OnParametersSet()
    {
        if (!Visible || FormVersion == AppliedFormVersion)
            return;

        FormState.Model.Name = InitialModel.Name;
        FormState.Model.CampaignId = InitialModel.CampaignId;
        FormState.Model.OwnerUsername = InitialModel.OwnerUsername;
        FormState.ResetValidation();
        AppliedFormVersion = FormVersion;
    }

    private async Task SubmitAsync()
    {
        FormState.ResetValidation();

        if (string.IsNullOrWhiteSpace(FormState.Model.Name))
            FormState.Errors["name"] = "Character name is required.";

        Guid? campaignId = null;
        if (!string.IsNullOrWhiteSpace(FormState.Model.CampaignId))
        {
            if (!Guid.TryParse(FormState.Model.CampaignId, out var parsedCampaignId))
                FormState.Errors["campaignId"] = "Campaign selection is invalid.";
            else
                campaignId = parsedCampaignId;
        }

        if (!EditingCharacterId.HasValue && !campaignId.HasValue)
            FormState.Errors["campaignId"] = "Campaign is required.";

        if (FormState.Errors.Count > 0)
        {
            FormState.ErrorMessage = "Resolve validation issues before submitting.";
            return;
        }

        IsSubmitting = true;
        try
        {
            CharacterSummary character;
            if (EditingCharacterId.HasValue)
            {
                var ownerUsername = AllowOwnerEdit && !string.IsNullOrWhiteSpace(FormState.Model.OwnerUsername) ? FormState.Model.OwnerUsername.Trim() : null;
                character = await ApiClient.RequestAsync<CharacterSummary>("PUT", $"/api/characters/{EditingCharacterId.Value}", new UpdateCharacterRequest(FormState.Model.Name.Trim(), campaignId, ownerUsername));
            }
            else
                character = await ApiClient.RequestAsync<CharacterSummary>("POST", "/api/characters", new CreateCharacterRequest(FormState.Model.Name.Trim(), campaignId!.Value));

            await CharacterSaved.InvokeAsync(character.CampaignId);
        }
        catch (ApiRequestException ex)
        {
            FormState.ErrorMessage = ex.Message;
        }
        finally
        {
            IsSubmitting = false;
        }
    }

    [Inject]
    private RpgRollerApiClient ApiClient { get; set; } = null!;

    private FormState<CharacterFormModel> FormState { get; } = new();
    private int AppliedFormVersion { get; set; } = -1;
    private bool IsSubmitting { get; set; }

    [Parameter]
    public bool Visible { get; set; }

    [Parameter]
    public string Title { get; set; } = "Character";

    [Parameter]
    public string SubmitLabel { get; set; } = "Save";

    [Parameter]
    public string NameInputId { get; set; } = "character-name";

    [Parameter]
    public string CampaignInputId { get; set; } = "character-campaign";

    [Parameter]
    public string OwnerUsernameInputId { get; set; } = "character-owner-username";

    [Parameter]
    public CharacterFormModel InitialModel { get; set; } = new();

    [Parameter]
    public int FormVersion { get; set; }

    [Parameter]
    public Guid? EditingCharacterId { get; set; }

    [Parameter]
    public IReadOnlyList<CampaignOption> CampaignOptions { get; set; } = [];

    [Parameter]
    public bool IsMutating { get; set; }

    [Parameter]
    public bool AllowOwnerEdit { get; set; }

    [Parameter]
    public IReadOnlyList<string> AvailableUsernames { get; set; } = [];

    [Parameter]
    public EventCallback<Guid?> CharacterSaved { get; set; }

    [Parameter]
    public EventCallback CancelRequested { get; set; }
}