using System;
using Bit.Core.Resources.Localization;
using Bit.Core;
using Bit.iOS.Core.Controllers;
using Bit.iOS.Core.Utilities;
using UIKit;

namespace Bit.iOS.Core.Views
{
    public class FormEntryTableViewCell : ExtendedUITableViewCell, ISelectable
    {
        public UILabel Label { get; set; }
        public UITextField TextField { get; set; }
        public UITextView TextView { get; set; }
        public UIButton Button { get; set; }
        public UIButton SecondButton { get; set; }
        public event EventHandler ValueChanged;

        public FormEntryTableViewCell(
            string labelName = null,
            bool useTextView = false,
            nfloat? height = null,
            ButtonsConfig buttonsConfig = ButtonsConfig.None,
            bool useLabelAsPlaceholder = false,
            float leadingConstant = 15f)
            : base(UITableViewCellStyle.Default, nameof(FormEntryTableViewCell))
        {
            var descriptor = UIFontDescriptor.PreferredBody;
            var pointSize = descriptor.PointSize;

            if (labelName != null && !useLabelAsPlaceholder)
            {
                Label = new UILabel
                {
                    Text = labelName,
                    TranslatesAutoresizingMaskIntoConstraints = false,
                    Font = UIFont.FromDescriptor(descriptor, 0.8f * pointSize),
                    TextColor = ThemeHelpers.MutedColor
                };

                ContentView.Add(Label);
            }

            if (useTextView)
            {
                TextView = new UITextView
                {
                    TranslatesAutoresizingMaskIntoConstraints = false,
                    Font = UIFont.FromDescriptor(descriptor, pointSize),
                    TextColor = ThemeHelpers.TextColor,
                    TintColor = ThemeHelpers.TextColor,
                    BackgroundColor = ThemeHelpers.BackgroundColor
                };

                if (!ThemeHelpers.LightTheme)
                {
                    TextView.KeyboardAppearance = UIKeyboardAppearance.Dark;
                }

                ContentView.Add(TextView);
                ContentView.AddConstraints(new NSLayoutConstraint[] {
                    NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, leadingConstant),
                    NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, TextView, NSLayoutAttribute.Trailing, 1f, 15f),
                    NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextView, NSLayoutAttribute.Bottom, 1f, 10f)
                });

                if (labelName != null && !useLabelAsPlaceholder)
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
                }
                else
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f));
                }

                if (height.HasValue)
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, height.Value));
                }

                TextView.Changed += (object sender, EventArgs e) =>
                {
                    ValueChanged?.Invoke(sender, e);
                };
            }
            else
            {
                TextField = new UITextField
                {
                    TranslatesAutoresizingMaskIntoConstraints = false,
                    BorderStyle = UITextBorderStyle.None,
                    Font = UIFont.FromDescriptor(descriptor, pointSize),
                    ClearButtonMode = UITextFieldViewMode.WhileEditing,
                    TextColor = ThemeHelpers.TextColor,
                    TintColor = ThemeHelpers.TextColor,
                    BackgroundColor = ThemeHelpers.BackgroundColor
                };

                if (!ThemeHelpers.LightTheme)
                {
                    TextField.KeyboardAppearance = UIKeyboardAppearance.Dark;
                }

                if (useLabelAsPlaceholder)
                {
                    TextField.Placeholder = labelName;
                }

                ContentView.Add(TextField);

                ContentView.AddConstraints(new NSLayoutConstraint[] {
                    NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, leadingConstant),
                    NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Trailing, 1f, GetTextFieldToContainerTrailingConstant(buttonsConfig)),
                    NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Bottom, 1f, 10f)
                });

                if (labelName != null && !useLabelAsPlaceholder)
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
                }
                else
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f));
                }

                if (height.HasValue)
                {
                    ContentView.AddConstraint(
                        NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, height.Value));
                }

                TextField.AddTarget((object sender, EventArgs e) =>
                {
                    ValueChanged?.Invoke(sender, e);
                }, UIControlEvent.EditingChanged);
            }

            if (labelName != null && !useLabelAsPlaceholder)
            {
                ContentView.AddConstraints(new NSLayoutConstraint[] {
                    NSLayoutConstraint.Create(Label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, leadingConstant),
                    NSLayoutConstraint.Create(Label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f),
                    NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Trailing, 1f, 15f)
                });
            }

            if(buttonsConfig != ButtonsConfig.None)
            {
                AddButtons(buttonsConfig);
            }
        }

        public void Select()
        {
            if (TextView != null)
            {
                TextView.BecomeFirstResponder();
            }
            else if (TextField != null)
            {
                TextField.BecomeFirstResponder();
            }
        }

        public void ConfigureToggleSecureTextCell(bool useSecondaryButton = false)
        {
            var button = useSecondaryButton ? SecondButton : Button;
            button.TitleLabel.Font = UIFont.FromName("bwi-font", 28f);
            button.SetTitle(BitwardenIcons.Eye, UIControlState.Normal);
            button.AccessibilityLabel = AppResources.ToggleVisibility;
            button.AccessibilityHint = AppResources.PasswordIsNotVisibleTapToShow;
            button.TouchUpInside += (sender, e) =>
            {
                TextField.SecureTextEntry = !TextField.SecureTextEntry;
                button.SetTitle(TextField.SecureTextEntry ? BitwardenIcons.Eye : BitwardenIcons.EyeSlash, UIControlState.Normal);
                button.AccessibilityHint = TextField.SecureTextEntry ? AppResources.PasswordIsNotVisibleTapToShow : AppResources.PasswordIsVisibleTapToHide;
            };
        }

        private void AddButtons(ButtonsConfig buttonsConfig)
        {
            Button = new UIButton(UIButtonType.System);
            Button.TranslatesAutoresizingMaskIntoConstraints = false;
            Button.SetTitleColor(ThemeHelpers.PrimaryColor, UIControlState.Normal);

            ContentView.Add(Button);

            ContentView.BottomAnchor.ConstraintEqualTo(Button.BottomAnchor, 10f).Active = true;

            switch (buttonsConfig)
            {
                case ButtonsConfig.One:
                    ContentView.AddConstraints(new NSLayoutConstraint[] {
                        NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, Button, NSLayoutAttribute.Trailing, 1f, 10f),
                        NSLayoutConstraint.Create(Button, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Trailing, 1f, 10f)
                    });
                    break;
                case ButtonsConfig.Two:
                    SecondButton = new UIButton(UIButtonType.System);
                    SecondButton.TranslatesAutoresizingMaskIntoConstraints = false;
                    SecondButton.SetTitleColor(ThemeHelpers.PrimaryColor, UIControlState.Normal);

                    ContentView.Add(SecondButton);

                    ContentView.AddConstraints(new NSLayoutConstraint[] {
                        NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, SecondButton, NSLayoutAttribute.Bottom, 1f, 10f),
                        NSLayoutConstraint.Create(SecondButton, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Trailing, 1f, 9f),
                        NSLayoutConstraint.Create(Button, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, SecondButton, NSLayoutAttribute.Trailing, 1f, 10f),
                        NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, Button, NSLayoutAttribute.Trailing, 1f, 10f)
                    });
                    break;
            }
        }

        private float GetTextFieldToContainerTrailingConstant(ButtonsConfig buttonsConfig)
        {
            switch (buttonsConfig)
            {
                case ButtonsConfig.None:
                    return 15f;
                case ButtonsConfig.One:
                    return 55f;
                case ButtonsConfig.Two:
                    return 95f;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        public enum ButtonsConfig : byte
        {
            None = 0,
            One = 1,
            Two = 2
        }
    }
}
