@inject IHttpClientFactory HttpClientFactory
@inject ISnackbar Snackbar

<div class="d-flex flex-column position-relative w-100 h-100">
    <MudCard Class="w-100" Elevation="5">
        <MudCardHeader>
            <MudText Typo="Typo.h5">Edge</MudText>
        </MudCardHeader>
        <MudCardContent>
            <div class="d-flex flex-column">

                <MudSelect Style="margin-left: 2rem" Margin="Margin.Dense" T="DirectionAllowed" @bind-Value="MapSettingDefaultDto.EdgeDirectionAllowed"
                           Label="Chiều cho phép di chuyển" Variant="Variant.Text" AnchorOrigin="Origin.BottomLeft">
                    <MudSelectItem Value="DirectionAllowed.Both" />
                    <MudSelectItem Value="DirectionAllowed.Forward" />
                    <MudSelectItem Value="DirectionAllowed.Backward" />
                    <MudSelectItem Value="DirectionAllowed.None" />
                </MudSelect>
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeMinLength" Min="0.1" Max="5" Step="0.1" Color="Color.Info">
                        Chiều dài tối thiểu khi tạo Edge (m)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeMinLength" Variant="Variant.Outlined" Min="0.1" Max="50" Step="0.1" />
                </div>
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeStraightMaxSpeed" Min="0" Max="5" Step="0.05" Color="Color.Info">
                        Vận tốc lớn nhất cho phép khi di chuyển trên Edge (thẳng) (m/s)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeStraightMaxSpeed" Variant="Variant.Outlined" Min="0" Max="5" Step="0.05" />
                </div>
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeCurveMaxSpeed" Min="0" Max="5" Step="0.05" Color="Color.Info">
                        Vận tốc lớn nhất cho phép khi di chuyển trên Edge (cong) (m/s)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeCurveMaxSpeed" Variant="Variant.Outlined" Min="0" Max="5" Step="0.05" />
                </div>
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeMaxHeight" Min="0.1" Max="5" Step="0.05" Color="Color.Info">
                        Chiều cao lớn nhất cho phép di chuyển trên Edge (m)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeMaxHeight" Variant="Variant.Outlined" Min="0.1" Max="50" Step="0.05" />
                </div>
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeMinHeight" Min="0.1" Max="5" Step="0.05" Color="Color.Info">
                        Chiều cao tối thiểu cho phép di chuyển trên Edge (m)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeMinHeight" Variant="Variant.Outlined" Min="0.1" Max="50" Step="0.05" />
                </div>

                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeMaxRotationSpeed" Min="0" Max="5" Step="0.05" Color="Color.Info">
                        Vận tốc quay lớn nhất cho phép di chuyển trên Edge (rad/s)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeMaxRotationSpeed" Variant="Variant.Outlined" Min="0" Max="5" Step="0.05" />
                </div>

                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeAllowedDeviationXy" Min="0" Max="1" Step="0.005" Color="Color.Info">
                        Sai số cho phép về tọa độ X,Y khi đi qua Edge (m)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeAllowedDeviationXy" Variant="Variant.Outlined" Min="0" Max="1" Step="0.005" />
                </div>

                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.EdgeAllowedDeviationTheta" Min="0" Max="180" Step="1" Color="Color.Info">
                        Sai số cho phép về góc khi đi qua Edge (degree)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.EdgeAllowedDeviationTheta" Variant="Variant.Outlined" Min="0" Max="180" Step="1" />
                </div>

                <div class="config-item">
                    <MudCheckBox @bind-Value="MapSettingDefaultDto.EdgeRotationAllowed" Label="Cho phép quay tại Edge" LabelPlacement="Placement.Start" UncheckedColor="Color.Default" Color="Color.Success"></MudCheckBox>
                </div>
            </div>
        </MudCardContent>
    </MudCard>

    <MudCard Class="w-100 mt-6" Elevation="5">
        <MudCardHeader>
            <MudText Typo="Typo.h5">Node</MudText>
        </MudCardHeader>
        <MudCardContent>
            <div class="d-flex flex-column">
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.NodeAllowedDeviationXy" Min="0" Max="1" Step="0.005" Color="Color.Info">
                        Sai số cho phép về tọa độ X,Y khi đi qua Node (m)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.NodeAllowedDeviationXy" Variant="Variant.Outlined" Min="0" Max="1" Step="0.005" />
                </div>

                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.NodeAllowedDeviationTheta" Min="0" Max="180" Step="1" Color="Color.Info">
                        Sai số cho phép về góc khi đi qua Node (degree)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.NodeAllowedDeviationTheta" Variant="Variant.Outlined" Min="0" Max="180" Step="1" />
                </div>

                <div class="config-item">
                    <MudCheckBox @bind-Value="MapSettingDefaultDto.NodeNameAutoGenerate" Class="mt-2" Label="Tự động tạo tên cho Node" LabelPlacement="Placement.Start" UncheckedColor="Color.Default" Color="Color.Success"></MudCheckBox>
                    <MudTextField @bind-Value="MapSettingDefaultDto.NodeNameTemplate" Label="Template" Disabled="@(!MapSettingDefaultDto.NodeNameAutoGenerate)" Style="width: 20%" ShrinkLabel Variant="Variant.Outlined" />
                </div>
            </div>
        </MudCardContent>
    </MudCard>

    <MudCard Class="w-100 mt-6" Elevation="5">
        <MudCardHeader>
            <MudText Typo="Typo.h5">Zone</MudText>
        </MudCardHeader>
        <MudCardContent>
            <div class="d-flex flex-column">
                <div class="config-item">
                    <MudSlider T="double" Class="me-2" @bind-Value="MapSettingDefaultDto.ZoneMinSquare" Min="0.1" Max="5" Step="0.1" Color="Color.Info">
                        Diện tích tối thiểu khi tạo Zone (m2)
                    </MudSlider>
                    <MudNumericField Class="mb-0 mt-0" Margin="Margin.Dense" Style="width: 100px;margin-top: 6px;" T="double" @bind-Value="MapSettingDefaultDto.ZoneMinSquare" Variant="Variant.Outlined" Min="0.1" Max="50" Step="0.1" />
                </div>
            </div>
        </MudCardContent>
    </MudCard>

    <MudOverlay Visible="OverlayVisible" DarkBackground="true" Absolute="true">
        <MudProgressCircular Color="Color.Secondary" Indeterminate="true" />
    </MudOverlay>
