using System;
using System.Globalization;
using InABox.Core;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XF.Material.Forms.Resources.Typography;

namespace InABox.Mobile
{
    
    public class MobileButtonClickEventArgs : EventArgs
    {
        public object Tag { get; private set; }

        public MobileButtonClickEventArgs(object tag)
        {
            Tag = tag;
        }
    }
    
    public delegate void MobileButtonClickEvent(object sender, MobileButtonClickEventArgs args);

    public class MobileButtonTextFormatter : IValueConverter
    {
        public object Prefix { get; set; }
        public String Prompt { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (String.IsNullOrWhiteSpace(value as String))
                return $"[{Prompt}]";
            return $"{Prefix} {value}".Trim();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public enum MobileButtonSizeDimension
    {
        Height,
        Width
    }
    
    public class MobileButtonSizeConverter : AbstractConverter<Size,double>
    {
        public MobileButtonSizeDimension Dimension { get; set; }

        protected override double Convert(Size value, object? parameter = null)
        {
            return Dimension == MobileButtonSizeDimension.Height
                ? value.Height
                : value.Width;
        }

    }

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MobileButton
    {

        public event MobileButtonClickEvent Clicked;
        
        public object Prefix
        {
            get => _textformatter.Prefix;
            set => _textformatter.Prefix = value;
        }
        
        public String Prompt
        {
            get => _textformatter.Prompt;
            set => _textformatter.Prompt = value;
        }
        
        public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
            nameof(CornerRadius), 
            typeof(float), 
            typeof(MobileButton),
            5.0f);
        
        public float CornerRadius 
        {
            get => (float)GetValue(CornerRadiusProperty);
            set => SetValue(CornerRadiusProperty, value);
        }
        
        public static readonly BindableProperty TagProperty = BindableProperty.Create(
            nameof(Tag), 
            typeof(object), 
            typeof(MobileButton));
        
        public object Tag 
        {
            get => GetValue(TagProperty);
            set => SetValue(TagProperty, value);
        }

        private static readonly BindableProperty OrientationProperty = BindableProperty.Create(
            nameof(Orientation), 
            typeof(StackOrientation), 
            typeof(MobileButton), 
            StackOrientation.Horizontal);
        
        public StackOrientation Orientation
        {
            get => (StackOrientation)GetValue(OrientationProperty);
            set => SetValue(OrientationProperty, value);
        }
        
        public static readonly BindableProperty ImageProperty = BindableProperty.Create(
            nameof(Image), 
            typeof(ImageSource), 
            typeof(MobileButton)
        );
        
        public ImageSource Image
        {
            get => GetValue(ImageProperty) as ImageSource;
            set => SetValue(ImageProperty, value);
        }        
        public static readonly BindableProperty ImageSizeProperty = BindableProperty.Create(
            nameof(ImageSize), 
            typeof(Size), 
            typeof(MobileButton),
            new Size(24,24)
        );
        
        public Size ImageSize
        {
            get => (Size)GetValue(ImageSizeProperty);
            set => SetValue(ImageSizeProperty, value);
        }
        
        public static readonly BindableProperty TextProperty = BindableProperty.Create(
            nameof(Text), 
            typeof(String),
            typeof(MobileButton)
        );
        
        public String Text
        {
            get => (String)GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        private static readonly BindableProperty AlertProperty = BindableProperty.Create(
            nameof(Alert), 
            typeof(String),
            typeof(MobileButton)
        );
        
        public String Alert
        {
            get => (String)GetValue(AlertProperty);
            set => SetValue(AlertProperty, value);
        }

        private static readonly BindableProperty TextColorProperty = BindableProperty.Create(
            nameof(TextColor),
            typeof(Color),
            typeof(MobileButton),
            XF.Material.Forms.Material.Color.OnSecondary);

        public Color TextColor
        {
            get => (Color)GetValue(TextColorProperty);
            set => SetValue(TextColorProperty, value);
        }

        private static readonly BindableProperty TypeScaleProperty = BindableProperty.Create(
            nameof(TypeScale), 
            typeof(MaterialTypeScale), 
            typeof(MobileButton), 
            MaterialTypeScale.Button);
        
        public MaterialTypeScale TypeScale
        {
            get => (MaterialTypeScale)GetValue(TypeScaleProperty);
            set => SetValue(TypeScaleProperty, value);
        }
        
        public new static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create(
            nameof(BackgroundColor),
            typeof(Color),
            typeof(MobileButton),
            XF.Material.Forms.Material.Color.Secondary);

        public new Color BackgroundColor
        {
            get => (Color)GetValue(BackgroundColorProperty);
            set => SetValue(BackgroundColorProperty, value);
        }

        private static readonly BindableProperty BorderColorProperty = BindableProperty.Create(
            nameof(BorderColor),
            typeof(Color),
            typeof(MobileButton),
            XF.Material.Forms.Material.Color.SecondaryVariant);

        public Color BorderColor
        {
            get => (Color)GetValue(BorderColorProperty);
            set => SetValue(BorderColorProperty, value);
        }
        
        public MobileButton()
        {
            InitializeComponent();
            Alert = "";
            HeightRequest = 40;
        }
        
        private async void _frame_OnClicked(object sender, EventArgs e)
        {
            Clicked?.Invoke(this, new MobileButtonClickEventArgs(Tag));
        }
    }
}