using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Xaml.Behaviors;

namespace InABox.WPF;

public class TextBoxDateMaskBehavior : Behavior<TextBox>
{
    private bool bFirst = true;
    private List<Tuple<int, char>> _separators = new List<Tuple<int, char>>();
    
    private string _format = "";
    public string Format
    {
        get => _format;
        set
        {
            _format = value;
            ReloadSeparators();
        }
    }
    

    private void ReloadSeparators()
    {
        _separators.Clear();
        var formatted = String.Format("{0:"+_format+"}",DateTime.Today );
        int iOffset = 0;
        for (int i=0; i<formatted.Length; i++)
        {
            var ch = formatted[i];
            if (!Char.IsNumber(ch))
            {
                _separators.Add(new Tuple<int, char>(i - iOffset, ch));
                iOffset++;
            }
        }
    }

    public TextBoxDateMaskBehavior(string? format)
    {
        Format = String.IsNullOrWhiteSpace(format) 
            ? "dd/MM/yyyy" 
            : format;
    }
    
    protected override void OnAttached()
    {
        AssociatedObject.PreviewTextInput += PreviewTextInput;
        AssociatedObject.TextChanged += TextChanged;
        AssociatedObject.MouseDoubleClick += MouseDoubleClick;
        //AssociatedObject.GotFocus -= GotFocus;
        //AssociatedObject.PreviewKeyDown -= PreviewKeyDown;
        base.OnAttached();
    }
    
    protected override void OnDetaching()
    {
        AssociatedObject.MouseDoubleClick -= MouseDoubleClick;
        AssociatedObject.TextChanged -= TextChanged;
        AssociatedObject.PreviewTextInput -= PreviewTextInput;
        //AssociatedObject.GotFocus += GotFocus;
        //AssociatedObject.PreviewKeyDown += PreviewKeyDown; 
        base.OnDetaching();
    }
    
    private void MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        AssociatedObject.Text = String.Format("{0:" + Format + "}", DateTime.Now);
    }

    private void PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        bFirst = false;
        if (!int.TryParse(e.Text, out int _))
            e.Handled = true;
    }

    private void TextChanged(object sender, TextChangedEventArgs e)
    {
        var plaintext = AssociatedObject.Text?.Trim() ?? "";
        foreach (var separator in _separators)
            plaintext = plaintext.Replace(separator.Item2.ToString(), "");
        
        var decorated = plaintext;
        for (int i = _separators.Count - 1; i >= 0; i--)
        {
            if (plaintext.Length >= _separators[i].Item1)
                decorated = decorated.Insert(_separators[i].Item1, _separators[i].Item2.ToString());
        }
        AssociatedObject.Text = decorated;
        if (bFirst)
            AssociatedObject.SelectAll();
        else
            AssociatedObject.Select(AssociatedObject.Text.Length, 0);
        e.Handled = true;
    }
}