using System.Linq.Expressions;
using BCrypt.Net;
using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;

using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;

namespace QYZH.InteractiveMagazine.Service;

/// <summary>
/// 管理员用户服务实现
/// </summary>
public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILogger<AdminUserService> logger) : BaseRepository<AdminUser>, IAdminUserService
{

    /// <summary>
    /// 创建管理员
    /// </summary>
    public async Task<AdminUserOutput> CreateAsync(AdminUserInput input)
    {
        logger.LogInformation("正在创建管理员，用户名: {UserName}", input.UserName);

        if (string.IsNullOrWhiteSpace(input.UserName))
        {
            throw new BusinessException("用户名不能为空", ResultCode.BAD_REQUEST);
        }

        if (string.IsNullOrWhiteSpace(input.Password))
        {
            throw new BusinessException("密码不能为空", ResultCode.BAD_REQUEST);
        }

        // 检查用户名是否已存在
        var existingUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName);
        if (existingUser != null)
        {
            logger.LogWarning("创建管理员失败，用户名已存在: {UserName}", input.UserName);
            throw new BusinessException("用户名已存在", ResultCode.CONFLICT);
        }

        var adminUser = new AdminUser
        {
            UserName = input.UserName.Trim(),
            PasswordHash = BCrypt.Net.BCrypt.HashPassword(input.Password),
            Type = input.Type,
            Status = input.Status,
            CreatedBy = "System",
            UpdatedBy = "System",
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now,
            IsDeleted = false
        };

        var result = await adminUserRepository.InsertAsync(adminUser);
        if (!result)
        {
            logger.LogError("管理员创建失败，用户名: {UserName}", input.UserName);
            throw new BusinessException("创建管理员失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("管理员创建成功，用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);

        return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type.ToString(), Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
    }

    /// <summary>
    /// 更新管理员
    /// </summary>
    public async Task<AdminUserOutput> UpdateAsync(long id, AdminUserInput input)
    {
        logger.LogInformation("正在更新管理员，ID: {Id}", id);

        var adminUser = await adminUserRepository.GetByIdAsync(id);
        if (adminUser == null)
        {
            logger.LogWarning("未找到要更新的管理员，ID: {Id}", id);
            throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
        }

        // 如果用户名有变更，检查是否与其他用户重复
        if (!string.IsNullOrWhiteSpace(input.UserName) && input.UserName != adminUser.UserName)
        {
            var existingUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName.Trim());
            if (existingUser != null && existingUser.Id != id)
            {
                logger.LogWarning("更新管理员失败，用户名已存在: {UserName}", input.UserName);
                throw new BusinessException("用户名已存在", ResultCode.CONFLICT);
            }

            adminUser.UserName = input.UserName.Trim();
        }

        // 如果提供了密码，则更新密码
        if (!string.IsNullOrWhiteSpace(input.Password))
        {
            adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(input.Password);
        }

       adminUser.Type = input.Type;


        adminUser.UpdatedBy = "System";
        adminUser.UpdatedAt = DateTime.Now;

        var result = await adminUserRepository.UpdateAsync(adminUser);
        if (!result)
        {
            logger.LogError("管理员更新失败，ID: {Id}", id);
            throw new BusinessException("更新管理员失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("管理员更新成功，ID: {Id}", id);

        return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type.ToString(), Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
    }

    /// <summary>
    /// 删除管理员（软删除）
    /// </summary>
    public async Task DeleteAsync(long id)
    {
        logger.LogInformation("正在删除管理员，ID: {Id}", id);

        var adminUser = await adminUserRepository.GetByIdAsync(id);
        if (adminUser == null)
        {
            logger.LogWarning("未找到要删除的管理员，ID: {Id}", id);
            throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
        }

        var result = await adminUserRepository.DeleteByIdAsync(id);
        if (!result)
        {
            logger.LogError("管理员删除失败，ID: {Id}", id);
            throw new BusinessException("删除管理员失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("管理员删除成功，ID: {Id}", id);
    }

    /// <summary>
    /// 根据ID获取管理员
    /// </summary>
    public async Task<AdminUserOutput> GetByIdAsync(long id)
    {
        logger.LogInformation("正在获取管理员信息，ID: {Id}", id);

        var adminUser = await adminUserRepository.GetByIdAsync(id);
        if (adminUser == null)
        {
            logger.LogWarning("未找到管理员，ID: {Id}", id);
            throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
        }
        return new AdminUserOutput
        {
            Id = adminUser.Id,
            UserName = adminUser.UserName,
            Type = adminUser.Type.ToString(),
            Status = adminUser.Status,
            CreatedBy = adminUser.CreatedBy,
            CreatedAt = adminUser.CreatedAt,
            UpdatedBy = adminUser.UpdatedBy,
            UpdatedAt = adminUser.UpdatedAt
        };
    }

    /// <summary>
    /// 分页查询管理员列表
    /// </summary>
    public async Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input)
    {
        logger.LogInformation("正在查询管理员列表，页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);

        if (input.PageIndex <= 0)
        {
            throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
        }

        if (input.PageSize <= 0 || input.PageSize > 100)
        {
            throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
        }
        RefAsync<int> totalNumber = 0;
        var pageResult = await adminUserRepository.Queryable()
               .WhereIF(!string.IsNullOrWhiteSpace(input.UserName), a => a.UserName == input.UserName)
                .OrderByDescending(a => a.CreatedAt)
                 .Select(a => new AdminUserOutput
                 {
                     Id = a.Id,
                     UserName = a.UserName,
                     Type = a.Type.ToString(),
                     Status = a.Status,
                     CreatedBy = a.CreatedBy,
                     CreatedAt = a.CreatedAt,
                     UpdatedBy = a.UpdatedBy,
                     UpdatedAt = a.UpdatedAt
                 }, true)
                  .ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
        return new PageListModel<AdminUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
    }

    /// <summary>
    /// 切换管理员状态（激活/冻结）
    /// </summary>
    public async Task ToggleStatusAsync(long id)
    {
        logger.LogInformation("正在切换管理员状态，ID: {Id}", id);

        var adminUser = await adminUserRepository.GetByIdAsync(id);
        if (adminUser == null)
        {
            logger.LogWarning("未找到要更新状态的管理员，ID: {Id}", id);
            throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
        }

        adminUser.Status = adminUser.Status==(int)DefaultStatusEnum.Active?(int)DefaultStatusEnum.Inactive:(int)DefaultStatusEnum.Active;
        adminUser.UpdatedBy = "System";
        adminUser.UpdatedAt = DateTime.Now;

        var result = await adminUserRepository.UpdateAsync(adminUser);
        if (!result)
        {
            logger.LogError("管理员状态更新失败，ID: {Id}", id);
            throw new BusinessException("更新管理员状态失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("管理员状态更新成功，ID: {Id}", id);
    }
}
