package com.haha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haha.common.constant.CommonConstants;
import com.haha.common.vo.AdminStatisticsVO;
import com.haha.common.vo.Result;
import com.haha.entity.Admin;
import com.haha.mapper.AdminMapper;
import com.haha.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 管理员服务实现类
 */
@Slf4j
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public Result<IPage<Admin>> getAdminList(int page, int pageSize, String username, String phone, Long roleId, Integer status) {
        try {
            LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();

            // 条件查询
            if (StringUtils.hasText(username)) {
                wrapper.and(w -> w.like(Admin::getUsername, username)
                                  .or().like(Admin::getRealName, username));
            }
            if (StringUtils.hasText(phone)) {
                wrapper.eq(Admin::getPhone, phone);
            }
            if (roleId != null) {
                // roleIds是逗号分隔的字符串，使用like模糊匹配
                wrapper.like(Admin::getRoleIds, roleId.toString());
            }
            if (status != null) {
                wrapper.eq(Admin::getStatus, status);
            }

            // 按创建时间倒序
            wrapper.orderByDesc(Admin::getCreateTime);

            // 分页查询
            Page<Admin> pageObj = new Page<>(page, pageSize);
            IPage<Admin> result = this.page(pageObj, wrapper);

            // 密码字段置空
            result.getRecords().forEach(admin -> admin.setPassword(null));

            return Result.success("查询成功", result);

        } catch (Exception e) {
            log.error("查询管理员列表失败", e);
            return Result.error(500, "查询失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> addAdmin(Admin admin) {
        try {
            // 检查用户名是否已存在
            Admin existAdmin = lambdaQuery().eq(Admin::getUsername, admin.getUsername()).one();
            if (existAdmin != null) {
                return Result.error(400, "用户名已存在");
            }

            // 检查手机号是否已存在
            if (StringUtils.hasText(admin.getPhone())) {
                existAdmin = lambdaQuery().eq(Admin::getPhone, admin.getPhone()).one();
                if (existAdmin != null) {
                    return Result.error(400, "手机号已存在");
                }
            }

            // 设置默认值
            admin.setStatus(CommonConstants.STATUS_ENABLED); // 默认正常状态
            admin.setCreateTime(LocalDateTime.now());
            admin.setUpdateTime(LocalDateTime.now());

            // BCrypt加密密码
            String password = admin.getPassword();
            if (!StringUtils.hasText(password)) {
                password = CommonConstants.DEFAULT_PASSWORD;
            }
            admin.setPassword(passwordEncoder.encode(password));

            boolean success = this.save(admin);
            return success ? Result.success("添加成功", null) : Result.error(500, "添加失败");

        } catch (Exception e) {
            log.error("添加管理员失败", e);
            return Result.error(500, "添加失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> updateAdmin(Admin admin) {
        try {
            // 检查管理员是否存在
            Admin existAdmin = this.getById(admin.getId());
            if (existAdmin == null) {
                return Result.error(404, "管理员不存在");
            }

            // 如果修改了用户名，检查是否重复
            if (!existAdmin.getUsername().equals(admin.getUsername())) {
                Admin checkAdmin = lambdaQuery().eq(Admin::getUsername, admin.getUsername()).one();
                if (checkAdmin != null) {
                    return Result.error(400, "用户名已存在");
                }
            }

            // 如果修改了手机号，检查是否重复
            if (StringUtils.hasText(admin.getPhone()) && !admin.getPhone().equals(existAdmin.getPhone())) {
                Admin checkAdmin = lambdaQuery().eq(Admin::getPhone, admin.getPhone()).one();
                if (checkAdmin != null) {
                    return Result.error(400, "手机号已存在");
                }
            }

            admin.setUpdateTime(LocalDateTime.now());
            // 不允许通过此接口修改密码
            admin.setPassword(null);

            boolean success = this.updateById(admin);
            return success ? Result.success("更新成功", null) : Result.error(500, "更新失败");

        } catch (Exception e) {
            log.error("更新管理员失败", e);
            return Result.error(500, "更新失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> deleteAdmin(Long id) {
        try {
            // 检查管理员是否存在
            Admin admin = this.getById(id);
            if (admin == null) {
                return Result.error(404, "管理员不存在");
            }

            // TODO: 检查是否可以删除(如果是超级管理员则不允许删除)

            boolean success = this.removeById(id);
            return success ? Result.success("删除成功", null) : Result.error(500, "删除失败");

        } catch (Exception e) {
            log.error("删除管理员失败", e);
            return Result.error(500, "删除失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> resetPassword(Long id, String newPassword) {
        try {
            Admin admin = this.getById(id);
            if (admin == null) {
                return Result.error(404, "管理员不存在");
            }

            // BCrypt加密密码
            if (!StringUtils.hasText(newPassword)) {
                newPassword = CommonConstants.DEFAULT_PASSWORD;
            }
            admin.setPassword(passwordEncoder.encode(newPassword));
            admin.setUpdateTime(LocalDateTime.now());

            boolean success = this.updateById(admin);
            return success ? Result.success("密码重置成功", null) : Result.error(500, "密码重置失败");

        } catch (Exception e) {
            log.error("重置密码失败", e);
            return Result.error(500, "重置密码失败: " + e.getMessage());
        }
    }

    @Override
    public Result<AdminStatisticsVO> getStatistics() {
        try {
            // 总管理员数
            long total = this.count();

            // 正常状态管理员数
            long active = this.count(new LambdaQueryWrapper<Admin>().eq(Admin::getStatus, CommonConstants.STATUS_ENABLED));

            // 禁用状态管理员数
            long disabled = this.count(new LambdaQueryWrapper<Admin>().eq(Admin::getStatus, CommonConstants.ADMIN_STATUS_DISABLED));

            AdminStatisticsVO statistics = AdminStatisticsVO.builder()
                    .total(total)
                    .active(active)
                    .disabled(disabled)
                    .todayLogin(0)
                    .build();

            return Result.success("获取成功", statistics);

        } catch (Exception e) {
            log.error("获取统计数据失败", e);
            return Result.error(500, "获取统计数据失败: " + e.getMessage());
        }
    }

    @Override
    public List<Admin> getAvailableAdmins(String keyword) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getStatus, CommonConstants.STATUS_ENABLED); // 只查询正常状态的管理员
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(Admin::getRealName, keyword)
                    .or().like(Admin::getPhone, keyword)
                    .or().like(Admin::getUsername, keyword));
        }
        wrapper.orderByDesc(Admin::getCreateTime);
        return this.list(wrapper);
    }
}
