using Microsoft.AspNetCore.Components.Forms;

namespace NetinaShop.AdminPanel.PWA.Dialogs;

public class StorageDialogBoxViewModel : BaseViewModel
{
    private readonly IRestWrapper _restWrapper;
    private readonly IUserUtility _userUtility;
    private readonly ISnackbar _snackbar;

    private readonly MudDialogInstance _mudDialog;

    public readonly ObservableCollection<StorageFileSDto> Files = new ObservableCollection<StorageFileSDto>();
    public List<StorageFileSDto> OriginalFiles = new List<StorageFileSDto>();
    public string Search = string.Empty;
    public bool IsPrimary { get; set; }
    public bool IsHeader { get; set; }

    public StorageDialogBoxViewModel(IRestWrapper restWrapper, IUserUtility userUtility, ISnackbar snackbar, MudDialogInstance mudDialog)
    {
        _restWrapper = restWrapper;
        _userUtility = userUtility;
        _snackbar = snackbar;
        _mudDialog = mudDialog;
    }


    public void Cancel() => _mudDialog.Cancel();
    public void SelectFile(StorageFileSDto item)
    {
        var pastSelect = Files.FirstOrDefault(f => f.Selected);
        if (pastSelect != null)
            pastSelect.Selected = false;
        item.Selected = true;
    }

    public void UnSelectFile(StorageFileSDto item) => item.Selected = false;

    public void SearchChanged(string search)
    {
        if (search.IsNullOrEmpty() && !Search.IsNullOrEmpty())
        {
            Files.Clear();
            OriginalFiles.ForEach(f => Files.Add(f));
        }
        Search = search;
    }
    public void SearchAsync()
    {
        try
        {
            if (Search.IsNullOrEmpty())
                throw new AppException("نام فایل برای جست جو وارد نشده است");
            Files.Clear();
            foreach (var storageFileSDto in OriginalFiles.Where(f => f.FileName.ToLower().Trim().Contains(Search.ToLower().Trim())))
                Files.Add(storageFileSDto);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
    }

    public void SelectFile()
    {
        try
        {
            var selected = Files.FirstOrDefault(f => f.Selected);
            if (selected == null)
                throw new Exception("یک فایل را انتخاب کنید");
            selected.IsHeader = IsHeader;
            selected.IsPrimary = IsPrimary;
            _mudDialog.Close(selected);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
    }

    public override async Task InitializeAsync()
    {
        try
        {
            IsProcessing = true;
            Files.Clear();
            var token = await _userUtility.GetBearerTokenAsync();
            var files = await _restWrapper.FileRestApi.GetFilesAsync(token);
            files.ForEach(f => Files.Add(f));
            OriginalFiles = files;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            if (exe != null)
                _snackbar.Add(exe.Message, Severity.Error);
            _snackbar.Add(ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {
            IsProcessing = false;
        }
    }

    public async Task FileChangeForUpload(InputFileChangeEventArgs obj)
    {
        try
        {
            IsProcessing = true;
            using var memoryStream = new MemoryStream();
            var file = obj.File;
            var stream = file.OpenReadStream();
            await stream.CopyToAsync(memoryStream);

            var fileUpload = new FileUploadRequest
            {
                ContentType = file.ContentType,
                FileName = file.Name,
                FileUploadType = FileUploadType.Image,
                StringBaseFile = Convert.ToBase64String(memoryStream.ToArray())
            };
            var token = await _userUtility.GetBearerTokenAsync();
            var rest = await _restWrapper.FileRestApi.UploadFileAsync(fileUpload, token);
            Files.Insert(0, new StorageFileSDto
            {
                FileLocation = rest.FileLocation,
                FileName = rest.FileName,
                FileType = StorageFileType.Image
            });
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            if (exe != null)
                _snackbar.Add(exe.Message, Severity.Error);
            _snackbar.Add(ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {
            IsProcessing = false;
        }
    }
}