using Billing.Languages;
using Billing.Models;
using Billing.Themes;
using System;
using System.Collections.Generic;
using System.Globalization;
using Xamarin.Forms;

namespace Billing.UI
{
    public class TitleDateConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is DateTime date)
            {
                if (date.Year <= 1900)
                {
                    return null;
                }
                return date.ToString(Resource.TitleDateFormat);
            }
            return value;
        }

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

    public class NegativeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool b)
            {
                return !b;
            }
            return value;
        }

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

    public class MoneyConverter : IValueConverter
    {
        public bool MarkVisible { get; set; }
        public bool Absolute { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is decimal d)
            {
                if (Absolute)
                {
                    d = Math.Abs(d);
                }
                var number = d.ToString("n2");
                if (MarkVisible)
                {
                    return "¥ " + number;
                }
                return number;
            }
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string s)
            {
                if (s.StartsWith("¥ "))
                {
                    s = s[2..];
                }
                if (decimal.TryParse(s, out decimal d))
                {
                    return d;
                }
                return 0m;
            }
            return value;
        }
    }

    public class BalanceColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var resource = Application.Current.Resources;
            if (value is decimal d)
            {
                if (d >= 0)
                {
                    return resource[BaseTheme.GreenColor];
                }
                return resource[BaseTheme.RedColor];
            }
            return resource[BaseTheme.TextColor];
        }

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

    public class TimeConverter : IValueConverter
    {
        public bool IncludeDate { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is DateTime time)
            {
                if (IncludeDate)
                {
                    return time.ToString("MM-dd HH:mm");
                }
                return time.ToString("HH:mm");
            }
            return string.Empty;
        }

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

    public class NotNullConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value != null;
        }

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

    public class AccountCategoryConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is AccountCategory category)
            {
                return category switch
                {
                    AccountCategory.Cash => Resource.Cash,
                    AccountCategory.CreditCard => Resource.CreditCard,
                    AccountCategory.DebitCard => Resource.DebitCard,
                    AccountCategory.ElecAccount => Resource.ElecAccount,
                    _ => category.ToString()
                };
            }
            return value;
        }

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

    public class IconConverter : IValueConverter
    {
        public static readonly Dictionary<string, string> IconPreset = new()
        {
            { "alipay", "\uf642" },
            { "appstore", "\uf370" },
            { "apple-pay", "\uf416" },
            { "btc", "\uf15a" },
            { "buffer", "\uf837" },
            { "jcb", "\uf24b" },
            { "master-card", "\uf1f1" },
            { "visa", "\uf1f0" },
            { "g-pay", "\ue079" },
            { "paypal", "\uf1ed" },
            { "qq", "\uf1d6" },
            { "steam", "\uf1b6" },
            { "uber", "\uf402" },
            { "weixin", "\uf1d7" },
            { "youtube", "\uf167" }
        };

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is ImageSource source)
            {
                return source;
            }
            if (value is string name)
            {
                if (name.StartsWith("#brand#"))
                {
                    var key = name[7..];
                    if (!IconPreset.TryGetValue(key, out var glyph))
                    {
                        if (!int.TryParse(key, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int i))
                        {
                            return ImageSource.FromFile(BaseModel.ICON_DEFAULT);
                        }
                        glyph = char.ConvertFromUtf32(i);
                    }
                    return new FontImageSource
                    {
                        FontFamily = Definition.GetBrandsFontFamily(),
                        Size = 20,
                        Glyph = glyph,
                        Color = Color.Black
                    };
                }
                return ImageSource.FromFile(name);
            }
            return null;
        }

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

    public class SelectBackgroundColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool b && b)
            {
                return Application.Current.Resources[BaseTheme.PromptBackgroundColor];
            }
            return default(Color);
        }

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