@*
 *                                dbMango
 *
 * Copyright 2025 Deutsche Bank AG
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *@
﻿<style>
    .full-width {
    width: 408px !important;
    }

    .column-cb {
        min-width: 30px;
        width: 30px;
    }

    .min-w {
        min-width: 100px;
    }

    .btn-toggle {
        width: 24px;
        height: 24px;
        padding: 0;
        margin: 0;
        border: none;
    }

</style>

<TableControl   Class="full-width table table-hover table-striped table-forge table-forge-striped mr-3" 
                Items="@AllRoles" 
                PageSize="25" 
                Filterable="false">
            
    <TableColumnControl Name="Role" Field="Role" Class="min-w"/>
    <TableColumnControl Name="Db"   Field="Db"   Class="min-w"/>

    <TableColumnControl Name="Selected" Field="IsSelected" Class="column-cb align-right" Sortable="false" Filterable="false">
        <Template Context="ctx">
            <FormToggleButton Enabled="@IsEnabled" Class="btn-toggle" GetIcon="@GetIcon" Arg="@((RoleInDbModel)ctx.Row)" OnClick="@(() => OnToggleClicked((RoleInDbModel)ctx.Row))" />
        </Template>
    </TableColumnControl>
</TableControl>

@code {
    [Parameter]
    public List<RoleInDbModel> Value
    {
        get => field;
        set
        {
            if (field == value)
                return;
            field = value;
            UpdateSelectable();
        }
    } = new();

    [Parameter]
    public List<RoleInDbModel> AllRoles
    {
        get;
        set 
        {
            if (field == value)
                return;
            field = value;
            UpdateSelectable();
        }
    } = [];


    [Parameter] public bool         IsEnabled        { get; set; } = true;

    public class SelectableString(string name, bool isSelected, Action<SelectableString, bool> update)
    {
        public override string ToString() => $"[{(IsSelected ? "X" : " ")}] {Name} {Db}";

        public string Name { get; } = name;
        public string Db   { get; init; } = string.Empty;

        public bool IsSelected
        {
            get;
            set
            {
                if (field == value)
                    return;
                field = value;
                update(this, field);
            }
        } = isSelected;
    }

    // ReSharper disable once UnusedAutoPropertyAccessor.Local
    private List<SelectableString> SelectableRoles   { get; set; } = [];

    private void UpdateSelectable()
    {
        SelectableRoles = AllRoles
           .Select(x =>
                       new SelectableString(x.Role, Value.Any(y => IsSameRole(x, y)), UpdateSelectedRoles)
                           {
                               Db = x.Db
                           }
            )
           .ToList();

        InvokeAsync(StateHasChanged);
    }

    private static bool IsSameRole(RoleInDbModel x, RoleInDbModel y)    => x.Role == y.Role && (x.Db == y.Db || string.IsNullOrWhiteSpace(x.Db) || string.IsNullOrWhiteSpace(y.Db));
    private static bool IsSameRole(RoleInDbModel x, SelectableString y) => x.Role == y.Name && (x.Db == y.Db || string.IsNullOrWhiteSpace(x.Db) || string.IsNullOrWhiteSpace(y.Db));


    private void UpdateSelectedRoles(SelectableString role, bool isSelected)
    {
        var found = Value.FirstOrDefault(x => IsSameRole(x, role));
        if (isSelected)
        {
            if (found == null)
                Value.Add(new () { Role = role.Name, Db = role.Db});
        }
        else
        {
            if (found != null)
                Value.Remove(found);
        }
    }

    private string GetIcon(RoleInDbModel role)
    {
        var found = Value.FirstOrDefault(x => IsSameRole(x, role));
        return found != null ? "icon-checkmark-sm" : "";
    }

    private void OnToggleClicked(RoleInDbModel role)
    {
        var found = Value.FirstOrDefault(x => IsSameRole(x, role));
        // Add logic to toggle the selection state of the role
        if (found != null)
        {
            // Role is selected, remove it
            Value.Remove(found);
        }
        else
        {
            // Role is not selected, add it
            Value.Add(new () { Role = role.Role, Db = role.Db });
        }

        InvokeAsync(StateHasChanged);
    }

}
