using FluentValidation;

using FrontOffice.Main.Pages.Profile.Components;
using FrontOffice.Main.Utilities;
using Mapster;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
using System.ComponentModel.DataAnnotations;
using CMSMicroservice.Protobuf.Protos.Package;
using CMSMicroservice.Protobuf.Protos.User;
using CMSMicroservice.Protobuf.Protos.UserAddress;
using CMSMicroservice.Protobuf.Validator.User;
using CMSMicroservice.Protobuf.Validator.UserAddress;
using Severity = MudBlazor.Severity;

namespace FrontOffice.Main.Pages.Profile;

public partial class Index
{
    [Inject] private UserContract.UserContractClient UserContract { get; set; } = default!;
    [Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
    [Inject] private PackageContract.PackageContractClient PackageContract { get; set; } = default!;
    [Inject] private AuthService AuthService { get; set; } = default!;
    [Inject] private BlogPostService BlogPostService { get; set; } = default!;

    private GetUserForCustomerResponse _userProfile = new();
    private BlogPostCardDto? _latestPost;
    private UpdateCustomerProfileRequest _updateUserRequest = new();

    private MudForm? _personalForm;

    private bool _isPersonalSaving;
    private bool _isSettingsSaving;

    private string _copyMessage = string.Empty;

    private DateTime? _date;

    // Referral Link Control
    private bool _hasPurchasedPackage;
    private bool _isClubMemberActive;
    private bool CanShowReferralLink => _hasPurchasedPackage && _isClubMemberActive;

    // Purchase flow
    private bool _isProcessingPayment;
    private int _purchaseCycleCount; // تعداد دورهای خرید — اگر > 0 فقط IPG مجاز

    // Dashboard Tiles
    private readonly List<DashTile> _dashTiles = new()
    {
        new(RouteConstants.Profile.Personal, Icons.Material.Filled.Person, "اطلاعات شخصی", "نمایش و ویرایش", "background:rgba(99,102,241,.12); color:#6366f1;"),
        new(RouteConstants.Profile.Addresses, Icons.Material.Filled.LocationOn, "آدرس‌ها", "مدیریت آدرس‌ها", "background:rgba(99,102,241,.12); color:#6366f1;"),
        new(RouteConstants.Profile.Tree, Icons.Material.Filled.AccountTree, "سازمان فروش", "ساختار تیم", "background:rgba(99,102,241,.12); color:#6366f1;"),
        new(RouteConstants.Gateway.StoreChooser, Icons.Material.Filled.Store, "فروشگاه‌ها", "ورود به فروشگاه", "background:rgba(16,185,129,.12); color:#10b981;"),
        new(RouteConstants.Profile.Wallet, Icons.Material.Filled.AccountBalanceWallet, "کیف پول", "مدیریت و تاریخچه", "background:rgba(16,185,129,.12); color:#10b981;"),
        new(RouteConstants.Profile.MagicWallet, Icons.Material.Filled.AutoAwesome, "کیف‌پول جادویی", "شارژ چند‌برابری", "background:rgba(168,85,247,.12); color:#a855f7;"),
        new(RouteConstants.Profile.WithdrawalRequests, Icons.Material.Filled.RequestPage, "درخواست برداشت", "ثبت و پیگیری", "background:rgba(245,158,11,.12); color:#f59e0b;"),
        new(RouteConstants.Club.Membership, Icons.Material.Filled.CardMembership, "باشگاه مشتریان", "عضویت و مزایا", "background:rgba(168,85,247,.12); color:#a855f7;"),
        new(RouteConstants.Network.Statistics, Icons.Material.Filled.Groups, "آمار باشگاه", "جزئیات باشگاه", "background:rgba(59,130,246,.12); color:#3b82f6;"),
        new(RouteConstants.Commission.Dashboard, Icons.Material.Filled.Payments, "پاداش", "درآمد و تاریخچه", "background:rgba(16,185,129,.12); color:#10b981;"),
    };

    private record DashTile(string Href, string Icon, string Title, string Subtitle, string AvatarStyle);

    // Address management
    private List<CustomerAddressModel> _addresses = new();
    private bool _isLoadingAddresses;
    private CreateNewUserAddressRequest _newAddressRequest = new();
    private UpdateUserAddressRequest _editAddressRequest = new();
    private MudForm? _addressForm;
    private readonly CreateNewUserAddressRequestValidator _addressValidator = new();
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            // Refresh token to get latest user claims
            await AuthService.RefreshTokenAsync();
            
            await LoadUserAuthInfo();
            await LoadUserProfile();
            await LoadAddresses();
            await LoadWallet();
            await LoadLatestPost();
            
            // نمایش Modal قرارداد باشگاه اگر پکیج خریده ولی باشگاه فعال نشده
            await CheckAndShowClubContractModal();
        }
    }

    private async Task LoadUserAuthInfo()
    {
        try
        {
            var userInfo = await AuthService.GetUserAuthInfo();
            _hasPurchasedPackage = userInfo.HasPurchasedPackage;
            _isClubMemberActive = userInfo.IsClubMemberActive;
        }
        catch
        {
            _hasPurchasedPackage = false;
            _isClubMemberActive = false;
        }
        StateHasChanged();
    }
    
    /// <summary>
    /// بررسی و نمایش Modal قرارداد باشگاه مشتریان
    /// اگر کاربر پکیج خریده ولی هنوز قرارداد باشگاه را امضا نکرده
    /// </summary>
    private async Task CheckAndShowClubContractModal()
    {
        // اگر پکیج خریده ولی باشگاه فعال نیست = باید قرارداد امضا کند
        if (_hasPurchasedPackage && !_isClubMemberActive)
        {
            var options = new DialogOptions
            {
                BackdropClick = false,          // غیرقابل بسته شدن با کلیک بیرون
                CloseOnEscapeKey = false,       // غیرقابل بسته شدن با Escape
                CloseButton = false,            // بدون دکمه بستن
                MaxWidth = MaxWidth.Medium,
                FullWidth = true
            };
            
            var dialog = await DialogService.ShowAsync<Shared.ClubMembershipContractDialog>(
                "قرارداد باشگاه مشتریان",
                options);
            
            var result = await dialog.Result;
            
            // اگر موفق بود، صفحه را refresh کنیم
            if (!result.Canceled)
            {
                await LoadUserAuthInfo();
                StateHasChanged();
            }
        }
    }

    private string _walletCredit = "-";
    private string _walletDiscount = "-";
    private string _walletNetwork = "-";
    private async Task LoadWallet()
    {
        var b = await WalletService.GetBalancesAsync();
        _walletCredit = FormatPrice(b.CreditBalance);
        var discount = FormatPrice(b.DiscountBalance);
        _walletNetwork = FormatPrice(b.NetworkBalance);
        _walletDiscount = discount;

        // بارگذاری تعداد دورهای خرید برای کنترل روش‌های پرداخت
        var magicStatus = await WalletService.GetMagicWalletStatusAsync();
        _purchaseCycleCount = magicStatus.PurchaseCycleCount;

        StateHasChanged();
    }

    private static string FormatPrice(long price) => string.Format("{0:N0} تومان", price);

    private async Task LoadLatestPost()
    {
        try
        {
            var posts = await BlogPostService.GetFeaturedPostsAsync(1);
            if (!posts.Any())
            {
                var result = await BlogPostService.GetPublishedPostsAsync(page: 1, pageSize: 1);
                posts = result.Posts;
            }
            _latestPost = posts.FirstOrDefault();
        }
        catch
        {
            _latestPost = null;
        }
        StateHasChanged();
    }

    private async Task LoadUserProfile()
    {
        try
        {
            _userProfile = await UserContract.GetUserForCustomerAsync(new());
            _updateUserRequest = new UpdateCustomerProfileRequest
            {
                FirstName = _userProfile.FirstName,
                LastName = _userProfile.LastName,
                Email = _userProfile.Email,
                NationalCode = _userProfile.NationalCode,
            };
            if (_userProfile.BirthDate != null)
            {
                _date = _userProfile.BirthDate.ToDateTime();
                _updateUserRequest.BirthDate = _userProfile.BirthDate;
            }
        }
        catch (Exception ex)
        {
            // Handle the case when user is not authenticated or API fails
            _userProfile = new GetUserForCustomerResponse();
        }
        StateHasChanged();
    }

    private async Task SavePersonalInfo()
    {
        if (_personalForm is null) return;

        await _personalForm.Validate();
        if (!_personalForm.IsValid) return;

        _isPersonalSaving = true;

        try
        {
            if (!string.IsNullOrWhiteSpace(_updateUserRequest.NationalCode))
                _updateUserRequest.NationalCode = _updateUserRequest.NationalCode.PersianToEnglish();

            if (_date != null)
                _updateUserRequest.BirthDate = _date.Value.DateTimeToTimestamp();

            await UserContract.UpdateCustomerProfileAsync(request: _updateUserRequest);
            await LoadUserProfile();
            Snackbar.Add("اطلاعات شخصی با موفقیت ذخیره شد.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در ذخیره اطلاعات: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isPersonalSaving = false;
            await InvokeAsync(StateHasChanged);
        }
    }


    private async Task SaveSettings()
    {
        _isSettingsSaving = true;

        try
        {
            await SavePersonalInfo();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در ذخیره تنظیمات: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isSettingsSaving = false;
            await InvokeAsync(StateHasChanged);
        }
    }

    private async Task CopyReferralCode()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", $"{Navigation.BaseUri}?ref={_userProfile.ReferralCode}");
            _copyMessage = "کد دعوت کپی شد!";
            Snackbar.Add("کد دعوت در کلیپ‌بورد کپی شد.", Severity.Success);

            // Clear message after 3 seconds
            await Task.Delay(3000);
            _copyMessage = string.Empty;
            await InvokeAsync(StateHasChanged);
        }
        catch (Exception ex)
        {
            Snackbar.Add("خطا در کپی کردن کد دعوت.", Severity.Error);
        }
    }

    private async Task ShareReferralCode()
    {
        var shareText = $"کد دعوت من در کارا بازار سلامت: {_userProfile.ReferralCode}\nبرای عضویت از این لینک استفاده کنید:";

        try
        {
            // Try to use Web Share API if available
            await JSRuntime.InvokeVoidAsync("navigator.share",
                new
                {
                    title = "کد دعوت کارا بازار سلامت",
                    text = shareText,
                    url = $"{Navigation.BaseUri}?ref={_userProfile.ReferralCode}"
                });
        }
        catch
        {
            // Fallback: copy to clipboard
            await JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", $"{Navigation.BaseUri}?ref={_userProfile.ReferralCode}");
            Snackbar.Add("لینک دعوت در کلیپ‌بورد کپی شد.", Severity.Success);
        }
    }

    // Address management methods
    private async Task LoadAddresses()
    {
        _isLoadingAddresses = true;
        try
        {
            var response = await UserAddressContract.GetCustomerAddressesAsync(request: new());
            if (response?.Models?.Any() == true)
            {
                _addresses = response.Models.ToList();
            }
            else
            {
                _addresses = new List<CustomerAddressModel>();
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error);
            _addresses = new List<CustomerAddressModel>();
        }
        finally
        {
            _isLoadingAddresses = false;
            await InvokeAsync(StateHasChanged);
        }
    }

    private async Task OpenAddAddressDialog()
    {
        var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            await LoadAddresses();
            await AuthService.RefreshTokenAsync();
        }
    }

    private async Task OpenEditAddressDialog(CustomerAddressModel address)
    {
        var dialog = await DialogService.ShowAsync<EditAddressDialog>("ویرایش آدرس", new DialogParameters<EditAddressDialog>
        {
            { x => x.Model, address }
        });
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            await LoadAddresses();
        }
    }

    private async Task SetAsDefaultAddress(long addressId)
    {
        try
        {
            await UserAddressContract.SetAddressAsDefaultAsync(request: new()
            {
                Id = addressId
            });
            Snackbar.Add("آدرس پیش‌فرض با موفقیت تغییر کرد.", Severity.Success);
            await LoadAddresses();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در تغییر آدرس پیش‌فرض: {ex.Message}", Severity.Error);
        }
    }

    private async Task DeleteAddress(long addressId)
    {
        var result = await DialogService.ShowMessageBox(
            "تأیید حذف",
            "آیا از حذف این آدرس اطمینان دارید؟",
            yesText: "حذف",
            cancelText: "لغو");

        if (result == true)
        {
            try
            {
                await UserAddressContract.DeleteUserAddressAsync(request: new()
                {
                    Id = addressId
                });
                Snackbar.Add("آدرس با موفقیت حذف شد.", Severity.Success);
                await LoadAddresses();
                await AuthService.RefreshTokenAsync();
            }
            catch (Exception ex)
            {
                Snackbar.Add($"خطا در حذف آدرس: {ex.Message}", Severity.Error);
            }
        }
    }

    private async Task OpenPurchaseOptions()
    {
        var options = new DialogOptions
        {
            MaxWidth = MaxWidth.Small,
            FullWidth = true,
            CloseOnEscapeKey = true,
            BackdropClick = true
        };

        var parameters = new DialogParameters<Shared.PackagePurchaseDialog>
        {
            { x => x.PurchaseCycleCount, _purchaseCycleCount }
        };

        var dialog = await DialogService.ShowAsync<Shared.PackagePurchaseDialog>(
            string.Empty, parameters, options);
        var result = await dialog.Result;

        if (result.Canceled) return;

        if (result.Data is Shared.PackagePurchaseDialog.PackagePurchaseResult purchase)
        {
            switch (purchase.Method)
            {
                case Shared.PackagePurchaseDialog.PaymentMethodType.DirectPayment:
                    await ProcessDirectPayment(purchase.Package.Id);
                    break;
                case Shared.PackagePurchaseDialog.PaymentMethodType.DayaLoan:
                    await ProcessDayaLoanPayment();
                    break;
            }
        }
    }

    private async Task ProcessDirectPayment(long packageId)
    {
        if (_isProcessingPayment) return;

        _isProcessingPayment = true;
        StateHasChanged();

        try
        {
            var response = await PackageContract.CustomerPurchasePackageAsync(new CustomerPurchasePackageRequest
            {
                PackageId = packageId,
                PurchaseMethod = PurchaseMethodEnum.PurchaseMethodGateway
            });

            if (!response.Success)
            {
                Snackbar.Add(response.Message ?? "خطا در آغاز فرآیند پرداخت", Severity.Error);
                return;
            }

            if (!string.IsNullOrEmpty(response.PaymentGatewayUrl))
            {
                Navigation.NavigateTo(response.PaymentGatewayUrl, forceLoad: true);
            }
            else
            {
                Snackbar.Add("خطا در دریافت آدرس درگاه پرداخت", Severity.Error);
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در فرآیند پرداخت: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isProcessingPayment = false;
            await InvokeAsync(StateHasChanged);
        }
    }

    private async Task ProcessDayaLoanPayment()
    {
        if (string.IsNullOrWhiteSpace(_updateUserRequest.FirstName))
        {
            Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (نام وارد نشده)", Severity.Error);
            return;
        }
        if (string.IsNullOrWhiteSpace(_updateUserRequest.LastName))
        {
            Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (نام خانوادگی وارد نشده)", Severity.Error);
            return;
        }
        if (string.IsNullOrWhiteSpace(_updateUserRequest.NationalCode))
        {
            Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (کدملی وارد نشده)", Severity.Error);
            return;
        }
        if (_updateUserRequest.BirthDate == null)
        {
            Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (تاریخ تولد وارد نشده)", Severity.Error);
            return;
        }

        var url = "https://dayadiamond.ir/profile/creditpurchase/?merchantcode=56146364";
        await JSRuntime.InvokeVoidAsync("open", url, "_blank");
    }
}
