using DocuMed.Domain.Entities.City;
using Mapster;

namespace DocuMed.PWA.Pages;

public class ProfilePageViewModel : BaseViewModel
{
    private readonly NavigationManager _navigationManager;
    public IUserUtility UserUtility { get; }
    public IRestWrapper RestWrapper { get; }
    public ISnackbar Snackbar { get; }
    public ApplicationUserSDto User { get; set; } = new();


    public List<CitySDto> Cities { get; private set; } = new List<CitySDto>();
    public List<UniversitySDto> Universities { get; private set; } = new List<UniversitySDto>();
    public List<SectionSDto> Sections { get; private set; } = new List<SectionSDto>();
    public SectionSDto? SelectedSection { get; set; }
    public CitySDto? SelectedCity { get; set; }
    public UniversitySDto? SelectedUni { get; set; }

    public readonly string Version = Assembly.GetAssembly(typeof(Program))?.GetName()?.Version?.ToString() ?? string.Empty;

    public ProfilePageViewModel(IUserUtility userUtility, IRestWrapper restWrapper, ISnackbar snackbar,NavigationManager navigationManager)
    {
        _navigationManager = navigationManager;
        UserUtility = userUtility;
        RestWrapper = restWrapper;
        Snackbar = snackbar;
    }

    public override async Task InitializeAsync()
    {
        User = await UserUtility.GetUserAsync();

        var token = await UserUtility.GetBearerTokenAsync();
        Cities = await RestWrapper.CrudDtoApiRest<City, CitySDto, Guid>(Address.CityController).ReadAll(0, token);
        Universities = await RestWrapper.CrudDtoApiRest<University, UniversitySDto, Guid>(Address.UniversityController).ReadAll(0, token);

        if (User.UniversityId != Guid.Empty)
        {
            SelectedUni = Universities.FirstOrDefault(u => u.Id == User.UniversityId);
            SelectedCity = Cities.FirstOrDefault(c => c.Id == SelectedUni?.CityId);
            if (SelectedUni != null)
                if (User.SectionId != Guid.Empty)
                {
                    Sections = await RestWrapper.SectionRestApi.GetByUniversityAsync(SelectedUni.Id, token);
                    SelectedSection = Sections.FirstOrDefault(s => s.Id == User.SectionId);
                }
        }

        await base.InitializeAsync();
    }

    public async Task SubmitEditAsync()
    {
        try
        {
            IsProcessing = true;
            var token = await UserUtility.GetBearerTokenAsync();
            var request = User.Adapt<UserActionRequestDto>();
            if (SelectedUni != null)
            {
                request.UniversityId = SelectedUni.Id;
                User.UniversityId = SelectedUni.Id;
            }
            if (SelectedSection != null)
            {
                request.SectionId = SelectedSection.Id;
                User.SectionId = SelectedSection.Id;
            }
            await RestWrapper.UserRestApi.UpdateUserAsync(request, token);
            await UserUtility.SetUserAsync(User);
            Snackbar.Add("ویرایش حساب کاربری با موفقیت انجام شد", Severity.Success);
        }
        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 LogoutAsync()
    {
        await UserUtility.LogoutAsync();
        _navigationManager.NavigateTo("");
    }



    public async Task<IEnumerable<CitySDto>> SearchCity(string city)
    {
        try
        {
            if (Cities.Count == 0)
            {
                var token = await UserUtility.GetBearerTokenAsync();
                Cities = await RestWrapper.CrudDtoApiRest<City, CitySDto, Guid>(Address.CityController).ReadAll(0, token);
            }
            if (city.IsNullOrEmpty())
                return Cities;
            return Cities.Where(c => c.Name.Contains(city));
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            Snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            return Cities;
        }
        catch (Exception e)
        {
            Snackbar.Add(e.Message, Severity.Error);
            return Cities;
        }
    }
    public async Task<IEnumerable<SectionSDto>> SearchSection(string section)
    {
        try
        {
            if (SelectedUni != null)
            {
                var token = await UserUtility.GetBearerTokenAsync();
                Sections = await RestWrapper.SectionRestApi.GetByUniversityAsync(SelectedUni.Id, token);
            }
            if (section.IsNullOrEmpty())
                return Sections;
            return Sections.Where(c => c.Name.Contains(section));
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            Snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            return Sections;
        }
        catch (Exception e)
        {
            Snackbar.Add(e.Message, Severity.Error);
            return Sections;
        }
    }
    public async Task<IEnumerable<UniversitySDto>> SearchUniversity(string uni)
    {
        try
        {
            if (Universities.Count == 0)
            {
                var token = await UserUtility.GetBearerTokenAsync();
                Universities = await RestWrapper.CrudDtoApiRest<University, UniversitySDto, Guid>(Address.UniversityController).ReadAll(0, token);
            }
            if (uni.IsNullOrEmpty())
                return Universities;
            return Universities.Where(c => c.Name.Contains(uni));
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            Snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            return Universities;
        }
        catch (Exception e)
        {
            Snackbar.Add(e.Message, Severity.Error);
            return Universities;
        }
    }
}