using FWLAZData;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FWLAZData
{
    public class DBManagement
    {
        public class ConnectionResult
        {
            public enum ConnectionStatus
            {
                ConnectionFailed,
                DatabaseMissing,
                UpdatesMissing,
                Successful,
            }

            public ConnectionStatus Status { get; set; }
            public string? Details { get; set; }

            public ConnectionResult(ConnectionStatus status)
            {
                Status = status;
            }
            public ConnectionResult(ConnectionStatus status, string details) : this(status)
            {
                Details = details;
            }

        }

        internal static void Migrate()
        {
            using (LocalDbContext db = new())
            {
                // Prüfen, ob Datenbank existiert, bevor EnsureCreated ausgeführt wird (EnsureCreated legt schon die benötigten Indizes an)
                var dbdir = Path.GetDirectoryName(LocalDbContext.DatabaseFile);
                if (dbdir != null && !Directory.Exists(dbdir)) Directory.CreateDirectory(dbdir);
                Console.Write("Applying migrations...");
                db.Database.Migrate();
                Console.WriteLine("Done");
            }
        }

        public static ConnectionResult TestConnection()
        {
            try
            {
                using (LocalDbContext db = new())
                {
                    if (!db.Database.CanConnect()) return new ConnectionResult(ConnectionResult.ConnectionStatus.DatabaseMissing); // CanConnect throws an exception if the server is not available and returns false if the database is missing
                    if (db.Database.GetPendingMigrations().Count() > 0) return new ConnectionResult(ConnectionResult.ConnectionStatus.UpdatesMissing);
                    return new ConnectionResult(ConnectionResult.ConnectionStatus.Successful);
                }
            }
            catch (Exception ex)
            {
                return new ConnectionResult(ConnectionResult.ConnectionStatus.ConnectionFailed, ex.Message);
            }
        }

        public static void ConnectAndMigrate()
        {
            var ConnectionStatus = TestConnection();
            switch (ConnectionStatus.Status)
            {
                case ConnectionResult.ConnectionStatus.Successful:
                    return;
                case ConnectionResult.ConnectionStatus.ConnectionFailed:
                    throw new Exception($"Connection to database failed: {ConnectionStatus.Details}");
                case ConnectionResult.ConnectionStatus.DatabaseMissing:
                case ConnectionResult.ConnectionStatus.UpdatesMissing:
                    Migrate();
                    return;
            }
        }
    }
}
