using GMCabsDriverAssistant.Models;
using GMCabsDriverAssistant.Services;
using GMCabsDriverAssistant.Utils;
using QRCoder;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GMCabsDriverAssistantSolution.ViewModels
{
    public class CouponsV2ViewModel : BaseViewModel
    {
        #region Fields
        Page page;
        private string emptyViewMessage;
        public ImageSource image;
        public float amount;
        public DateTime expiryDate;
        private CouponDto _selectedCoupon;
        private bool _hasCoupons = false;
        private bool _hasEmptyMessage = false;

        private bool _isNextButton = false;
        private bool _isBackButton = false;
        int couponPosition = 0;
        int couponCount = 0;
        #endregion

        #region Properties
        public string EmptyViewMessage
        {
            get => emptyViewMessage;
            set => SetProperty(ref emptyViewMessage, value);
        }
        public ObservableCollection<CouponDto> Coupons { get; }
        public Command SyncCouponCommand { get; }

        public ImageSource Image
        {
            get => image;
            set => SetProperty(ref image, value);
        }

        public float Amount
        {
            get => amount;
            set => SetProperty(ref amount, value);
        }

        public DateTime ExpiryDate
        {
            get => expiryDate;
            set => SetProperty(ref expiryDate, value);
        }

        public CouponDto SelectedCoupon
        {
            get => _selectedCoupon;
            set => SetProperty(ref _selectedCoupon, value);
        }

        public bool HasCoupons
        {
            get => _hasCoupons;
            set => SetProperty(ref _hasCoupons, value);
        }

        public bool HasEmptyMessage
        {
            get => _hasEmptyMessage;
            set => SetProperty(ref _hasEmptyMessage, value);
        }

        public bool IsNextButton
        {
            get => _isNextButton;
            set => SetProperty(ref _isNextButton, value);
        }

        public bool IsBackButton
        {
            get => _isBackButton;
            set => SetProperty(ref _isBackButton, value);
        }

        public Command NextCouponCommand { get; }
        public Command BackCouponCommand { get; }
        public Command RedemptionDetails { get; }

        #endregion

        #region Constructor
        public CouponsV2ViewModel(Page page)
        {
            this.page = page;
            Title = "Available Coupons";
            SyncCouponCommand = new Command(async () => await GetCoupons());
            BackCouponCommand = new Command(() => SelectCouponOption(true));
            NextCouponCommand = new Command(() => SelectCouponOption(false));
            RedemptionDetails = new Command(() => RedemptionDetailsDialog());
            Coupons = new ObservableCollection<CouponDto>();
            HandleReceivedMessages();
        }


        #endregion

        #region Methods
        public void OnAppearing()
        {
            Task.Run(async () => await GetCoupons());
        }
        private async Task GetCoupons()
        {
            HasCoupons = false;
            IsBackButton = false;
            IsNextButton = false;
            HasEmptyMessage = true;
            EmptyViewMessage = "Loading Coupons...";
            string appToken = Preferences.Get(SecureStorageData.Token, "");
            GMCabsDriverService gMCabsDriverService = new GMCabsDriverService();

            Coupons.Clear();
            List<CouponDto> coupons = await gMCabsDriverService.GetCoupons(appToken);
            if (coupons != null && coupons.Count > 0)
            {
                couponPosition = 0;
                couponCount = coupons.Count;
                HasCoupons = true;
                HasEmptyMessage = false;
                if (couponCount == 1)
                {
                    IsBackButton = false;
                    IsNextButton = false;
                }
                else
                {
                    IsNextButton = true;
                }
                foreach (CouponDto coupon in coupons)
                {
                    QRCodeGenerator qrGenerator = new QRCodeGenerator();
                    QRCodeData qrCodeData = qrGenerator.CreateQrCode(coupon.Id.ToString(), QRCodeGenerator.ECCLevel.Q);
                    BitmapByteQRCode qrCode = new BitmapByteQRCode(qrCodeData);
                    byte[] qrCodeAsBitmapByteArr = qrCode.GetGraphic(20);
                    coupon.Image = ImageSource.FromStream(() => new MemoryStream(qrCodeAsBitmapByteArr));
                    Coupons.Add(coupon);
                }
                Console.WriteLine("Before Position :" + couponPosition);
                Image = Coupons[couponPosition].Image;
            }
            else
            {
                HasCoupons = false;
                HasEmptyMessage = true;
                EmptyViewMessage = "No Coupons available";
            }
        }
        private void SelectCouponOption(bool isback)
        {
            if (isback)
            {
                couponPosition = couponPosition - 1;
                if (couponPosition + 1 == 1 && couponCount > 1)
                {
                    IsBackButton = false;
                    IsNextButton = true;
                }
                else
                {
                    IsNextButton = true;
                }

            }
            else
            {
                couponPosition = couponPosition + 1;
                IsBackButton = true;
                if (couponCount == couponPosition + 1 && couponCount > 1)
                {
                    IsNextButton = false;
                }
            }

            SelectedCoupon = Coupons[couponPosition];
            Image = Coupons[couponPosition].Image;
        }

        [Obsolete]
        void HandleReceivedMessages()
        {
            MessagingCenter.Unsubscribe<App, CouponDto>(this, nameof(App));
            MessagingCenter.Subscribe<App, CouponDto>(this, nameof(App), (sender, couponDto) => {
                Device.BeginInvokeOnMainThread(() => {
                    CouponDto redeemedcoupon = new CouponDto
                    {
                        Id = couponDto.Id,
                        Status = couponDto.Status
                    };
                    List<CouponDto> copyCoupons = new List<CouponDto>(Coupons);
                    Coupons.Clear();
                    foreach (var item in copyCoupons)
                    {
                        if (item.Id == redeemedcoupon.Id)
                        {
                            item.Image = ImageSource.FromFile("scanned.png");
                        }
                        Coupons.Add(item);
                    }
                    Console.WriteLine("After Position :" + couponPosition);
                    SelectedCoupon = Coupons[couponPosition];
                    Image = Coupons[couponPosition].Image;
                });
            });

        }

        private async void RedemptionDetailsDialog()
        {
            int issuedFromLocationID = Coupons[couponPosition].IssuedLocationID;
            string appToken = Preferences.Get(SecureStorageData.Token, "");
            GMCabsDriverService gMCabsDriverService = new GMCabsDriverService();
            LocationVoucherDto locationVoucher = await gMCabsDriverService.GetLocationVoucherByLocationID(appToken, issuedFromLocationID);
            if (locationVoucher != null)
            {
                string voucherOfferText = locationVoucher.VoucherOfferText.Replace("<h1>", "").Replace("</h1>", "");
                await page.DisplayAlert("Redemption Details", voucherOfferText, "Ok");
            }
        }


        #endregion
    }
}
