using Aberwyn.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
using System.Text.Json;
using static Aberwyn.Data.SetupService;

namespace Aberwyn.Data
{
    public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            var setup = LoadSetup();

            var csBuilder = new MySqlConnector.MySqlConnectionStringBuilder
            {
                Server = setup.DbHost,
                Port = (uint)setup.DbPort,
                Database = setup.DbName,
                UserID = setup.DbUser,
                Password = setup.DbPassword,
                AllowUserVariables = true
            };

            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseMySql(csBuilder.ConnectionString, new MySqlServerVersion(new Version(8, 0, 36)));

            return new ApplicationDbContext(optionsBuilder.Options);
        }

        public static ApplicationDbContext CreateWithConfig(IHostEnvironment env, bool useProdDb = false)
        {
            var setup = SetupLoader.Load(env);
            var connStr = SetupLoader.GetConnectionString(setup);

            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseMySql(connStr, new MySqlServerVersion(new Version(8, 0, 36)));

            return new ApplicationDbContext(optionsBuilder.Options);
        }


        private static SetupSettings LoadSetup()
        {
            var basePath = Directory.GetCurrentDirectory();
            var setupPath = Path.Combine(basePath, "infrastructure", "setup.json");

            if (!File.Exists(setupPath))
                throw new FileNotFoundException("setup.json saknas i infrastructure-mappen.");

            var json = File.ReadAllText(setupPath);
            var setup = JsonSerializer.Deserialize<SetupSettings>(json);

            if (setup == null || !setup.IsConfigured)
                throw new InvalidOperationException("setup.json är inte korrekt konfigurerad.");

            return setup;
        }
    }
}
