using DbFirst.Domain.Entities;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWeb;
using DevExpress.DataAccess.Json;
using System.Xml.Linq;

namespace DbFirst.API.Dashboards;

public static class DashboardConfiguratorFactory
{
    public static DashboardConfigurator Create(
        IServiceProvider serviceProvider,
        IConfiguration configuration,
        IWebHostEnvironment environment)
    {
        // Den gesamten Inhalt des Lambdas hierher verschieben
        // serviceProvider, configuration, environment statt builder.* verwenden

        var dashboardsPath = Path.Combine(environment.ContentRootPath, "Data", "Dashboards");
        Directory.CreateDirectory(dashboardsPath);

        var defaultDashboardPath = Path.Combine(dashboardsPath, "DefaultDashboard.xml");
        if (!File.Exists(defaultDashboardPath))
        {
            var defaultDashboard = new Dashboard();
            defaultDashboard.Title.Text = "Default Dashboard";
            defaultDashboard.SaveToXml(defaultDashboardPath);
        }

        var dashboardBaseUrl = configuration["Dashboard:BaseUrl"]
            ?? configuration["ApiBaseUrl"]
            ?? configuration["ASPNETCORE_URLS"]?.Split(';', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()
            ?? "https://localhost:7204";

        dashboardBaseUrl = dashboardBaseUrl.TrimEnd('/');

        var catalogsGridDashboardPath = Path.Combine(dashboardsPath, "CatalogsGrid.xml");
        if (!File.Exists(catalogsGridDashboardPath))
        {
            var dashboard = new Dashboard();
            dashboard.Title.Text = "Catalogs (Dashboard Grid)";

            var catalogDataSource = new DashboardJsonDataSource("Catalogs (API)")
            {
                ComponentName = "catalogsDataSource",
                JsonSource = new UriJsonSource(new Uri($"{dashboardBaseUrl}/api/catalogs"))
            };

            dashboard.DataSources.Add(catalogDataSource);

            var grid = new GridDashboardItem
            {
                DataSource = catalogDataSource,
                Name = "Catalogs"
            };

            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.Guid))) { Name = "Id" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.CatTitle))) { Name = "Titel" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.CatString))) { Name = "String" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.AddedWho))) { Name = "Angelegt von" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.AddedWhen))) { Name = "Angelegt am" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.ChangedWho))) { Name = "Geändert von" });
            grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.ChangedWhen))) { Name = "Geändert am" });

            dashboard.Items.Add(grid);

            var layoutGroup = new DashboardLayoutGroup { Orientation = DashboardLayoutGroupOrientation.Vertical };
            layoutGroup.ChildNodes.Add(new DashboardLayoutItem(grid));
            dashboard.LayoutRoot = layoutGroup;

            dashboard.SaveToXml(catalogsGridDashboardPath);
        }

        DashboardConfigurator configurator = new DashboardConfigurator();

        var connectionString = configuration.GetConnectionString("DefaultConnection") ?? string.Empty;
        var notifier = serviceProvider.GetRequiredService<IDashboardChangeNotifier>();
        var dashboardStorage = new SqlDashboardStorage(connectionString, "TBDD_SMF_CONFIG", notifier: notifier);
        configurator.SetDashboardStorage(dashboardStorage);

        DataSourceInMemoryStorage dataSourceStorage = new DataSourceInMemoryStorage();
        DashboardJsonDataSource jsonDataSourceUrl = new DashboardJsonDataSource("JSON Data Source (URL)");
        jsonDataSourceUrl.JsonSource = new UriJsonSource(
                new Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json"));
        jsonDataSourceUrl.RootElement = "Customers";
        dataSourceStorage.RegisterDataSource("jsonDataSourceUrl", jsonDataSourceUrl.SaveToXml());

        var catalogsJsonDataSource = new DashboardJsonDataSource("Catalogs (API)")
        {
            ComponentName = "catalogsDataSource",
            JsonSource = new UriJsonSource(new Uri($"{dashboardBaseUrl}/api/catalogs"))
        };
        dataSourceStorage.RegisterDataSource(catalogsJsonDataSource.ComponentName, catalogsJsonDataSource.SaveToXml());
        dataSourceStorage.RegisterDataSource(catalogsJsonDataSource.Name, catalogsJsonDataSource.SaveToXml());

        configurator.SetDataSourceStorage(dataSourceStorage);

        EnsureDashboardInStorage(dashboardStorage, "DefaultDashboard", defaultDashboardPath);
        EnsureDashboardInStorage(dashboardStorage, "CatalogsGrid", catalogsGridDashboardPath);

        return configurator;
    }

    private static void EnsureDashboardInStorage(IEditableDashboardStorage storage, string id, string filePath)
    {
        var exists = storage.GetAvailableDashboardsInfo().Any(info => string.Equals(info.ID, id, StringComparison.OrdinalIgnoreCase));
        if (exists || !File.Exists(filePath))
        {
            return;
        }

        var doc = XDocument.Load(filePath);
        storage.AddDashboard(doc, id);
    }
}