using AntDesign.TableModels;
using EasyTemplate.Tool;
using Microsoft.JSInterop;
using SqlSugar;

namespace EasyTemplate.Blazor.Web.Components.Pages.Management.Role;

public partial class Role
{
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            DefaultCheckedKeys = Global.Menus.Where(x => x.Necessary == true).Select(x => x.Id.ToString()).ToArray();
            await NavigationManager.RedirectLogin(IJSRuntime);
            //await Query();
        }
    }

    /// <summary>
    /// 查
    /// </summary>
    /// <returns></returns>
    private async Task Query()
    {
        Loading = true;
        RefAsync<int> total = 0;
        var res = await Repository.AsQueryable()
            .WhereIF(!string.IsNullOrWhiteSpace(Q_Name), x => x.Name.Contains(Q_Name))
            .OrderByDescending(x => x.Id)
            .ToPageListAsync(Pi, Ps, total);
        Total = total.Value;
        DataSource = res;
        Loading = false;
        //_table.ReloadData();
    }

    /// <summary>
    /// 增/改
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    private async Task<bool> InsertOrUpdate(SystemRole data)
    {
        bool flag = false;
        if (data.Id == 0)
        {
            if (Repository.AsQueryable().Any(x => x.Name.ToLower() == data.Name.ToLower()))
            {
                MessageService.Error("该账号名已存在");
                return false;
            }

            var id = Repository.AsInsertable(data).ExecuteReturnIdentity();
            RoleMenu.Insert(new SystemRoleMenu() { RoleId = id, MenuId = 1 });

            return id > 0;
        }
        else
        {
            if (Repository.AsQueryable().Any(x => x.Name.ToLower() == data.Name.ToLower() && x.Id != data.Id))
            {
                MessageService.Error("该账号名已存在");
                return false;
            }

            return await Repository.AsUpdateable()
                .SetColumns(x => x.Name == data.Name)
                .SetColumns(x => x.RoleType == data.RoleType)
                .SetColumns(x => x.Enabled == data.Enabled)
                .Where(x => x.Id == data.Id)
                .ExecuteCommandAsync() > 0;
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="row"></param>
    /// <returns></returns>
    private async Task Delete(SystemRole row)
    {
        if (!await Comfirm($"确认删除 [{row.Name}] ?")) return;

        var flag = await Repository.AsUpdateable()
            .SetColumns(x => x.IsDelete == true)
            .Where(x => x.Id == row.Id)
            .ExecuteCommandAsync() > 0;

        Table.ReloadData(Pi, Ps);
    }

    /// <summary>
    /// 
    /// </summary>
    private void UpdateMenu()
    {
        if (SelectedRow is null)
        {
            MessageService.Error("请先选择一个角色");
            return;
        }

        var nodes = Tree.CheckedKeys;
        if (nodes.Length == 0)
        {
            MessageService.Error("请选择菜单");
            return;
        }

        bool flag = false;
        try
        {
            RoleMenu.Context.Ado.BeginTran();

            RoleMenu.AsDeleteable().Where(x => x.RoleId == SelectedRow.Data.Id).ExecuteCommand();

            var menuIds = CalculateIds(nodes.ToList());
            var menus = menuIds.Select(x => new SystemRoleMenu() { RoleId = SelectedRow.Data.Id, MenuId = Convert.ToInt32(x) }).ToList();
            flag = RoleMenu.InsertRange(menus);

            RoleMenu.Context.Ado.CommitTran();
        }
        catch (Exception ex)
        {
            RoleMenu.Context.Ado.RollbackTran();
            flag = false;
        }

        if (flag)
        {
            MessageService.Success("修改成功");
        }
        else
        {
            MessageService.Error("修改失败");
        }

        CheckedKeys = Tree.CheckedKeys;
        SelectedRow = null;

        Table.ReloadData(Pi, Ps);
        //StateHasChanged();
    }

    private List<long> CalculateIds(List<string> ids)
    {
        var result = new List<long>();

        foreach (var id in ids)
        {
            var menuId = long.Parse(id);
            AddParentIds(menuId, result);
        }

        return result;
    }

    private void AddParentIds(long id, List<long> result)
    {
        var menu = Menu.AsQueryable().First(m => m.Id == id);
        if (menu != null && !result.Contains(menu.Id))
        {
            result.Add(menu.Id);
            if (menu.ParentId != 0)
            {
                AddParentIds(menu.ParentId, result);
            }
        }
    }

    /// <summary>
    /// 重置查询
    /// </summary>
    private async Task ResetQuery()
    {
        Q_Name = string.Empty;
        Pi = 1;
        await Query();
    }

    protected override async void OnInitialized()
    {
        await Query();
    }

    private async Task OnChange(QueryModel<SystemRole> query)
        => await Query();

    private async Task Search()
        => await Query();

    private void OnRowClick(RowData<SystemRole> row)
    {
        SelectedRow = row;
        CheckedKeys = RoleMenu.AsQueryable()
                    .LeftJoin<SystemMenu>((rm, m) => rm.MenuId == m.Id)
                    .Where((rm, m) => rm.RoleId == row.Data.Id)
                    .Select((rm, m) => m.Id.ToString())
                    .ToArray();

        //这里最好做一下筛选，也可以不做，目的是去除Global.Menus树形结构中没有的数据，如果_CheckedKeys有，而Global.Menus没有，会报错
        //一般出现的情形是有人从数据库删除了某个菜单项，但前端没有及时刷新，导致_CheckedKeys与Global.Menus数据不匹配
        CheckedKeys = FilterCheckedKeys(CheckedKeys, Global.Menus);
    }

    /// <summary>
    /// 过滤已选中的菜单项，确保它们在菜单树中存在
    /// </summary>
    /// <param name="checkedKeys"></param>
    /// <param name="menuTree"></param>
    /// <returns></returns>
    private string[] FilterCheckedKeys(string[] checkedKeys, List<SystemMenu> menuTree)
    {
        var validIds = new HashSet<string>();
        void CollectIds(List<SystemMenu> menus)
        {
            if (menus == null) return;
            foreach (var menu in menus)
            {
                validIds.Add(menu.Id.ToString());
                if (menu.Children != null && menu.Children.Count > 0)
                    CollectIds(menu.Children);
            }
        }
        CollectIds(menuTree);

        return checkedKeys.Where(id => validIds.Contains(id)).ToArray();
    }

    private void CheckedChanged(SystemRole row)
    {
        Repository.AsUpdateable()
            .SetColumns(x => x.Enabled == row.Enabled)
            .Where(x => x.Id == row.Id)
            .ExecuteCommand();
        //_table.ReloadData();
    }

    /// <summary>
    /// 注入实例
    /// </summary>
    [Inject] private SqlSugarRepository<SystemRole> Repository { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [Inject] private SqlSugarRepository<SystemRoleMenu> RoleMenu { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [Inject] private SqlSugarRepository<SystemMenu> Menu { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [Inject] NavigationManager NavigationManager { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [Inject] IJSRuntime IJSRuntime { get; set; }
    /// <summary>
    /// 账号
    /// </summary>
    private string Q_Name { get; set; }
    /// <summary>
    /// 
    /// </summary>
    private string[] DefaultCheckedKeys = [];
    /// <summary>
    /// 
    /// </summary>
    private string[] CheckedKeys = [];
    /// <summary>
    /// 
    /// </summary>
    private RowData<SystemRole> SelectedRow;
    /// <summary>
    ///
    /// </summary>
    private ITable Table;
    /// <summary>
    ///
    /// </summary>
    private Tree<SystemMenu> Tree;
    /// <summary>
    ///
    /// </summary>
    private IEnumerable<SystemRole> SelectedRows = [];
    /// <summary>
    ///
    /// </summary>
    private List<SystemRole> DataSource;
    /// <summary>
    ///
    /// </summary>
    private int Pi = 1;
    /// <summary>
    ///
    /// </summary>
    private int Ps = 20;
    /// <summary>
    ///
    /// </summary>
    private int Total;
    /// <summary>
    ///
    /// </summary>
    private bool Loading = false;
    /// <summary>
    ///
    /// </summary>
    Func<PaginationTotalContext, string> ShowTotal => x => $"总共 {Total} 条";
}


