package shop.alien.storeplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.config.redis.BaseRedisService;
import shop.alien.entity.store.StorePlatformRole;
import shop.alien.entity.store.StoreUser;
import shop.alien.entity.store.vo.StorePlatformRoleVo;
import shop.alien.mapper.StorePlatformRoleMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.storeplatform.service.StorePlatformRoleMenuService;
import shop.alien.storeplatform.service.StorePlatformRoleService;
import shop.alien.storeplatform.service.StorePlatformUserRoleService;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 平台角色信息表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class StorePlatformRoleServiceImpl extends ServiceImpl<StorePlatformRoleMapper, StorePlatformRole> implements StorePlatformRoleService {

    private final StorePlatformRoleMapper storePlatformRoleMapper;
    private final StorePlatformRoleMenuService storePlatformRoleMenuService;
    private final StorePlatformUserRoleService storePlatformUserRoleService;
    private final StoreUserMapper storeUserMapper;
    private final BaseRedisService baseRedisService;

    @Override
    public IPage<StorePlatformRole> getRolePage(int page, int size, Integer storeId, String roleName, String description, String status) {
        LambdaQueryWrapper<StorePlatformRole> queryWrapper = new LambdaQueryWrapper<>();
        
        // 店铺ID查询
        if (storeId != null) {
            queryWrapper.eq(StorePlatformRole::getStoreId, storeId);
        }
        
        // 角色名称模糊查询
        if (StringUtils.hasText(roleName)) {
            queryWrapper.like(StorePlatformRole::getRoleName, roleName);
        }
        // 角色描述模糊查询
        if (StringUtils.hasText(description)) {
            queryWrapper.like(StorePlatformRole::getDescription, description);
        }
        
        // 角色状态查询
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(StorePlatformRole::getStatus, status);
        }
        
        // 按显示顺序和创建时间排序
        queryWrapper.orderByAsc(StorePlatformRole::getRoleSort);
        queryWrapper.orderByDesc(StorePlatformRole::getCreatedTime);

        return storePlatformRoleMapper.selectPage(new Page<>(page, size), queryWrapper);
    }

    @Override
    public StorePlatformRole getRoleById(Long roleId) {
        return storePlatformRoleMapper.selectById(roleId);
    }

    @Override
    public boolean saveRole(StorePlatformRole role) {
        // 校验必填字段
        if (!StringUtils.hasText(role.getRoleName())) {
            log.error("角色名称不能为空");
            return false;
        }
        // 检查角色名称是否已存在（同一店铺内不能重复）
        if (checkRoleNameExists(role.getStoreId(), role.getRoleName(), null)) {
            log.error("角色名称已存在：{}", role.getRoleName());
            return false;
        }
        // 设置默认值
        if (role.getRoleSort() == null) {
            role.setRoleSort(0);
        }
        if (!StringUtils.hasText(role.getStatus())) {
            role.setStatus("0"); // 默认正常
        }
        if (!StringUtils.hasText(role.getDelFlag())) {
            role.setDelFlag("0"); // 默认未删除
        }
        int result = storePlatformRoleMapper.insert(role);
        return result > 0;
    }

    @Override
    public boolean createRoleWithMenus(StorePlatformRole role, List<Long> menuIds) {
        // 校验必填字段
        if (!StringUtils.hasText(role.getRoleName())) {
            log.error("角色名称不能为空");
            return false;
        }
        // 检查角色名称是否已存在（同一店铺内不能重复）
        if (checkRoleNameExists(role.getStoreId(), role.getRoleName(), null)) {
            log.error("角色名称已存在，不允许重复添加：{}", role.getRoleName());
            return false;
        }
        // 设置默认值
        if (role.getRoleSort() == null) {
            role.setRoleSort(0);
        }
        if (!StringUtils.hasText(role.getStatus())) {
            role.setStatus("0"); // 默认正常
        }
        if (!StringUtils.hasText(role.getDelFlag())) {
            role.setDelFlag("0"); // 默认未删除
        }
        // 保存角色
        int result = storePlatformRoleMapper.insert(role);
        if (result <= 0) {
            log.error("保存角色失败");
            return false;
        }
        // 如果有菜单权限，保存到关联表
        if (menuIds != null && !menuIds.isEmpty()) {
            boolean assignResult = storePlatformRoleMenuService.assignMenus(role.getRoleId(), menuIds);
            if (!assignResult) {
                log.error("分配菜单权限失败，角色ID：{}", role.getRoleId());
                // 如果分配权限失败，可以考虑回滚角色创建，这里先记录日志
            }
        }
        return true;
    }

    @Override
    public boolean checkRoleNameExists(Integer storeId, String roleName, Long excludeRoleId) {
        if (!StringUtils.hasText(roleName)) {
            return false;
        }
        LambdaQueryWrapper<StorePlatformRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRole::getRoleName, roleName);
        queryWrapper.eq(StorePlatformRole::getDelFlag, "0"); // 只查询未删除的
        // 店铺ID查询（同一店铺内角色名称不能重复）
        if (storeId != null) {
            queryWrapper.eq(StorePlatformRole::getStoreId, storeId);
        }
        // 如果指定了排除的角色ID，则排除该角色
        if (excludeRoleId != null) {
            queryWrapper.ne(StorePlatformRole::getRoleId, excludeRoleId);
        }
        long count = storePlatformRoleMapper.selectCount(queryWrapper);
        return count > 0;
    }

    @Override
    public boolean updateRole(StorePlatformRole role) {
        if (role.getRoleId() == null) {
            log.error("角色ID不能为空");
            return false;
        }

        int result = storePlatformRoleMapper.updateById(role);
        return result > 0;
    }

    @Override
    public boolean updateRoleWithMenus(StorePlatformRole role, List<Long> menuIds) {
        if (role.getRoleId() == null) {
            log.error("角色ID不能为空");
            return false;
        }

        // 1. 查询原始角色信息
        StorePlatformRole originalRole = storePlatformRoleMapper.selectById(role.getRoleId());
        if (originalRole == null) {
            log.error("角色不存在，roleId={}", role.getRoleId());
            return false;
        }

        // 2. 校验角色类型（roleName）是否变化
        boolean roleNameChanged = false;
        if (StringUtils.hasText(role.getRoleName()) && 
            !role.getRoleName().equals(originalRole.getRoleName())) {
            // 角色名称变化，需要校验是否重复
            // 使用传入的 storeId，如果没有则使用原始角色的 storeId
            Integer storeId = role.getStoreId() != null ? role.getStoreId() : originalRole.getStoreId();
            if (checkRoleNameExists(storeId, role.getRoleName(), role.getRoleId())) {
                log.error("角色名称已存在，不允许重复：{}", role.getRoleName());
                return false;
            }
            roleNameChanged = true;
            log.info("角色名称发生变化：{} -> {}", originalRole.getRoleName(), role.getRoleName());
        }

        // 3. 如果角色类型有变化，更新 store_platform_role 表
        if (roleNameChanged || role.getRoleSort() != null || 
            StringUtils.hasText(role.getStatus()) || StringUtils.hasText(role.getDescription()) ||
            StringUtils.hasText(role.getRoleNameEn()) || StringUtils.hasText(role.getRemark())) {
            // 只更新传入的字段，保留原有字段
            StorePlatformRole updateRole = new StorePlatformRole();
            updateRole.setRoleId(role.getRoleId());
            if (roleNameChanged && StringUtils.hasText(role.getRoleName())) {
                updateRole.setRoleName(role.getRoleName());
            }
            if (role.getRoleSort() != null) {
                updateRole.setRoleSort(role.getRoleSort());
            }
            if (StringUtils.hasText(role.getStatus())) {
                updateRole.setStatus(role.getStatus());
            }
            if (StringUtils.hasText(role.getDescription())) {
                updateRole.setDescription(role.getDescription());
            }
            if (StringUtils.hasText(role.getRoleNameEn())) {
                updateRole.setRoleNameEn(role.getRoleNameEn());
            }
            if (StringUtils.hasText(role.getRemark())) {
                updateRole.setRemark(role.getRemark());
            }
            
            int updateResult = storePlatformRoleMapper.updateById(updateRole);
            if (updateResult <= 0) {
                log.error("更新角色信息失败，roleId={}", role.getRoleId());
                return false;
            }
            log.info("成功更新角色信息，roleId={}", role.getRoleId());
        }

        // 4. 查询当前角色的权限列表
        List<Long> currentMenuIds = storePlatformRoleMenuService.getMenuIdsByRoleId(role.getRoleId());
        
        // 5. 比较权限是否变化
        boolean permissionsChanged = false;
        if (menuIds != null) {
            // 排序后比较，避免顺序不同导致的误判
            List<Long> sortedCurrent = currentMenuIds != null ? 
                currentMenuIds.stream().sorted().collect(Collectors.toList()) : 
                java.util.Collections.emptyList();
            List<Long> sortedNew = menuIds.stream().sorted().collect(Collectors.toList());
            
            if (!sortedCurrent.equals(sortedNew)) {
                permissionsChanged = true;
                log.info("权限发生变化，roleId={}, 原权限={}, 新权限={}", 
                    role.getRoleId(), sortedCurrent, sortedNew);
            }
        } else {
            // 如果传入的 menuIds 为 null，但当前有权限，也算变化
            if (currentMenuIds != null && !currentMenuIds.isEmpty()) {
                permissionsChanged = true;
                log.info("权限发生变化（清空权限），roleId={}, 原权限={}", role.getRoleId(), currentMenuIds);
            }
        }

        // 6. 如果权限有变化，更新 store_platform_role_menu 表
        if (permissionsChanged) {
            // 先删除所有现有权限
            boolean removeResult = storePlatformRoleMenuService.removeAllMenus(role.getRoleId());
            if (!removeResult) {
                log.error("删除角色权限失败，roleId={}", role.getRoleId());
                return false;
            }
            
            // 如果有新权限，则添加
            if (menuIds != null && !menuIds.isEmpty()) {
                boolean assignResult = storePlatformRoleMenuService.assignMenus(role.getRoleId(), menuIds);
                if (!assignResult) {
                    log.error("分配角色权限失败，roleId={}", role.getRoleId());
                    return false;
                }
            }
            //角色被编辑 清除当前被编辑角色的账号的token
            try {
                // 获取该角色下的所有用户ID
                Integer storeId = role.getStoreId() != null ? role.getStoreId() : originalRole.getStoreId();
                List<Integer> userIds = storePlatformUserRoleService.getUserIdsByRoleId(role.getRoleId(), storeId);
                if (userIds != null && !userIds.isEmpty()) {
                    // 根据用户ID查询用户信息，获取手机号
                    for (Integer userId : userIds) {
                        StoreUser storeUser = storeUserMapper.selectById(userId);
                        if (storeUser != null && storeUser.getPhone() != null) {
                            // 删除Redis中的token，key格式：storePlatform_手机号
                            String tokenKey = "store_" + storeUser.getPhone();
                            String existingToken = baseRedisService.getString(tokenKey);
                            if (existingToken != null) {
                                baseRedisService.delete(tokenKey);
                                log.info("清除角色编辑后的用户token成功，roleId={}, userId={}, phone={}, tokenKey={}", 
                                        role.getRoleId(), userId, storeUser.getPhone(), tokenKey);
                            } else {
                                log.warn("用户token不存在或已过期，roleId={}, userId={}, phone={}, tokenKey={}", 
                                        role.getRoleId(), userId, storeUser.getPhone(), tokenKey);
                            }
                        }
                    }
                } else {
                    log.info("该角色下没有关联用户，无需清除token，roleId={}", role.getRoleId());
                }
            } catch (Exception e) {
                log.error("清除角色编辑后的用户token失败，roleId={}, error={}", role.getRoleId(), e.getMessage(), e);
                // 不清除token不影响角色更新，只记录错误日志
            }
            log.info("成功更新角色权限，roleId={}, menuIds={}", role.getRoleId(), menuIds);
        }

        return true;
    }

    @Override
    public boolean deleteRole(Long roleId) {
        // 逻辑删除
        LambdaUpdateWrapper<StorePlatformRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StorePlatformRole::getRoleId, roleId);
        updateWrapper.set(StorePlatformRole::getDelFlag, "2"); // 2代表删除
        
        int result = storePlatformRoleMapper.update(null, updateWrapper);
        return result > 0;
    }

    @Override
    public String deleteRoleWithCheck(Long roleId) {
        if (roleId == null) {
            log.error("角色ID不能为空");
            return "角色ID不能为空";
        }

        // 查询角色信息，获取 storeId
        StorePlatformRole role = storePlatformRoleMapper.selectById(roleId);
        if (role == null) {
            log.error("角色不存在: roleId={}", roleId);
            return "角色不存在";
        }

        // 检查角色是否有关联的子账号
        List<Integer> userIds = storePlatformUserRoleService.getUserIdsByRoleId(roleId, role.getStoreId());
        if (userIds != null && !userIds.isEmpty()) {
            log.warn("角色有关联的子账号，不允许删除: roleId={}, 关联子账号数量={}", roleId, userIds.size());
            return "该角色下存在关联的子账号，不允许删除";
        }

        // 执行逻辑删除
        LambdaUpdateWrapper<StorePlatformRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StorePlatformRole::getRoleId, roleId);
        updateWrapper.set(StorePlatformRole::getDelFlag, "2"); // 2代表删除

        int result = storePlatformRoleMapper.update(null, updateWrapper);
        if (result > 0) {
            log.info("角色逻辑删除成功: roleId={}", roleId);
            return null; // 成功返回null
        } else {
            log.error("角色逻辑删除失败: roleId={}", roleId);
            return "删除失败";
        }
    }

    @Override
    public List<StorePlatformRole> getAllNormalRoles(Integer storeId) {
        LambdaQueryWrapper<StorePlatformRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRole::getStatus, "0"); // 正常状态
        queryWrapper.eq(StorePlatformRole::getDelFlag, "0"); // 未删除
        // 店铺ID查询
        if (storeId != null) {
            queryWrapper.eq(StorePlatformRole::getStoreId, storeId);
        }
        queryWrapper.orderByAsc(StorePlatformRole::getRoleSort);
        
        return storePlatformRoleMapper.selectList(queryWrapper);
    }

    @Override
    public IPage<StorePlatformRoleVo> getRolePageWithStats(int page, int size, Integer storeId, String roleName, String description, String status) {
        // 先查询角色分页数据
        IPage<StorePlatformRole> rolePage = getRolePage(page, size, storeId, roleName, description, status);
        
        // 转换为VO并填充统计信息
        IPage<StorePlatformRoleVo> voPage = new Page<>(rolePage.getCurrent(), rolePage.getSize(), rolePage.getTotal());
        List<StorePlatformRoleVo> voList = rolePage.getRecords().stream()
                .map(role -> {
                    StorePlatformRoleVo vo = new StorePlatformRoleVo();
                    BeanUtils.copyProperties(role, vo);
                    
                    // 统计关联子账号数量
                    List<Integer> userIds = storePlatformUserRoleService.getUserIdsByRoleId(role.getRoleId(),storeId);
                    vo.setSubAccountCount(userIds != null ? userIds.size() : 0);
                    
                    // 统计关联权限数量
                    List<Long> menuIds = storePlatformRoleMenuService.getMenuIdsByRoleId(role.getRoleId());
                    vo.setPermissionCount(menuIds != null ? menuIds.size() : 0);
                    
                    // 查询权限树形结构
//                    List<RolePermissionVo> permissions = storePlatformRoleMenuService.getRolePermissionTree(role.getRoleId());
//                    vo.setPermissions(permissions);
                    
                    return vo;
                })
                .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }
}

