using HoneyBox.Admin.Data;
using HoneyBox.Admin.Entities;
using HoneyBox.Admin.Models.AdminUser;
using HoneyBox.Admin.Models.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Admin.Services;

/// <summary>
/// 管理员服务实现
/// </summary>
public class AdminUserService : IAdminUserService
{
    private readonly AdminDbContext _dbContext;
    private readonly ILogger<AdminUserService> _logger;
    private readonly IAuthService _authService;

    // 超级管理员角色编码
    private const string SuperAdminRoleCode = "super_admin";

    public AdminUserService(AdminDbContext dbContext, ILogger<AdminUserService> logger, IAuthService authService)
    {
        _dbContext = dbContext;
        _logger = logger;
        _authService = authService;
    }

    /// <inheritdoc />
    public async Task<PagedResult<AdminUserDto>> GetListAsync(AdminUserQueryRequest request)
    {
        var query = _dbContext.AdminUsers
            .Include(u => u.Department)
            .Include(u => u.AdminUserRoles)
                .ThenInclude(ur => ur.Role)
            .AsQueryable();

        // 关键词模糊搜索（用户名、姓名、手机号）
        if (!string.IsNullOrWhiteSpace(request.Keyword))
        {
            var keyword = request.Keyword;
            query = query.Where(u => 
                u.Username.Contains(keyword) || 
                (u.RealName != null && u.RealName.Contains(keyword)) ||
                (u.Phone != null && u.Phone.Contains(keyword)));
        }

        // 部门筛选
        if (request.DepartmentId.HasValue)
        {
            query = query.Where(u => u.DepartmentId == request.DepartmentId.Value);
        }

        // 状态筛选
        if (request.Status.HasValue)
        {
            query = query.Where(u => u.Status == request.Status.Value);
        }

        var total = await query.CountAsync();

        var list = await query
            .OrderByDescending(u => u.CreatedAt)
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(u => new AdminUserDto
            {
                Id = u.Id,
                Username = u.Username,
                RealName = u.RealName,
                Avatar = u.Avatar,
                Email = u.Email,
                Phone = u.Phone,
                DepartmentId = u.DepartmentId,
                DepartmentName = u.Department != null ? u.Department.Name : null,
                Status = u.Status,
                LastLoginTime = u.LastLoginTime,
                LastLoginIp = u.LastLoginIp,
                CreatedAt = u.CreatedAt,
                UpdatedAt = u.UpdatedAt,
                Remark = u.Remark,
                RoleIds = u.AdminUserRoles.Select(ur => ur.RoleId).ToList(),
                RoleNames = u.AdminUserRoles.Select(ur => ur.Role.Name).ToList(),
                Roles = u.AdminUserRoles.Select(ur => new AdminUserRoleDto
                {
                    Id = ur.RoleId,
                    Name = ur.Role.Name
                }).ToList()
            })
            .ToListAsync();

        return new PagedResult<AdminUserDto>
        {
            List = list,
            Total = total,
            Page = request.Page,
            PageSize = request.PageSize
        };
    }


    /// <inheritdoc />
    public async Task<AdminUserDto> GetByIdAsync(long id)
    {
        var user = await _dbContext.AdminUsers
            .Include(u => u.Department)
            .Include(u => u.AdminUserRoles)
                .ThenInclude(ur => ur.Role)
            .Include(u => u.AdminUserMenus)
            .FirstOrDefaultAsync(u => u.Id == id);

        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        return new AdminUserDto
        {
            Id = user.Id,
            Username = user.Username,
            RealName = user.RealName,
            Avatar = user.Avatar,
            Email = user.Email,
            Phone = user.Phone,
            DepartmentId = user.DepartmentId,
            DepartmentName = user.Department?.Name,
            Status = user.Status,
            LastLoginTime = user.LastLoginTime,
            LastLoginIp = user.LastLoginIp,
            CreatedAt = user.CreatedAt,
            UpdatedAt = user.UpdatedAt,
            Remark = user.Remark,
            RoleIds = user.AdminUserRoles.Select(ur => ur.RoleId).ToList(),
            RoleNames = user.AdminUserRoles.Select(ur => ur.Role.Name).ToList(),
            Roles = user.AdminUserRoles.Select(ur => new AdminUserRoleDto
            {
                Id = ur.RoleId,
                Name = ur.Role.Name
            }).ToList(),
            MenuIds = user.AdminUserMenus.Select(um => um.MenuId).ToList()
        };
    }

