using Bit.App.Utilities;
using Foundation;
using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
using System;
using System.Diagnostics;
using UIKit;

namespace Bit.iOS.Core.Views
{
    public class Toast : UIView
    {
        private NSTimer _dismissTimer;
        private NSLayoutConstraint _heightConstraint;
        private NSLayoutConstraint _leftMarginConstraint;
        private NSLayoutConstraint _rightMarginConstraint;
        private NSLayoutConstraint _bottomMarginConstraint;

        public Toast(string text)
            : base(CoreGraphics.CGRect.FromLTRB(0, 0, 320, 38))
        {
            TranslatesAutoresizingMaskIntoConstraints = false;
            var bgColor = UIColor.DarkGray;
            var nordTheme = ThemeManager.Resources() != null &&
                ThemeManager.GetResourceColor("BackgroundColor") == Color.FromHex("#3b4252");
            if (nordTheme)
            {
                bgColor = Color.FromHex("#4c566a").ToUIColor();
            }
            BackgroundColor = bgColor.ColorWithAlpha(0.9f);
            Layer.CornerRadius = 18;
            Layer.MasksToBounds = true;

            MessageLabel = new UILabel
            {
                TranslatesAutoresizingMaskIntoConstraints = false,
                TextColor = UIColor.White,
                Font = UIFont.SystemFontOfSize(14),
                BackgroundColor = UIColor.Clear,
                LineBreakMode = UILineBreakMode.WordWrap,
                TextAlignment = UITextAlignment.Center,
                Lines = 0,
                Text = text
            };

            AddSubview(MessageLabel);

            var hMessageConstraints = NSLayoutConstraint.FromVisualFormat("H:|-5-[messageLabel]-5-|", 0, new NSDictionary(),
                NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel },
                    new NSObject[] { new NSString("messageLabel") })
            );

            var vMessageConstraints = NSLayoutConstraint.FromVisualFormat("V:|-0-[messageLabel]-0-|", 0, new NSDictionary(),
                NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel },
                    new NSObject[] { new NSString("messageLabel") })
            );

            AddConstraints(hMessageConstraints);
            AddConstraints(vMessageConstraints);

            AddGestureRecognizer(new UITapGestureRecognizer(() => Dismiss(false)));
        }

        public bool Dismissed { get; set; }
        public Action DismissCallback { get; set; }
        public TimeSpan Duration { get; set; } = TimeSpan.FromSeconds(3);
        public UILabel MessageLabel { get; set; }
        public nfloat LeftMargin { get; set; } = 5;
        public nfloat RightMargin { get; set; } = 5;
        public nfloat BottomMargin { get; set; } = 5;
        public nfloat Height { get; set; } = 38;

        public void Show()
        {
            if (Superview != null)
            {
                return;
            }

            _dismissTimer = NSTimer.CreateScheduledTimer(Duration, x => Dismiss());
            LayoutIfNeeded();

            var localSuperView = UIApplication.SharedApplication.KeyWindow;
            if (localSuperView != null)
            {
                localSuperView.AddSubview(this);

                _heightConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Height,
                    NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, Height);

                _leftMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Left, NSLayoutRelation.Equal,
                    localSuperView, NSLayoutAttribute.Left, 1, LeftMargin);

                _rightMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Right, NSLayoutRelation.Equal,
                    localSuperView, NSLayoutAttribute.Right, 1, -RightMargin);

                _bottomMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal,
                    localSuperView, NSLayoutAttribute.Bottom, 1, -BottomMargin);

                // Avoid the "UIView-Encapsulated-Layout-Height" constraint conflicts
                // http://stackoverflow.com/questions/25059443/what-is-nslayoutconstraint-uiview-encapsulated-layout-height-and-how-should-i
                _leftMarginConstraint.Priority = 999;
                _rightMarginConstraint.Priority = 999;

                AddConstraint(_heightConstraint);
                localSuperView.AddConstraint(_leftMarginConstraint);
                localSuperView.AddConstraint(_rightMarginConstraint);
                localSuperView.AddConstraint(_bottomMarginConstraint);

                ShowWithAnimation();
            }
            else
            {
                Debug.WriteLine("Toast needs a keyWindows to display.");
            }
        }

        public void Dismiss(bool animated = true)
        {
            if (Dismissed)
            {
                return;
            }

            Dismissed = true;
            _dismissTimer?.Invalidate();
            _dismissTimer = null;

            if (!animated)
            {
                RemoveFromSuperview();
                DismissCallback?.Invoke();
                return;
            }

            SetNeedsLayout();
            Animate(0.3f, 0, UIViewAnimationOptions.CurveEaseIn, () => { Alpha = 0; }, () =>
            {
                RemoveFromSuperview();
                DismissCallback?.Invoke();
            });
        }

        private void ShowWithAnimation()
        {
            Alpha = 0;
            SetNeedsLayout();
            _bottomMarginConstraint.Constant = -BottomMargin;
            _leftMarginConstraint.Constant = LeftMargin;
            _rightMarginConstraint.Constant = -RightMargin;
            AnimateNotify(0.3f, 0, 0.7f, 5f, UIViewAnimationOptions.CurveEaseInOut, () => { Alpha = 1; }, null);
        }
    }
}
