using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Utils;
using Avalonia.Diagnostics;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.VisualTree;
using NP.Utilities;
using System.Diagnostics;
using System.Linq;
using Mapsui.Projections;
using Mapsui.Extensions;
using Avalonia.Interactivity;
using BruTile.Predefined;
using Mapsui.Tiling.Layers;
using Avalonia.Controls.Primitives;
using System;
using pavesys_iRAP.ViewModels;
using pavesys_iRAP.Helper;
using Mapsui.Tiling.Fetcher;
using Mapsui;
using System.Runtime.InteropServices;
using Mapsui.Nts.Extensions;
using Mapsui.Layers;
using NP.Ava.UniDock;
using System.IO;
namespace pavesys_iRAP.Views;

public partial class CodingTwoScreenPageView : UserControl
{

    MPoint Point { get; set; }
    Map SatteliteMap { get; set; }
    Map RoadMap { get; set; }
    ILayer lineLayer;
    ILayer pointLayer;
    public CodingTwoScreenPageView()
    {
        InitializeComponent();

        //Requisição do Mapa Sattelite
        string bingMapsApiKey = "API_TEST";
        var bingMapsLayer = new TileLayer(KnownTileSources.Create(KnownTileSource.BingHybrid, bingMapsApiKey),
            dataFetchStrategy: new DataFetchStrategy()) // DataFetchStrategy prefetches tiles from higher levels
        {
            Name = "Bing Aerial",
        };

        SatteliteMap = new Map();
        RoadMap = new Map();

        SatteliteMap.Layers.Add(bingMapsLayer);
        RoadMap.Layers.Add(Mapsui.Tiling.OpenStreetMap.CreateTileLayer("pavesys-iRAP"));



        SatteliteMap.Home = n => n.ZoomToLevel(15);
        RoadMap.Home = n => n.ZoomToLevel(15);
        RoadMap.Refresh();
        SatteliteMap.Refresh();
        MapView.Refresh();
        //Inicia o mapview no 2d openstreetmap
        MapView.Map = RoadMap;

    }

    private void X_Closed(object? sender, EventArgs e)
    {
        Environment.Exit(0);
    }