    /// <inheritdoc />
    public async Task<long> CreateAsync(CreateAdminUserRequest request, long? createdBy = null)
    {
        // 检查用户名是否重复
        var usernameExists = await _dbContext.AdminUsers.AnyAsync(u => u.Username == request.Username);
        if (usernameExists)
        {
            throw new AdminException(AdminErrorCodes.DuplicateUsername, "用户名已存在");
        }

        // 验证部门是否存在
        if (request.DepartmentId.HasValue)
        {
            var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.DepartmentId.Value);
            if (!departmentExists)
            {
                throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
            }
        }

        var user = new Entities.AdminUser
        {
            Username = request.Username,
            PasswordHash = AuthService.HashPassword(request.Password),
            RealName = request.RealName,
            Avatar = request.Avatar,
            Email = request.Email,
            Phone = request.Phone,
            DepartmentId = request.DepartmentId,
            Status = request.Status,
            Remark = request.Remark,
            CreatedBy = createdBy,
            CreatedAt = DateTime.Now
        };

        _dbContext.AdminUsers.Add(user);
        await _dbContext.SaveChangesAsync();

        // 分配角色
        if (request.RoleIds.Any())
        {
            var userRoles = request.RoleIds.Distinct().Select(roleId => new AdminUserRole
            {
                AdminUserId = user.Id,
                RoleId = roleId
            });
            _dbContext.AdminUserRoles.AddRange(userRoles);
            await _dbContext.SaveChangesAsync();
        }

