using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SPC.Kiosk.Base;
using SPC.Kiosk.Common;
using SPC.Kiosk.PB.Model;
namespace SPC.Kiosk.PB
{
    /// <summary>
    /// DetailBasketItems.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class DetailBasketItems : UserControl
    {
        #region [ Members ]
        /// <summary>
        /// ListItems
        /// </summary>
        public static readonly DependencyProperty ListItemsProperty =
                 DependencyProperty.Register(nameof(ListItems), typeof(ObservableCollection<M_BasketItem>), typeof(DetailBasketItems), new PropertyMetadata(null, new PropertyChangedCallback(OnListItemsPropertyChanged)));
        /// <summary>
        /// Command
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
                 DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(DetailBasketItems), new UIPropertyMetadata(null));
        /// <summary>
        /// Horizontal Scroll Offset
        /// </summary>
        public static readonly DependencyProperty HorizontalOffsetProperty =
                 DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(DetailBasketItems), new PropertyMetadata(0d, new PropertyChangedCallback(OnHorizontalOffsetPropertyChanged)));
        /// <summary>
        /// Display Language
        /// </summary>
        public static readonly DependencyProperty DisplayLanguagePropery =
                 DependencyProperty.Register(nameof(DisplayLanguage), typeof(SupportLanguageType), typeof(DetailBasketItems), new PropertyMetadata(SupportLanguageType.ko, new PropertyChangedCallback(OnDisplayLanguageProperyChanged)));
        /// <summary>
        /// Default PageNo
        /// </summary>
        public static readonly DependencyProperty DefaultPageNoProperty =
                 DependencyProperty.Register(nameof(DefaultPageNo), typeof(int), typeof(DetailBasketItems), new PropertyMetadata(0, new PropertyChangedCallback(OnDefaultPageNoPropertyChanged)));
        /// <summary>
        /// Page Count
        /// </summary>
        public static readonly DependencyProperty PageCountProperty =
                 DependencyProperty.Register(nameof(PageCount), typeof(int), typeof(DetailBasketItems), new PropertyMetadata(0));

        private int TargetPageNo = 0;
        private double mouseDownXposition = -1;
        private bool MoseDown = false;
        /// <summary>
        /// ListItems
        /// </summary>
        public ObservableCollection<M_BasketItem> ListItems
        {
            get { return (ObservableCollection<M_BasketItem>)GetValue(ListItemsProperty); }
            set { SetValue(ListItemsProperty, value); }
        }
        /// <summary>
        /// Command
        /// </summary>
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }
        /// <summary>
        /// HorizontalOffset
        /// </summary>
        public double HorizontalOffset
        {
            get { return (double)GetValue(HorizontalOffsetProperty); }
            set { SetValue(HorizontalOffsetProperty, value); }
        }
        /// <summary>
        /// Display Language
        /// </summary>
        public SupportLanguageType DisplayLanguage
        {
            get { return (SupportLanguageType)GetValue(DisplayLanguagePropery); }
            set { SetValue(DisplayLanguagePropery, value); }
        }
        /// <summary>
        /// DefaultPageNo
        /// </summary>
        public int DefaultPageNo
        {
            get { return (int)GetValue(DefaultPageNoProperty); }
            set { SetValue(DefaultPageNoProperty, value); }
        }
        /// <summary>
        /// Page Count
        /// </summary>
        public int PageCount
        {
            get { return (int)GetValue(PageCountProperty); }
            set { SetValue(PageCountProperty, value); }
        }
        #region [ RoutedEvent 'MouseClicked' ]

        /// <summary>
        /// MouseClicked Event
        /// </summary>
        public static readonly RoutedEvent MouseClickedEvent = EventManager.RegisterRoutedEvent(nameof(MouseClicked), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailBasketItems));
        /// <summary>
        /// MouseClicked Routed Event Handler
        /// </summary>
        public event RoutedEventHandler MouseClicked
        {
            add { AddHandler(MouseClickedEvent, value); }
            remove { RemoveHandler(MouseClickedEvent, value); }
        }
        #endregion RoutedEvent 'MouseClicked'

        #endregion Members

        #region [ Ctor & Etc ]
        /// <summary>
        /// Ctor
        /// </summary>
        public DetailBasketItems()
        {
            InitializeComponent();
            this.Unloaded += DetailBasketItems_Unloaded;
        }

        #endregion Ctor & Etc

        #region [ Methods ]
        /// <summary>
        /// Raise MouseClicked Event
        /// </summary>
        private void RaiseMouseClickedEvent(object _sender)
        {
            //Command Excute 
            if (Command != null && Command.CanExecute(_sender))
            {
                Command.Execute(_sender);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(DetailBasketItems.MouseClickedEvent, _sender);
            RaiseEvent(newEventArgs);
        }
        private void FlipItem(FrameworkElement _target)
        {
            try
            {
                var targetAnimation = new Storyboard();
                var getAnimations = Animations.GetMoveAnimation(_target, OpenCloseAnimationType.GotoDown, _target.ActualHeight *-1, 0, 0.5, 1, 0.5);
                foreach (var aAnimation in getAnimations) targetAnimation.Children.Add(aAnimation);
                targetAnimation.Begin();
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "FlipItem()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        private void ItemsButtonCreate(object _listItems)
        {
            try
            {
                this.GridEventsRemove();
                this.MainStack.Children.Clear();
                if (_listItems is ObservableCollection<M_BasketItem> lstItems && lstItems.Count > 0)
                {
                    foreach (var aItem in lstItems)
                    {
                        var newItemObject = new DetailBasketItem();
                        newItemObject.ItemData = aItem;
                        newItemObject.DisplayLanguage = this.DisplayLanguage;
                        newItemObject.Name = string.Format("ItemStack{0}", aItem.Index);
                        this.ReregisterName(newItemObject.Name, newItemObject);
                        this.MainStack.Children.Add(newItemObject);
                    }
                    this.UpdateLayout();
                    CommonFunction.ReregisterName(this.Parent as FrameworkElement, this.Name, this);

                    this.GridEventsSet();
                    this.DefaultPageNo = 0;
                    this.PageCount = lstItems.Count / 5 + (lstItems.Count % 5 > 0 ? 1 : 0);
                }
                else
                {
                    this.PageCount = 0;
                }

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "ItemsButtonCreate()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// Events Set
        /// </summary>
        public void GridEventsSet()
        {
            try
            {
                MainGrid.PreviewMouseDown += Grid_PreviewMouseDown;
                MainGrid.PreviewMouseUp += MainGrid_PreviewMouseUp;
                foreach (var aItem in this.MainStack.Children)
                {
                    if (aItem is DetailBasketItem ItemContent)
                    {
                        ItemContent.MouseClicked += ItemContent_MouseClicked;
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "GridEventsSet()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }



        /// <summary>
        /// Events Remove
        /// </summary>
        public void GridEventsRemove()
        {
            try
            {
                MainGrid.PreviewMouseDown -= Grid_PreviewMouseDown;
                MainGrid.PreviewMouseMove -= MainGrid_PreviewMouseUp;
                foreach (var aItem in this.MainStack.Children)
                {
                    if (aItem is DetailBasketItem ItemContent)
                    {
                        ItemContent.MouseClicked -= ItemContent_MouseClicked;
                    }
                }
                this.MainStack.Children.Clear();
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "GridEventsRemove()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        public void ChangePageTo(int _toPageNo)
        {
            try
            {
                if (_toPageNo > -1 && _toPageNo < PageCount)
                {
                    var fromOffset = 0d;
                    var toOffset = 0d;
                    var totalTime = 0.3;
                    fromOffset = this.MainScroll.HorizontalOffset;
                    toOffset = this.Width * _toPageNo;
                    var scrollAnimation = Animations.GetScrollAnimation(this, Orientation.Horizontal, fromOffset, toOffset, totalTime);
                    if (scrollAnimation != null)
                    {
                        scrollAnimation.Completed += ScrollAnimation_Completed;
                        scrollAnimation.Begin();
                    }
                    TargetPageNo = _toPageNo;
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "ChangePageTo()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        #endregion Methods

        #region [ Event Handlers ]
        private void ScrollAnimation_Completed(object sender, EventArgs e)
        {
            var targetGrid = this.FindName(string.Format("PageGrid{0}", TargetPageNo));
            if (targetGrid is Grid selectGrid)
            {
                DefaultPageNo = TargetPageNo;
                selectGrid.IsEnabled = true;
            }
        }

        private void DetailBasketItems_Unloaded(object sender, RoutedEventArgs e)
        {
            this.MainStack.Children.Clear();
            this.ListItems = null;
        }
        private static void OnDisplayLanguageProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                if (e.NewValue is SupportLanguageType newValue && !e.NewValue.Equals(e.OldValue))
                {
                    var target = d as DetailBasketItems;
                    foreach (var aItem in target.MainStack.Children)
                    {
                        if (aItem is DetailBasketItem ItemContent)
                        {
                            ItemContent.DisplayLanguage = newValue; 
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(d, "OnDisplayLanguageProperyChanged()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }

        private static void OnHorizontalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                var target = d as DetailBasketItems;
                target.MainScroll.ScrollToHorizontalOffset((double)e.NewValue);
            }
        }
        private static void OnDefaultPageNoPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {

                var target = d as DetailBasketItems;
                target.ChangePageTo((int)e.NewValue);
            }
        }
        private static void OnListItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as DetailBasketItems;
            target.ItemsButtonCreate(e.NewValue);
        }


        private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var requstGrid = sender as Grid;
            mouseDownXposition = e.GetPosition(sender as Grid).X;
            MoseDown = true;
        }
        private void MainGrid_PreviewMouseUp(object sender, MouseEventArgs e)
        {
            if (!MoseDown) return;
            var requstGrid = sender as Grid;
            var curMouseXposition = e.GetPosition(requstGrid).X;
            if (!mouseDownXposition.Equals(-1) && (mouseDownXposition - curMouseXposition) > 50)
            {
                if (this.DefaultPageNo < this.PageCount - 1) this.DefaultPageNo++;
            }
            else if (!mouseDownXposition.Equals(-1) && (mouseDownXposition - curMouseXposition) < -50)
            {
                if (this.DefaultPageNo > 0) this.DefaultPageNo--;
            }
            mouseDownXposition = curMouseXposition;
            MoseDown = false;
        }

        private void ItemContent_MouseClicked(object sender, RoutedEventArgs e)
        {
            RaiseMouseClickedEvent(e.OriginalSource);
        }

        #endregion Event Handlers
    }
}
