using Elwig.Helpers;
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace Elwig.Windows {
    public abstract class ContextWindow : Window {

        private bool _lockContext = false;
        protected bool LockContext {
            get => _lockContext;
            set {
                _lockContext = value;
                if (!_lockContext && _renewPending) {
                    Dispatcher.BeginInvoke(async () => await RenewContext());
                }
            }
        }

        private bool _renewPending = false;

        private readonly RoutedCommand CtrlR = new("CtrlR", typeof(ContextWindow), [new KeyGesture(Key.R, ModifierKeys.Control)]);
        private readonly RoutedCommand F5 = new("F5", typeof(ContextWindow), [new KeyGesture(Key.F5)]);

        public ContextWindow() : base() {
            CommandBindings.Add(new CommandBinding(CtrlR, ForceContextReload));
            CommandBindings.Add(new CommandBinding(F5, ForceContextReload));
            Loaded += OnLoaded;
        }

        public async void ForceContextReload(object sender, EventArgs evt) {
            await HintContextChange();
        }

        public async Task HintContextChange() {
            _renewPending = true;
            if (LockContext) return;
            await RenewContext();
        }

        protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
            using var ctx = new AppDbContext();
            await OnRenewContext(ctx);
        }

        protected async Task RenewContext() {
            if (!_renewPending) return;
            using var ctx = new AppDbContext();
            await OnRenewContext(ctx);
            _renewPending = false;
        }

        abstract protected Task OnRenewContext(AppDbContext ctx);
    }
}