</div>


@code {
    [Parameter, EditorRequired]
    public Guid Id { get; set; }

    private readonly MapSettingDefaultDto MapSettingDefaultDto = new();
    private readonly MapSettingDefaultDto MapSettingDefaultResetDto = new();

    private bool OverlayVisible;
    private HttpClient Http = default!;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (!firstRender) return;

        Http = HttpClientFactory.CreateClient("MapManagerAPI");
        await LoadMapVersionConfig();
        StateHasChanged();
    }

    private async Task LoadMapVersionConfig()
    {
        OverlayVisible = true;
        StateHasChanged();

        var result = await Http.GetFromJsonAsync<MessageResult<MapSettingDefaultDto>>($"api/MapsSetting/{Id}");

        if (result == null)
        {
            Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
            return;
        }
        if (!result.IsSuccess)
        {
            Snackbar.Add(result.Message, Severity.Error);
            return;
        }
        if (result.Data == null)
        {
            Snackbar.Add("Không tìm thấy cấu hình mặc định cho bản đồ này", Severity.Error);
            return;
        }

        SetConfigBindingDto(result.Data);
        SetConfigResetDto(result.Data);

        OverlayVisible = false;
        StateHasChanged();
    }

    private void SetConfigResetDto(MapSettingDefaultDto dto)
    {
        MapSettingDefaultResetDto.Id = dto.Id;

        MapSettingDefaultResetDto.EdgeMinLength = dto.EdgeMinLength;
        MapSettingDefaultResetDto.EdgeMinHeight = dto.EdgeMinHeight;
        MapSettingDefaultResetDto.EdgeMaxHeight = dto.EdgeMaxHeight;
        MapSettingDefaultResetDto.EdgeMaxRotationSpeed = dto.EdgeMaxRotationSpeed;
        MapSettingDefaultResetDto.EdgeStraightMaxSpeed = dto.EdgeStraightMaxSpeed;
        MapSettingDefaultResetDto.EdgeCurveMaxSpeed = dto.EdgeCurveMaxSpeed;
        MapSettingDefaultResetDto.EdgeDirectionAllowed = dto.EdgeDirectionAllowed;
        MapSettingDefaultResetDto.EdgeRotationAllowed = dto.EdgeRotationAllowed;
        MapSettingDefaultResetDto.EdgeAllowedDeviationXy = dto.EdgeAllowedDeviationXy;
        MapSettingDefaultResetDto.EdgeAllowedDeviationTheta = dto.EdgeAllowedDeviationTheta;

        MapSettingDefaultResetDto.NodeAllowedDeviationXy = dto.NodeAllowedDeviationXy;
        MapSettingDefaultResetDto.NodeAllowedDeviationTheta = dto.NodeAllowedDeviationTheta;
        MapSettingDefaultResetDto.NodeNameAutoGenerate = dto.NodeNameAutoGenerate;
        MapSettingDefaultResetDto.NodeNameTemplate = dto.NodeNameTemplate;

        MapSettingDefaultResetDto.ZoneMinSquare = dto.ZoneMinSquare;
    }

    private void SetConfigBindingDto(MapSettingDefaultDto dto)
    {
        MapSettingDefaultDto.Id = dto.Id;

        MapSettingDefaultDto.EdgeMinLength = dto.EdgeMinLength;
        MapSettingDefaultDto.EdgeMinHeight = dto.EdgeMinHeight;
        MapSettingDefaultDto.EdgeMaxHeight = dto.EdgeMaxHeight;
        MapSettingDefaultDto.EdgeMaxRotationSpeed = dto.EdgeMaxRotationSpeed;
        MapSettingDefaultDto.EdgeStraightMaxSpeed = dto.EdgeStraightMaxSpeed;
        MapSettingDefaultDto.EdgeCurveMaxSpeed = dto.EdgeCurveMaxSpeed;
        MapSettingDefaultDto.EdgeDirectionAllowed = dto.EdgeDirectionAllowed;
        MapSettingDefaultDto.EdgeRotationAllowed = dto.EdgeRotationAllowed;
        MapSettingDefaultDto.EdgeAllowedDeviationXy = dto.EdgeAllowedDeviationXy;
        MapSettingDefaultDto.EdgeAllowedDeviationTheta = dto.EdgeAllowedDeviationTheta;

        MapSettingDefaultDto.NodeAllowedDeviationXy = dto.NodeAllowedDeviationXy;
        MapSettingDefaultDto.NodeAllowedDeviationTheta = dto.NodeAllowedDeviationTheta;
        MapSettingDefaultDto.NodeNameAutoGenerate = dto.NodeNameAutoGenerate;
        MapSettingDefaultDto.NodeNameTemplate = dto.NodeNameTemplate;

        MapSettingDefaultDto.ZoneMinSquare = dto.ZoneMinSquare;
    }

    public void Reset()
    {
        SetConfigBindingDto(MapSettingDefaultResetDto);
        StateHasChanged();
    }

    public async Task Save()
    {
        if (!ValidateUpdateData(MapSettingDefaultResetDto, MapSettingDefaultDto))
        {
            Snackbar.Add("Không có sự thay đổi", Severity.Warning);
            return;
        }

        var result = await (await Http.PutAsJsonAsync<MapSettingDefaultDto>("api/MapsSetting", MapSettingDefaultDto)).Content.ReadFromJsonAsync<MessageResult>();

        if (result == null)
        {
            Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
            return;
        }
        else if (!result.IsSuccess)
        {
            Snackbar.Add(result.Message, Severity.Error);
            return;
        }

        SetConfigResetDto(MapSettingDefaultDto);
        Snackbar.Add("Cập nhật thành công", Severity.Success);
        StateHasChanged();
    }

    private bool ValidateUpdateData(MapSettingDefaultDto old, MapSettingDefaultDto update)
    {
        if (old.EdgeStraightMaxSpeed != update.EdgeStraightMaxSpeed) return true;
        if (old.EdgeCurveMaxSpeed != update.EdgeCurveMaxSpeed) return true;
        if (old.EdgeMaxRotationSpeed != update.EdgeMaxRotationSpeed) return true;
        if (old.EdgeMinLength != update.EdgeMinLength) return true;
        if (old.EdgeMinHeight != update.EdgeMinHeight) return true;
        if (old.EdgeMaxHeight != update.EdgeMaxHeight) return true;
        if (old.EdgeDirectionAllowed != update.EdgeDirectionAllowed) return true;
        if (old.EdgeRotationAllowed != update.EdgeRotationAllowed) return true;
        if (old.EdgeAllowedDeviationXy != update.EdgeAllowedDeviationXy) return true;
        if (old.EdgeAllowedDeviationTheta != update.EdgeAllowedDeviationTheta) return true;

        if (old.NodeAllowedDeviationXy != update.NodeAllowedDeviationXy) return true;
        if (old.NodeAllowedDeviationTheta != update.NodeAllowedDeviationTheta) return true;
        if (old.NodeNameAutoGenerate != update.NodeNameAutoGenerate) return true;
        if (old.NodeNameTemplate != update.NodeNameTemplate) return true;

        if (old.ZoneMinSquare != update.ZoneMinSquare) return true;
        return false;
    }
}
