using MudBlazor;
using NetinaShop.Common.Models.Mapper;
using NetinaShop.Domain.Entities.Blogs;
using NetinaShop.Domain.Entities.Users;

namespace NetinaShop.AdminPanel.PWA.Pages;

public class UserSettingsPageViewModel : BaseViewModel
{
    private readonly NavigationManager _navigationManager;
    private readonly ISnackbar _snackbar;
    private readonly IUserUtility _userUtility;
    private readonly IDialogService _dialogService;
    private readonly IRestWrapper _restWrapper;

    public string Search = string.Empty;
    public int UsersCurrentPage = 0;
    public int UsersPageCount = 1;

    public int RolesCurrentPage = 0;
    public int RolesPageCount = 1;

    public ObservableCollection<ApplicationUserSDto> Users { get; set; } = new ObservableCollection<ApplicationUserSDto>();
    public ObservableCollection<ApplicationRole> Roles { get; set; } = new ObservableCollection<ApplicationRole>();

    public UserSettingsPageViewModel(NavigationManager navigationManager,
        ISnackbar snackbar,
        IUserUtility userUtility,
        IRestWrapper restWrapper,
        IDialogService dialogService)
    {
        _navigationManager = navigationManager;
        _snackbar = snackbar;
        _userUtility = userUtility;
        _restWrapper = restWrapper;
        _dialogService = dialogService;
    }

    public override async Task InitializeAsync()
    {
        try
        {
            var token = await _userUtility.GetBearerTokenAsync();
            if (token == null)
                throw new Exception("Token is null");
            IsProcessing = true;
            Users.Clear();
            var dto = await _restWrapper.UserRestApi.ReadAll(UsersCurrentPage, token);
            dto.ForEach(d => Users.Add(d));
            if (Users.Count == 15)
                UsersPageCount = 2;


            Roles.Clear();
            var roleDtos = await _restWrapper.RoleRestApi.ReadAll(RolesCurrentPage, token);
            roleDtos.ForEach(d => Roles.Add(d));
            if (Users.Count == 15)
                UsersPageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
        await base.InitializeAsync();
    }

    public async Task ChangeUserPageAsync(int page)
    {
        UsersCurrentPage = page - 1;
        if (UsersCurrentPage > UsersPageCount - 2)
        {

            try
            {
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                IsProcessing = true;

                List<ApplicationUserSDto> dto = new List<ApplicationUserSDto>();
                if (Search.IsNullOrEmpty())
                {
                    dto = await _restWrapper.UserRestApi.ReadAll(UsersCurrentPage,token);
                }
                else
                {
                    dto = await _restWrapper.UserRestApi.ReadAll(UsersCurrentPage, Search);
                }

                dto.ForEach(d => Users.Add(d));
                if (Users.Count % 20 == 0)
                    UsersPageCount = UsersCurrentPage + 2;

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }


    public async Task ChangeRolePageAsync(int page)
    {
        RolesCurrentPage = page - 1;
        if (RolesCurrentPage > RolesPageCount - 2)
        {

            try
            {
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                IsProcessing = true;


                var roleDtos = await _restWrapper.RoleRestApi.ReadAll(RolesCurrentPage, token);
                roleDtos.ForEach(d => Roles.Add(d));
                if (Users.Count == 15)
                    RolesPageCount = RolesCurrentPage + 2;

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }

    public async Task AddRoleClicked()
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
        var dialogResult =await _dialogService.ShowAsync<RoleActionDialogBox>("افزودن نقش جدید", maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }
    public async Task EditRoleClicked(ApplicationRole role)
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
        var parameters = new DialogParameters<RoleActionDialogBox>();
        parameters.Add(x => x.Role, role);
        var dialogResult = await _dialogService.ShowAsync<RoleActionDialogBox>($"ویرایش نقش {role.PersianName}", parameters, maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task DeleteRoleAsync(Guid selectedRoleId)
    {
        var options = new DialogOptions { CloseOnEscapeKey = true };
        var parameters = new DialogParameters<QuestionDialog>();
        parameters.Add(x => x.ContentText, "آیا از حذف نقش اطمینان دارید ?");
        var dialogReference = await _dialogService.ShowAsync<QuestionDialog>("حذف نقش", parameters, options);
        var result = await dialogReference.Result;
        if (!result.Canceled)
        {

            try
            {

                IsProcessing = true;
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                await _restWrapper.CrudApiRest<ApplicationRole, Guid>(Address.RoleController).Delete(selectedRoleId, token);
                _snackbar.Add("حذف نقش با موفقیت انجام شد", Severity.Success);
                await InitializeAsync();

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }

    public async Task AddUserClicked()
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
        var dialogResult = await _dialogService.ShowAsync<UserActionDialogBox>("افزودن کاربر جدید", maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task EditUserClicked(ApplicationUserSDto user)
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
        var parameters = new DialogParameters<UserActionDialogBox>();
        parameters.Add(x => x.User, user);
        var dialogResult = await _dialogService.ShowAsync<UserActionDialogBox>($"ویرایش {user.FirstName + " " + user.LastName}", parameters, maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task DeleteUserAsync(Guid selectedUserId)
    {
        var options = new DialogOptions { CloseOnEscapeKey = true };
        var parameters = new DialogParameters<QuestionDialog>();
        parameters.Add(x => x.ContentText, "آیا از حذف کاربر اطمینان دارید ?");
        var dialogReference = await _dialogService.ShowAsync<QuestionDialog>("حذف کاربر", parameters, options);
        var result = await dialogReference.Result;
        if (!result.Canceled)
        {

            try
            {

                IsProcessing = true;
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                await _restWrapper.CrudApiRest<ApplicationUser, Guid>(Address.UserController).Delete(selectedUserId, token);
                _snackbar.Add("حذف کاربر با موفقیت انجام شد", Severity.Success);
                await InitializeAsync();

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }

    public async Task SearchUserChanged(string search)
    {
        if (search.IsNullOrEmpty() && !Search.IsNullOrEmpty())
            await InitializeAsync();
        Search = search;
    }
    public async Task SearchUserAsync()
    {
        try
        {
            if (Search.IsNullOrEmpty())
                throw new AppException("نام بلاگ برای جست جو وارد نشده است");
            IsProcessing = true;
            UsersCurrentPage = 0;
            UsersPageCount = 1;
            Users.Clear();
            var dto = await _restWrapper.UserRestApi.ReadAll(UsersCurrentPage, Search);
            dto.ForEach(d => Users.Add(d));
            if (Users.Count == 20)
                UsersPageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
    }
}