using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Elwig.Controls;
using Elwig.Helpers;
using Elwig.Helpers.Billing;
using Elwig.Models.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using ScottPlot;
using ScottPlot.Plottable;
using Xceed.Wpf.Toolkit.Primitives;

namespace Elwig.Windows {
    public partial class ChartWindow : ContextWindow {

        public static readonly Color ColorUngebunden = Color.Blue;
        public static readonly Color ColorGebunden = Color.Gold;

        public readonly int Year;
        public readonly int AvNr;
        public Season Season;
        private PaymentVar PaymentVar;

        private ScatterPlot DataPlot;
        private ScatterPlot? GebundenPlot;
        private MarkerPlot HighlightedPointPlot;
        private MarkerPlot PrimaryMarkedPointPlot;
        private MarkerPlot SecondaryMarkedPointPlot;
        private Tooltip TooltipPlot;

        private (Graph? graph, int index) LastHighlighted = (null, -1);
        private (Graph? graph, int index) Highlighted = (null, -1);
        private Graph? ActiveGraph = null;
        private int PrimaryMarkedPoint = -1;
        private int SecondaryMarkedPoint = -1;
        private bool HoverChanged = false;
        private bool HoverActive = false;
        private bool FillingInputs = false;

        private List<GraphEntry> GraphEntries = [];
        private GraphEntry? SelectedGraphEntry;

        public ChartWindow(int year, int avnr) {
            InitializeComponent();
            Year = year;
            AvNr = avnr;
            Season = Context.Seasons.Find(year) ?? throw new ArgumentException("Season not found");
            PaymentVar = Context.PaymentVariants.Find(year, avnr) ?? throw new ArgumentException("PaymentVar not found");
            Title = $"{PaymentVar?.Name} - Lese {year} - Elwig";
        }

        private void Window_Loaded(object sender, RoutedEventArgs evt) {
            OechslePricePlot.IsEnabled = false;
        }

        private async Task RefreshGraphList() {
            PaymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
            Season = await Context.Seasons.FindAsync(Year) ?? throw new ArgumentException("Season not found");

            var attrVariants = (await Context.DeliveryParts
                .Where(d => d.Year == Year)
                .Select(d => $"{d.SortId}{d.AttrId}")
                .Distinct()
                .ToListAsync())
                .Union(Context.WineVarieties.Select(v => v.SortId))
                .Order()
                .ToList();
            var data = EditBillingData.FromJson(PaymentVar.Data, attrVariants);
            GraphEntries = [ ..data.GetPaymentGraphEntries(Context, Season), ..data.GetQualityGraphEntries(Context, Season)];

            var contracts = ContractSelection.GetContractsForYear(Context, Year);
            FillingInputs = true;
            ControlUtils.RenewItemsSource(ContractInput, contracts, g => (g as ContractSelection)?.Listing);
            FillingInputs = false;
            ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id, GraphList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
            SelectedGraphEntry = GraphList.SelectedItem as GraphEntry;

            RefreshInputs();
        }

        private void RefreshInputs() {
            ResetPlot();
            if (SelectedGraphEntry != null) {
                CopyButton.IsEnabled = true;
                DeleteButton.IsEnabled = true;
                //EnableUnitTextBox(OechsleInput);
                GebundenTypeFixed.IsEnabled = true;
                GebundenTypeGraph.IsEnabled = true;
                GebundenTypeNone.IsEnabled = true;
                ContractInput.IsEnabled = true;
                AbgewertetInput.IsEnabled = true;
                EnableOptionButtons();
                FillInputs();
            } else {
                CopyButton.IsEnabled = false;
                DeleteButton.IsEnabled = false;
                DisableUnitTextBox(OechsleInput);
                DisableOptionButtons();
            }
            if (!PaymentVar.TestVariant) {
                AddButton.IsEnabled = false;
                CopyButton.IsEnabled = false;
                DeleteButton.IsEnabled = false;
                DisableUnitTextBox(OechsleInput);
                DisableUnitTextBox(PriceInput);
                GebundenTypeFixed.IsEnabled = false;
                GebundenTypeGraph.IsEnabled = false;
                GebundenTypeNone.IsEnabled = false;
                ContractInput.IsEnabled = false;
                AbgewertetInput.IsEnabled = false;
            }
            GC.Collect();
        }

