using FreeSql;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using BookmarkApi.Data.Entities;

namespace BookmarkApi.Data;

/// <summary>
/// FreeSql 配置扩展
/// </summary>
public static class FreeSqlSetup
{
    /// <summary>
    /// 添加 FreeSql 服务
    /// </summary>
    public static IServiceCollection AddFreeSql(this IServiceCollection services, IConfiguration configuration)
    {
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        var provider = configuration["DatabaseProvider"]?.ToLower() ?? "sqlserver";

        var dataType = provider switch
        {
            "postgresql" or "pgsql" => DataType.PostgreSQL,
            "sqlserver" or "mssql" => DataType.SqlServer,
            _ => DataType.SqlServer
        };

        var freeSql = new FreeSqlBuilder()
            .UseConnectionString(dataType, connectionString)
            .UseAutoSyncStructure(true) // 自动同步实体结构到数据库
            .UseMonitorCommand(cmd => Console.WriteLine($"[FreeSql] {cmd.CommandText}")) // 开发时打印 SQL
            .Build();

        // 注册为单例
        services.AddSingleton<IFreeSql>(freeSql);

        return services;
    }

    /// <summary>
    /// 初始化数据库（创建表、种子数据等）
    /// </summary>
    public static async Task InitializeDatabaseAsync(IFreeSql freeSql)
    {
        // 同步表结构
        freeSql.CodeFirst.SyncStructure<User>();
        freeSql.CodeFirst.SyncStructure<Device>();
        freeSql.CodeFirst.SyncStructure<Bookmark>();
        freeSql.CodeFirst.SyncStructure<RefreshToken>();

        // 创建超级管理员账号（如果不存在）
        await SeedSuperAdminAsync(freeSql);
    }

    /// <summary>
    /// 创建超级管理员种子数据
    /// </summary>
    private static async Task SeedSuperAdminAsync(IFreeSql freeSql)
    {
        const string adminEmail = "admin@bookmarks.local";

        var adminExists = await freeSql.Select<User>()
            .Where(u => u.Email == adminEmail)
            .AnyAsync();

        if (!adminExists)
        {
            var admin = new User
            {
                Id = Guid.NewGuid(),
                Email = adminEmail,
                UserName = "Administrator",
                PasswordHash = BCrypt.Net.BCrypt.HashPassword("Admin@123"),
                Role = Shared.Enums.AdminRole.SuperAdmin,
                Status = Shared.Enums.UserStatus.Normal,
                CreatedAt = DateTime.UtcNow
            };

            await freeSql.Insert(admin).ExecuteAffrowsAsync();
            Console.WriteLine($"[FreeSql] Created super admin account: {adminEmail}");
        }
    }
}