        _logger.LogInformation("创建管理员成功: {UserId} - {Username}", user.Id, user.Username);
        return user.Id;
    }

    /// <inheritdoc />
    public async Task UpdateAsync(long id, UpdateAdminUserRequest request)
    {
        var user = await _dbContext.AdminUsers.FindAsync(id);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        // 验证部门是否存在
        if (request.DepartmentId.HasValue)
        {
            var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.DepartmentId.Value);
            if (!departmentExists)
            {
                throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
            }
        }

        user.RealName = request.RealName;
        user.Avatar = request.Avatar;
        user.Email = request.Email;
        user.Phone = request.Phone;
        user.DepartmentId = request.DepartmentId;
        user.Status = request.Status;
        user.Remark = request.Remark;
        user.UpdatedAt = DateTime.Now;

        await _dbContext.SaveChangesAsync();
        _logger.LogInformation("更新管理员成功: {UserId} - {Username}", user.Id, user.Username);
    }

    /// <inheritdoc />
    public async Task DeleteAsync(long id)
    {
        var user = await _dbContext.AdminUsers
            .Include(u => u.AdminUserRoles)
                .ThenInclude(ur => ur.Role)
            .FirstOrDefaultAsync(u => u.Id == id);

        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        // 检查是否是最后一个超级管理员
        var isSuperAdmin = user.AdminUserRoles.Any(ur => ur.Role.Code == SuperAdminRoleCode);
        if (isSuperAdmin)
        {
            var superAdminCount = await _dbContext.AdminUserRoles
                .Include(ur => ur.Role)
                .Where(ur => ur.Role.Code == SuperAdminRoleCode)
                .Select(ur => ur.AdminUserId)
                .Distinct()
                .CountAsync();

            if (superAdminCount <= 1)
            {
                throw new AdminException(AdminErrorCodes.CannotDeleteLastSuperAdmin, "不能删除最后一个超级管理员");
            }
        }

        // 删除关联数据
        var userRoles = await _dbContext.AdminUserRoles.Where(ur => ur.AdminUserId == id).ToListAsync();
        _dbContext.AdminUserRoles.RemoveRange(userRoles);

        var userMenus = await _dbContext.AdminUserMenus.Where(um => um.AdminUserId == id).ToListAsync();
        _dbContext.AdminUserMenus.RemoveRange(userMenus);

        _dbContext.AdminUsers.Remove(user);
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("删除管理员成功: {UserId} - {Username}", id, user.Username);
    }

    /// <inheritdoc />
    public async Task<List<long>> GetRoleIdsAsync(long userId)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        return await _dbContext.AdminUserRoles
            .Where(ur => ur.AdminUserId == userId)
            .Select(ur => ur.RoleId)
            .ToListAsync();
    }

    /// <inheritdoc />
    public async Task AssignRolesAsync(long userId, List<long> roleIds)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        // 删除现有关联
        var existingRoles = await _dbContext.AdminUserRoles.Where(ur => ur.AdminUserId == userId).ToListAsync();
        _dbContext.AdminUserRoles.RemoveRange(existingRoles);

        // 添加新关联
        if (roleIds.Any())
        {
            var newRoles = roleIds.Distinct().Select(roleId => new AdminUserRole
            {
                AdminUserId = userId,
                RoleId = roleId
            });
            _dbContext.AdminUserRoles.AddRange(newRoles);
        }

        await _dbContext.SaveChangesAsync();
        _logger.LogInformation("管理员 {UserId} 分配角色成功，角色数量: {Count}", userId, roleIds.Count);
    }

    /// <inheritdoc />
    public async Task<List<long>> GetMenuIdsAsync(long userId)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        return await _dbContext.AdminUserMenus
            .Where(um => um.AdminUserId == userId)
            .Select(um => um.MenuId)
            .ToListAsync();
    }

    /// <inheritdoc />
    public async Task AssignMenusAsync(long userId, List<long> menuIds)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        // 删除现有关联
        var existingMenus = await _dbContext.AdminUserMenus.Where(um => um.AdminUserId == userId).ToListAsync();
        _dbContext.AdminUserMenus.RemoveRange(existingMenus);

        // 添加新关联
        if (menuIds.Any())
        {
            var newMenus = menuIds.Distinct().Select(menuId => new AdminUserMenu
            {
                AdminUserId = userId,
                MenuId = menuId
            });
            _dbContext.AdminUserMenus.AddRange(newMenus);
        }

        await _dbContext.SaveChangesAsync();
        _logger.LogInformation("管理员 {UserId} 分配用户专属菜单成功，菜单数量: {Count}", userId, menuIds.Count);
    }

    /// <inheritdoc />
    public async Task AssignDepartmentAsync(long userId, long? departmentId)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        // 验证部门是否存在
        if (departmentId.HasValue)
        {
            var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == departmentId.Value);
            if (!departmentExists)
            {
                throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
            }
        }

        user.DepartmentId = departmentId;
        user.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("管理员 {UserId} 分配部门成功，部门ID: {DepartmentId}", userId, departmentId);
    }

    /// <inheritdoc />
    public async Task SetStatusAsync(long userId, bool enabled, string? ipAddress = null)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        user.Status = enabled ? (byte)1 : (byte)0;
        user.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        // 禁用账号时撤销所有 RefreshToken
        if (!enabled)
        {
            await _authService.RevokeAllTokensAsync(userId, ipAddress ?? "system");
            _logger.LogInformation("管理员 {UserId} 账号被禁用，已撤销所有 RefreshToken", userId);
        }

        _logger.LogInformation("管理员 {UserId} 状态设置为: {Status}", userId, enabled ? "启用" : "禁用");
    }

    /// <inheritdoc />
    public async Task ResetPasswordAsync(long userId, string newPassword)
    {
        var user = await _dbContext.AdminUsers.FindAsync(userId);
        if (user == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
        }

        user.PasswordHash = AuthService.HashPassword(newPassword);
        user.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("管理员 {UserId} 密码重置成功", userId);
    }
}