        private void FillInputs() {
            FillingInputs = true;

            if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
                GebundenTypeFixed.IsChecked = true;
                GebundenFlatBonus.Text = $"{bonus}";
            } else if (SelectedGraphEntry?.GebundenGraph != null) {
                GebundenTypeGraph.IsChecked = true;
                GebundenFlatBonus.Text = "";
            } else {
                GebundenTypeNone.IsChecked = true;
                GebundenFlatBonus.Text = "";
            }

            ControlUtils.SelectCheckComboBoxItems(ContractInput, SelectedGraphEntry?.Contracts ?? [], i => (i as ContractSelection)?.Listing);

            InitPlot();
            OechslePricePlot.IsEnabled = true;
            FillingInputs = false;
        }

        protected override async Task OnRenewContext() {
            await RefreshGraphList();
        }

        private void InitPlot() {
            if (SelectedGraphEntry?.GebundenGraph != null) {
                GebundenPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.GebundenGraph.DataX, SelectedGraphEntry.GebundenGraph.DataY, label: "Gebunden");
                GebundenPlot.LineColor = ColorGebunden;
                GebundenPlot.MarkerColor = ColorGebunden;
                GebundenPlot.MarkerSize = 9;
            }

            DataPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry!.DataGraph.DataX, SelectedGraphEntry!.DataGraph.DataY, label: "Ungebunden");
            DataPlot.LineColor = ColorUngebunden;
            DataPlot.MarkerColor = ColorUngebunden;
            DataPlot.MarkerSize = 9;

            if (SelectedGraphEntry?.GebundenGraph == null) {
                ChangeActiveGraph(SelectedGraphEntry?.DataGraph);
            }

            OechslePricePlot.RightClicked -= OechslePricePlot.DefaultRightClickEvent;
            OechslePricePlot.Configuration.DoubleClickBenchmark = false;
            //OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
            OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
            OechslePricePlot.Plot.SetAxisLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 2);
            
            OechslePricePlot.Plot.Layout(padding: 0);
            OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
            OechslePricePlot.Plot.YAxis.Layout(padding: 0);
            OechslePricePlot.Plot.YAxis2.Layout(padding: 0);

            HighlightedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
            HighlightedPointPlot.Color = Color.Red;
            HighlightedPointPlot.MarkerSize = 10;
            HighlightedPointPlot.MarkerShape = MarkerShape.openCircle;
            HighlightedPointPlot.IsVisible = false;

            PrimaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
            PrimaryMarkedPointPlot.Color = Color.Red;
            PrimaryMarkedPointPlot.MarkerSize = 6;
            PrimaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
            PrimaryMarkedPointPlot.IsVisible = false;

            SecondaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
            SecondaryMarkedPointPlot.Color = Color.Red;
            SecondaryMarkedPointPlot.MarkerSize = 6;
            SecondaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
            SecondaryMarkedPointPlot.IsVisible = false;

            OechslePricePlot.Refresh();

            RefreshFreeZoom();
            RefreshGradationLines();
        }

        private void ResetPlot() {
            PrimaryMarkedPoint = -1;
            SecondaryMarkedPoint = -1;
            ChangeActiveGraph(null);
            HideGradationLines();
            OechslePricePlot.Plot.Remove(DataPlot);
            OechslePricePlot.Plot.Remove(GebundenPlot);
            OechslePricePlot.Plot.Clear();
            OechslePricePlot.Reset();
            OechslePricePlot.Refresh();
        }

        private void ChangeMarker(MarkerPlot point, bool visible, double x = 0, double y = 0) {
            point.X = x;
            point.Y = y;
            point.IsVisible = visible;
        }

        private void LinearIncreaseGraph(int begin, int end, double inc) {

        }

        private void EnableActionButtons() {
            if (PaymentVar.TestVariant) {
                LeftFlatButton.IsEnabled = true;
                RightFlatButton.IsEnabled = true;
                LinearIncreaseButton.IsEnabled = true;
            }
        }

        private void DisableActionButtons() {
            LeftFlatButton.IsEnabled = false;
            RightFlatButton.IsEnabled = false;
            InterpolateButton.IsEnabled = false;
            LinearIncreaseButton.IsEnabled = false;
        }

        private void FreeZoomInput_Changed(object sender, RoutedEventArgs evt) {
            RefreshFreeZoom();
        }

        private void RefreshFreeZoom() {
            if (FreeZoomInput.IsChecked == true) {
                UnlockZoom();
            } else {
                LockZoom();
            }
            OechslePricePlot.Refresh();
        }

        private void LockZoom() {
            OechslePricePlot.Plot.XAxis.SetBoundary(GraphEntry.MinX - 1, GraphEntry.MaxX + 1);
            OechslePricePlot.Plot.YAxis.SetBoundary(-0.1, 2);
            OechslePricePlot.Plot.XAxis.SetZoomOutLimit(GraphEntry.MaxX - GraphEntry.MinX + 2);
            OechslePricePlot.Plot.YAxis.SetZoomOutLimit(2.1);
            OechslePricePlot.Plot.SetAxisLimits(GraphEntry.MinX - 1, GraphEntry.MaxX + 1, -0.1, 2);
        }

        private void UnlockZoom() {
            OechslePricePlot.Plot.XAxis.SetBoundary();
            OechslePricePlot.Plot.YAxis.SetBoundary();
            OechslePricePlot.Plot.XAxis.SetZoomOutLimit((GraphEntry.MaxX - GraphEntry.MinX) * 1.5);
            OechslePricePlot.Plot.YAxis.SetZoomOutLimit(3.5);
        }

        private void EnableOptionButtons() {
            FreeZoomInput.IsEnabled = true;
            GradationLinesInput.IsEnabled = true;
            TooltipInput.IsEnabled = true;
        }

        private void DisableOptionButtons() {
            FreeZoomInput.IsEnabled = false;
            GradationLinesInput.IsEnabled = false;
            TooltipInput.IsEnabled = false;
        }

        private void GradationLinesInput_Changed(object sender, RoutedEventArgs evt) {
            RefreshGradationLines();
        }

        private void RefreshGradationLines() {
            if (GradationLinesInput.IsChecked == true && SelectedGraphEntry != null && !OechslePricePlot.Plot.GetPlottables().OfType<VLine>().Any()) {
                ShowGradationLines();
                ShowLegend();
            } else if (GradationLinesInput.IsChecked == false) {
                HideGradationLines();
                HideLegend();
            }
            OechslePricePlot.Refresh();
        }

        private void ShowGradationLines() {
            OechslePricePlot.Plot.AddVerticalLine(68, Color.Red,    2, label: "68 °Oe (LDW)");
            OechslePricePlot.Plot.AddVerticalLine(73, Color.Orange, 2, label: "73 °Oe (QUW)");
            OechslePricePlot.Plot.AddVerticalLine(84, Color.Green,  2, label: "84 °Oe (KAB)");
        }

        private void HideGradationLines() {
            OechslePricePlot.Plot.Clear(typeof(VLine));
        }

        private void ShowLegend() {
            OechslePricePlot.Plot.Legend(true, Alignment.UpperLeft);
        }

        private void HideLegend() {
            OechslePricePlot.Plot.Legend(false, Alignment.UpperLeft);
        }

        private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) {
            if (ActiveGraph == null || SelectedGraphEntry == null) {
                return;
            }

            bool success = int.TryParse(OechsleInput.Text, out int oechsle);

            SecondaryMarkedPoint = -1;
            ChangeMarker(SecondaryMarkedPointPlot, false);

            if (success) { 
                if (oechsle >= ActiveGraph.MinX && oechsle <= ActiveGraph.MaxX) {
                    PrimaryMarkedPoint = oechsle - ActiveGraph.MinX;
                    ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));

                    PriceInput.Text = ActiveGraph.GetPriceAt(PrimaryMarkedPoint).ToString();

                    EnableActionButtons();
                    OechslePricePlot.Render();
                    EnableUnitTextBox(PriceInput);
                    return;
                }
            }

            PrimaryMarkedPoint = -1;
            //ChangeActiveGraph(null);
            ChangeMarker(PrimaryMarkedPointPlot, false);
            DisableActionButtons();
            PriceInput.Text = "";
            DisableUnitTextBox(PriceInput);
            OechslePricePlot.Render();
            DisableUnitTextBox(PriceInput);
        }

        private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) {
            if (PrimaryMarkedPoint != -1 && ActiveGraph != null) {
                if (double.TryParse(PriceInput.Text, out double price)) {
                    ActiveGraph.SetPriceAt(PrimaryMarkedPoint, price);
                    PrimaryMarkedPointPlot.Y = price;
                    OechslePricePlot.Refresh();
                    CheckGebundenTypeFixed();
                }
            }
        }

        private void LeftFlatButton_Click(object sender, RoutedEventArgs evt) {
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
                return;
            }
            ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
            OechslePricePlot.Render();
            CheckGebundenTypeFixed();
        }

        private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
                return;
            }
            ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
            OechslePricePlot.Render();
            CheckGebundenTypeFixed();
        }

        private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
            if (PrimaryMarkedPoint == SecondaryMarkedPoint || PrimaryMarkedPoint == -1 || SecondaryMarkedPoint == -1 || ActiveGraph == null) {
                return;
            }
            ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
            OechslePricePlot.Render();
            CheckGebundenTypeFixed();
        }

        private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) { 
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
                return;
            }
            double? priceIncrease = Utils.ShowLinearPriceIncreaseDialog();
            if (priceIncrease == null) {
                return;
            }
            ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
            OechslePricePlot.Render();
            CheckGebundenTypeFixed();
        }

        private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
            if (GraphList.SelectedItem == null) {
                return;
            }

            if (HoverActive) {
                if (PaymentVar.TestVariant && Keyboard.IsKeyDown(Key.LeftCtrl)) {
                    if (PrimaryMarkedPoint == -1 || ActiveGraph == null || ActiveGraph != Highlighted.graph) {
                        return;
                    }
                    SecondaryMarkedPoint = Highlighted.index;

                    ChangeMarker(SecondaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(SecondaryMarkedPoint), ActiveGraph.GetPriceAt(SecondaryMarkedPoint));

                    InterpolateButton.IsEnabled = true;

                    return;
                }

                PrimaryMarkedPoint = Highlighted.index;
                ChangeActiveGraph(Highlighted.graph);

                ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));

                OechsleInput.Text = Highlighted.graph.GetOechsleAt(Highlighted.index).ToString();
                PriceInput.Text = Highlighted.graph.GetPriceAt(Highlighted.index).ToString();

                EnableActionButtons();
            } else {
                PrimaryMarkedPoint = -1;
                SecondaryMarkedPoint = -1;
                if (SelectedGraphEntry!.GebundenGraph != null) {
                    ChangeActiveGraph(null);
                }
                ChangeMarker(PrimaryMarkedPointPlot, false);
                ChangeMarker(SecondaryMarkedPointPlot, false);

                OechsleInput.Text = "";
                PriceInput.Text = "";
                DisableUnitTextBox(PriceInput);

                DisableActionButtons();
            }
        }

        private (double, double, int)? MouseOnPlot(ScatterPlot? plot) {
            if (plot == null) {
                return null;
            }

            (double mouseCoordX, double mouseCoordY) = OechslePricePlot.GetMouseCoordinates();
            (double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
            double xyRatio = OechslePricePlot.Plot.XAxis.Dims.PxPerUnit / OechslePricePlot.Plot.YAxis.Dims.PxPerUnit;

            (double pointX, double pointY, int pointIndex) = plot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
            (double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);

            if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
                return (pointX, pointY, pointIndex);
            } else {
                return null;
            }
        }

        private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
            if (GraphList.SelectedItem == null) {
                return;
            }

            (double x, double y, int index)? mouseOnData = MouseOnPlot(DataPlot);
            (double x, double y , int index)? mouseOnGebunden = MouseOnPlot(GebundenPlot);

            Highlighted = LastHighlighted;

            if (mouseOnData != null) {
                ChangeMarker(HighlightedPointPlot, true, mouseOnData.Value.x, mouseOnData.Value.y);
                HighlightedPointPlot.IsVisible = true;
                HoverChanged = true ^ HoverActive;
                HoverActive = true;
                HandleTooltip(mouseOnData.Value.x, mouseOnData.Value.y, mouseOnData.Value.index, SelectedGraphEntry!.DataGraph);
            } else if (mouseOnGebunden != null) {
                ChangeMarker(HighlightedPointPlot, true, mouseOnGebunden.Value.x, mouseOnGebunden.Value.y);
                HighlightedPointPlot.IsVisible = true;
                HoverChanged = true ^ HoverActive;
                HoverActive = true;
                HandleTooltip(mouseOnGebunden.Value.x, mouseOnGebunden.Value.y, mouseOnGebunden.Value.index, SelectedGraphEntry!.GebundenGraph!);
            } else {
                ChangeMarker(HighlightedPointPlot, false);
                HoverChanged = false ^ HoverActive;
                HoverActive = false;
                OechslePricePlot.Plot.Remove(TooltipPlot);
                OechslePricePlot.Render();
            }
        }

        private void HandleTooltip(double pointX, double pointY, int pointIndex, Graph g) {
            if (LastHighlighted != Highlighted || HoverChanged) {
                OechslePricePlot.Plot.Remove(TooltipPlot);
                if (TooltipInput.IsChecked == true) {
                    TooltipPlot = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, Season.Precision)}€/kg)", pointX, pointY);
                }
                LastHighlighted = (g, pointIndex);
                HoverChanged = false;
                OechslePricePlot.Render();
            }
        }

        private int GetMaxGraphId() {
            return GraphEntries.Count == 0 ? 0 : GraphEntries.Select(g => g.Id).Max();
        }

        private void AddButton_Click(object sender, RoutedEventArgs e) {
            GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, Season.Precision, BillingData.CurveMode.Oe);
            GraphEntries.Add(newGraphEntry);
            GraphList.Items.Refresh();
            GraphList.SelectedItem = newGraphEntry;
        }

        private void CopyButton_Click(object sender, RoutedEventArgs e) {
            if (SelectedGraphEntry == null) return;

            GraphEntry newGraphEntry = SelectedGraphEntry.Copy(GetMaxGraphId() + 1);
            GraphEntries.Add(newGraphEntry);
            GraphList.Items.Refresh();
            GraphList.SelectedItem = newGraphEntry;
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e) {
            if (SelectedGraphEntry == null) return;

            var r = MessageBox.Show(
                $"Soll der Graph {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.Contracts}) wirklich gelöscht werden?",
                "Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);

            if (r == MessageBoxResult.Yes) {
                GraphEntries.Remove(SelectedGraphEntry);
                GraphList.Items.Refresh();
            }
        }

        private async void SaveButton_Click(object sender, RoutedEventArgs e) {
            var origData = BillingData.FromJson(PaymentVar.Data);
            var data = origData.FromGraphEntries(GraphEntries);

            EntityEntry<PaymentVar>? tr = null;
            try {
                PaymentVar.Data = data.ToJsonString();
                tr = Context.Update(PaymentVar);
                await Context.SaveChangesAsync();
                LockContext = false;
                await App.HintContextChange();
            } catch (Exception exc) {
                if (tr != null) await tr.ReloadAsync();
                var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message;
                if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
                MessageBox.Show(str, "Auszahlungsvariante speichern", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            LockContext = true;
        }

        private void EnableUnitTextBox(UnitTextBox u) {
            if (PaymentVar.TestVariant) {
                u.IsEnabled = true;
                u.TextBox.IsReadOnly = false;
            }
        }

        private void DisableUnitTextBox(UnitTextBox u) {
            u.IsEnabled = false;
            u.TextBox.IsReadOnly = true;
        }

        private void ChangeActiveGraph(Graph? g) {
            if (g != null && g == SelectedGraphEntry?.DataGraph) {
                EnableUnitTextBox(OechsleInput);
                ChangeLineWidth(DataPlot, 4);
                ChangeLineWidth(GebundenPlot, 1);
            } else if (g != null && g == SelectedGraphEntry?.GebundenGraph) {
                EnableUnitTextBox(OechsleInput);
                ChangeLineWidth(GebundenPlot, 4);
                ChangeLineWidth(DataPlot, 1);
            } else {
                DisableUnitTextBox(OechsleInput);
                DisableUnitTextBox(PriceInput);
                OechsleInput.Text = "";
                PriceInput.Text = "";
                ChangeLineWidth(DataPlot, 1);
                ChangeLineWidth(GebundenPlot, 1);
            }
            ActiveGraph = g;
        }

        private void ChangeLineWidth(ScatterPlot? p, double lineWidth) {
            if (p != null) {
                p.LineWidth = lineWidth;
            }
        }

        private void GraphList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            SelectedGraphEntry = GraphList.SelectedItem as GraphEntry;
            RefreshInputs();
        }

        private void PriceInput_LostFocus(object sender, RoutedEventArgs e) {

        }

        private void OechsleInput_LostFocus(object sender, RoutedEventArgs e) {

        }

        private void GebundenFlatBonus_TextChanged(object sender, TextChangedEventArgs e) {
            if (FillingInputs) return;
            var r = Validator.CheckDecimal(GebundenFlatBonus.TextBox, true, 2, Season.Precision);
            if (r.IsValid && SelectedGraphEntry != null) {
                SelectedGraphEntry.GebundenFlatBonus = double.Parse(GebundenFlatBonus.Text);
                ResetPlot();
                InitPlot();
            }
        }

        private void ContractInput_Changed(object sender, ItemSelectionChangedEventArgs e) {
            if (FillingInputs) return;
            if (e.IsSelected == true) {
                RemoveContractFromOtherGraphEntries(e.Item.ToString());
            }
            var r = ContractInput.SelectedItems.Cast<ContractSelection>();
            SelectedGraphEntry!.Contracts = r.ToList();
            GraphList.Items.Refresh();
        }

        private void RemoveContractFromOtherGraphEntries(string? contract) {
            if (contract == null) return;
            foreach (var ge in GraphEntries) {
                if (ge != SelectedGraphEntry) {
                    ge.Contracts.RemoveAll(c => c.Listing.Equals(contract));
                }
            }
        }

        private void AbgewertetInput_Changed(object sender, RoutedEventArgs e) {
            if (SelectedGraphEntry == null) return;
            SelectedGraphEntry.Abgewertet = AbgewertetInput.IsChecked == true;
        }

        private void GebundenType_Checked(object sender, RoutedEventArgs e) {
            if (FillingInputs) return;
            if (SelectedGraphEntry == null) {
                DisableUnitTextBox(GebundenFlatBonus);
                return;
            }
            if (GebundenTypeNone.IsChecked == true) {
                SelectedGraphEntry.RemoveGebundenGraph();
                DisableUnitTextBox(GebundenFlatBonus);
            } else if (GebundenTypeFixed.IsChecked == true) {
                SelectedGraphEntry.GebundenFlatBonus = double.TryParse(GebundenFlatBonus.Text, out var val) ? val : 0.1;
                SelectedGraphEntry.AddGebundenGraph();
                EnableUnitTextBox(GebundenFlatBonus);
            } else if (GebundenTypeGraph.IsChecked == true) {
                SelectedGraphEntry.AddGebundenGraph();
                DisableUnitTextBox(GebundenFlatBonus);
            }
            RefreshInputs();
        }

        private void CheckGebundenTypeFixed() {
            FillingInputs = true;
            if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
                GebundenTypeFixed.IsChecked = true;
                GebundenFlatBonus.Text = $"{bonus}";
                EnableUnitTextBox(GebundenFlatBonus);
            } else {
                GebundenTypeGraph.IsChecked = true;
                DisableUnitTextBox(GebundenFlatBonus);
            }
            FillingInputs = false;
        }
    }
}