    private void SelectMapStyle(object sender, SelectionChangedEventArgs args)
    {
        var lb = sender as ListBox;
        switch (lb.SelectedIndex)
        {
            case 0:
                MapView.Map = RoadMap;
                MapView.Map.Navigator.CenterOn(Point);
                MapView.Refresh();
                break;

            case 1:
                MapView.Map = SatteliteMap;
                MapView.Map.Navigator.CenterOn(Point);
                MapView.Refresh();
                break;
        }
    }
    private void updateDataContext(object sender, EventArgs e)
    {
        var x = this.DataContext as CodingTwoScreenPageViewModel;

        this.GetVisualDescendants().OfType<ListBox>().ToList().ForEach(list =>
        {
            list.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<TextBox>().ToList().ForEach(list =>
        {
            list.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<ProgressBar>().ToList().ForEach(list =>
        {
            list.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<NumericUpDown>().ToList().ForEach(list =>
        {
            list.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<ToggleSwitch>().ToList().ForEach(toggle =>
        {
            toggle.DataContext = this.DataContext;
            if (toggle.IsChecked == null)
            {
                toggle.Background = Brush.Parse("SlateGray");
            }
        });

        this.GetVisualDescendants().OfType<ComboBox>().ToList().ForEach(combo =>
        {
            combo.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<Button>().ToList().ForEach(button =>
        {
            button.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<DataGrid>().ToList().ForEach(dataGrid =>
        {
            dataGrid.DataContext = this.DataContext;
        });

        this.GetVisualDescendants().OfType<Image>().ToList().ForEach(img =>
        {
            img.DataContext = this.DataContext;
        });
        Test.TheDockManager.AllWindows.DoForEach(window =>
        {
            window.GetVisualDescendants().OfType<ListBox>().ToList().ForEach(list =>
            {
                list.DataContext = this.DataContext;
            });

            window.GetVisualDescendants().OfType<NumericUpDown>().ToList().ForEach(list =>
            {
                list.DataContext = this.DataContext;
            });

            window.GetVisualDescendants().OfType<ToggleSwitch>().ToList().ForEach(toggle =>
            {
                toggle.DataContext = this.DataContext;
                if (toggle.IsChecked == null)
                {
                    toggle.Background = Brush.Parse("SlateGray");
                }
            });

            window.GetVisualDescendants().OfType<ComboBox>().ToList().ForEach(combo =>
            {
                combo.DataContext = this.DataContext;
            });



            window.GetVisualDescendants().OfType<DataGrid>().ToList().ForEach(dataGrid =>
            {
                dataGrid.DataContext = this.DataContext;
            });

            window.GetVisualDescendants().OfType<Image>().ToList().ForEach(img =>
            {
                img.DataContext = this.DataContext;
            });
        });


    }

    private void LatLonChanged(object? sender, Avalonia.Controls.NumericUpDownValueChangedEventArgs e)
    {
        var ctx = this.DataContext as CodingPageViewModel;

        //var Point = SphericalMercator.FromLonLat((double)NumLatitude.Value, (double)NumLongitude.Value).ToMPoint();
        Point = SphericalMercator.FromLonLat((double)NumLongitude.Value, (double)NumLatitude.Value).ToMPoint();

        if (lineLayer is null)
        {
            lineLayer = MapHelper.CreateLineStringLayer(ctx.codingCtx.Select(coding =>
            SphericalMercator.FromLonLat((double)coding.Longitude, (double)coding.Latitude)
            .ToCoordinate())
                .ToArray(),
                MapHelper.CreateLineStringStyle());
            RoadMap.Layers.Add(lineLayer);
            SatteliteMap.Layers.Add(lineLayer);
        }
        if (pointLayer is null)
        {
            pointLayer = MapHelper.CreatePointLayer(Point);
            RoadMap.Layers.Add(pointLayer);
            SatteliteMap.Layers.Add(pointLayer);
        }
        else
        {
            RoadMap.Layers.Remove(pointLayer);
            SatteliteMap.Layers.Remove(pointLayer);
            pointLayer = MapHelper.CreatePointLayer(Point);
            RoadMap.Layers.Add(pointLayer);
            SatteliteMap.Layers.Add(pointLayer);
        }
        RoadMap.Navigator.CenterOn(Point);
        SatteliteMap.Navigator.CenterOn(Point);
        MapView.Refresh();

    }

    private void DataGrid_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
    {
        var vm = this.DataContext as CodingPageViewModel;


        if (e.Source is Avalonia.Controls.Border)
            vm.LoadSegfromGrid();
    }
    private void SegGridFocusOnSelectedItem(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        try
        {
            var segGrid = sender as DataGrid;
            if (segGrid.SelectedItem != null)
            {
                segGrid.ScrollIntoView(segGrid.SelectedItem, segGrid.Columns[2]);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

    private void ToggleSwitch_IsCheckedChanged(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        var toggle = sender as ToggleSwitch;
        toggle.Background = Brush.Parse("White");
    }

    private void ApplyCheck(object sender, RoutedEventArgs args)
    {
        var toggleButton = sender as ToggleButton;

        if (toggleButton.Content != "X" && (toggleButton.IsChecked != null))
        {
            toggleButton.Content = "X";
        }
        else
        {
            toggleButton.Content = "";
        }
    }



    private void SetTextDataContext(object? sender, System.EventArgs e)
    {
        var text = sender as TextBlock;
        text.DataContext = this.DataContext;
    }
    private void SetPBarDataContext(object? sender, System.EventArgs e)
    {
        var PB = sender as ProgressBar;
        PB.DataContext = this.DataContext;
    }

    private void OpenUrl(string url)
    {
        try
        {
            Process.Start(url);
        }
        catch
        {
            // hack because of this: https://github.com/dotnet/corefx/issues/10361
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                url = url.Replace("&", "^&");
                Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Process.Start("xdg-open", url);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                Process.Start("open", url);
            }
            else
            {
                throw;
            }
        }
    }
    public void ClickManual(object sender, RoutedEventArgs args)
    {
        OpenUrl(@"https://irap.org/specifications/");
    }
    private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        //Test.TheDockManager.AllWindows.DoForEach(window => {  Debug.WriteLine(window.ToString()); window.Background = Brushes.AliceBlue; Debug.WriteLine(VisualTreeDebug.PrintVisualTree(this));  });
        //Test.DockChildren.DoForEach(child => { Debug.WriteLine(child.ToString()); });
        //Debug.WriteLine(Test.NumberDockChildren);
        //Test.GetVisualDescendants().ToList().ForEach(d => { Debug.WriteLine(d.ToString()); });
        //Debug.WriteLine(VisualTreeDebug.PrintVisualTree(this));
        this.GetVisualDescendants().OfType<Rectangle>().ToList().ForEach(list =>
        {
        });

    }

    private void ListBox_LayoutUpdated_1(object? sender, System.EventArgs e)
    {
        var x = this.DataContext as CodingTwoScreenPageViewModel;
        var y = TopLevel.GetTopLevel(this);



        Bordenha.Width = y.Width * (7.5 / 8.0) - 10;
        ViewColOne.Width = Bordenha.Width / 3.0 * 0.9;
        ViewColOne.MaxWidth = 400;
        ViewColOne.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left;
        ViewCol2.Width = (Bordenha.Width / 3.0) * 0.9;
        ViewCol2.MaxWidth = 419;
        ViewCol2.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left;
        ViewCol3.Width = Bordenha.Width / 3.0 * 1;
        ViewCol3.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left;
        ViewCol3.MaxWidth = 530;

        //Debug.WriteLine($"Y=WxH:{y.Width}-{y.Height} VM={x.Width}-{x.Height} + viewer{Viewer.Width}");
    }

    private void Button_Click_1(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        Bordenha.Width = 450;
    }

    private void Button_Click_2(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        var _dockManager = (DockManager)this.FindResource("TheDockManager")!;

        

        _dockManager.RestoreFromFile(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                    "Pavesys", "Layout.xml"));

    }

    private void Button_Click_3(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
    {
        var _dockManager = (DockManager)this.FindResource("TheDockManager")!;

        _dockManager.SaveToFile(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                    "Pavesys", "Layout.xml"));
    }
}