package com.zt.plat.module.qms.resource.record.service.recordpermission;

import cn.hutool.core.collection.CollUtil;
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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxl.job.core.context.XxlJobHelper;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.enums.QmsPermissionConstant;
import com.zt.plat.module.qms.resource.record.constant.RecordConstants;
import com.zt.plat.module.qms.resource.record.controller.admin.recordpermission.vo.RecordPermissionPageReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordpermission.vo.RecordPermissionRespVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordpermission.vo.RecordPermissionSaveReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordrecord.vo.RecordJoinPermissionRespVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordrecord.vo.RecordRecordPageReqVO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordpermission.RecordPermissionDO;
import com.zt.plat.module.qms.resource.record.dal.mapper.RecordPermissionMapper;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
import com.zt.plat.module.system.api.permission.PermissionApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.BatchResult;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.RECORD_PERMISSION_NOT_EXISTS;

/**
 * 记录权限 Service 实现类
 *
 * @author 后台管理
 */
@Slf4j
@Service
@Validated
public class RecordPermissionServiceImpl implements RecordPermissionService {

    @Resource
    private RecordPermissionMapper recordPermissionMapper;

    @Resource
    private PermissionApi permissionApi;

    @Resource
    private PermissionCommonApi permissionCommonApi;

    @Resource
    private DeptApi deptApi;

//    private List<Long> deptIds = new ArrayList<>();
//
//    private Set<Long> roles = new HashSet<>();

    /**
     * 通过分类Id 获取满足当前用户的权限列表
     *
     * @param
     * @return
     */
    @Override
    public List<RecordPermissionDO> selectPermissionList(RecordPermissionDO permissionDO) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long userId = loginUser.getId();
        List<Long> deptIds = getParentDepts();
        Set<Long> roles = getRoles(userId);
        if (deptIds.isEmpty()) deptIds = new ArrayList<>();
        if (roles.isEmpty()) roles = new HashSet<>();
        permissionDO.setUserId(userId); // 当前用户ID
        permissionDO.setUserDeptIds(deptIds); // 当前用户部门ID
        permissionDO.setUserRoles(roles); // 当前用户部门ID
        // 查询用户是否有该分类的管理员权限
        return recordPermissionMapper.selectPermissionList(permissionDO);
    }

    //    检查用户是否有记录的权限,返回权限列表
    @Override
    public List<RecordPermissionDO> selectRecordPermissionList() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long userId = loginUser.getId();
        List<Long> deptIds = getParentDepts();
//        if (deptIds.isEmpty()) deptIds = new ArrayList<>();
//        // 查询用户是否有该分类的管理员权限
        RecordPermissionDO permissionDO = new RecordPermissionDO();
        String view = RecordConstants.PermissionType.VIEW;
        permissionDO.setPermission(view);
        String record = RecordConstants.PermissionSourceType.RECORD;
        permissionDO.setSourceType(record);
        permissionDO.setUserId(userId); // 当前用户ID
        permissionDO.setUserDeptIds(deptIds); // 当前用户部门ID
        return recordPermissionMapper.selectRecordPermissionList(permissionDO);
    }


    // 判断当前用户是否有管理员权限（用户，部门，角色）任意满足
    @Override
    public boolean hasAdminPermissionByCategoryId(Long categoryId) {

        // 获取用户所在的所有部门（包括父部门）
//        deptIds = getParentDepts();
        String admin = RecordConstants.PermissionType.ADMIN;
        RecordPermissionDO recordPermissionDO = new RecordPermissionDO();
        recordPermissionDO.setSourceId(categoryId);
        recordPermissionDO.setPermission(admin);
        List<RecordPermissionDO> recordCategoryDOS = this.selectPermissionList(recordPermissionDO);
        if (!recordCategoryDOS.isEmpty()) return true;
        return false;
    }

    /**
     * 通过分类Id 获取满足当前用户的权限列表
     *
     * @param categoryId 分类ID（对应 recordPermission.sourceId）
     * @return
     */
    @Override
    public List<RecordPermissionDO> getMatchedPermissionList(Long categoryId) {
        // 获取当前登录用户

        // 判断是最高管理员
        boolean b = judgeIsSuperAdmin();
        boolean adminByUserId = this.hasAdminPermissionByCategoryId(categoryId);
        if (b || adminByUserId) {
            // 用户是最高管理员，直接返回该分类下的所有权限记录
            RecordPermissionDO query = new RecordPermissionDO();
            query.setSourceId(categoryId);
            return this.selectAllListBySourceId(query);
        }

        // 直接查询满足条件的权限列表
//        return recordPermissionService.selectPermissionList(categoryId);
        return new ArrayList<>();

    }

    // 获取当前用户所在权限列表
    public Set<Long> getRoles(Long userId) {
//        if (!ObjectUtils.isEmpty(roles)) return roles;
        CommonResult<Set<Long>> userRoleIdListByUserId = permissionApi.getUserRoleIdListByUserId(userId);
        Set<Long> userRoles = userRoleIdListByUserId.getData();
//        Set<Long> roles = new HashSet<>();
//        roles.addAll(userRoles);
        return userRoles;
    }

    @Override
    public List<Long> getParentDepts() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long currentDeptId = loginUser.getVisitDeptId();
//        if (!ObjectUtils.isEmpty(deptIds)) return deptIds;
        //通过DeptApi获取完整部门信息（包括父部门）
        CommonResult<DeptRespDTO> deptResult = deptApi.getDept(currentDeptId);
        DeptRespDTO currentDept = deptResult.getData();
        Long parentDeptId = currentDept.getParentId();  // 获取父部门ID
//
        List<Long> deptIds = new ArrayList<>();
        // 添加当前部门到父部门列表中
        Long tempParentId = parentDeptId;
        int count = 0;
        while (tempParentId != null && tempParentId != 0) {
            CommonResult<DeptRespDTO> parentResult = deptApi.getDept(tempParentId);
            DeptRespDTO parentDept = parentResult.getData();
            deptIds.add(parentDept.getId());
            tempParentId = parentDept.getParentId();
            count++;
            if (count > 10) {
                break;
            }
        }
        deptIds.add(currentDept.getId());
        return deptIds;
    }

    @Override
    public boolean hasEditPermissionByUserId(Long categoryId) {
        String edit = RecordConstants.PermissionType.EDIT;
        RecordPermissionDO recordPermissionDO = new RecordPermissionDO();
        recordPermissionDO.setSourceId(categoryId);
        recordPermissionDO.setPermission(edit);
        List<RecordPermissionDO> recordCategoryDOS = this.selectPermissionList(recordPermissionDO);
        if (!recordCategoryDOS.isEmpty()) return true;
        return false;
    }


    // 判断当前用户是不是最高管理员
//    @QmsPermission(deptIdColumn="")
    @Override
    public boolean judgeIsSuperAdmin() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long userId = loginUser.getId();
        CommonResult<Boolean> booleanCommonResult = permissionCommonApi.hasAnyRoles(userId, QmsPermissionConstant.ADMIN_ROLE);
//        log.info("booleanCommonResult:{}", booleanCommonResult.getData());
        return booleanCommonResult.getData();
    }


    // 查询所有记录权限列表
    @Override
    public List<RecordPermissionDO> selectAllListBySourceId(RecordPermissionDO recordPermissionDO) {
        LambdaQueryWrapper<RecordPermissionDO> wrapper = Wrappers.lambdaQuery();
        if (!ObjectUtils.isEmpty(recordPermissionDO.getSourceId()))
            wrapper.eq(RecordPermissionDO::getSourceId, recordPermissionDO.getSourceId());
        return recordPermissionMapper.selectList(wrapper);
    }

    // 查询管理员-- 单条数据
//    @Override
//    public List<RecordPermissionDO> selectRecordPermission(RecordPermissionDO recordPermissionDO) {
//        LambdaQueryWrapper<RecordPermissionDO> queryWrapper = Wrappers.lambdaQuery();
//        queryWrapper.eq(RecordPermissionDO::getTargetId, recordPermissionDO.getTargetId());
//        queryWrapper.eq(RecordPermissionDO::getTargetType, recordPermissionDO.getTargetType());
//        queryWrapper.eq(RecordPermissionDO::getPermission, recordPermissionDO.getPermission());
//        if (!ObjectUtils.isEmpty(recordPermissionDO.getSourceId()))
//            queryWrapper.eq(RecordPermissionDO::getSourceId, recordPermissionDO.getSourceId());
//        if (!ObjectUtils.isEmpty(recordPermissionDO.getSourceType()))
//            queryWrapper.eq(RecordPermissionDO::getSourceType, recordPermissionDO.getSourceType());
//        return recordPermissionMapper.selectList(queryWrapper);
//    }

    @Override
    public int insertOrUpdateRecordPermissionBatch(List<RecordPermissionDO> permissionDOList) {
        List<BatchResult> batchResults = recordPermissionMapper.insertOrUpdate(permissionDOList);
        return batchResults.size();
    }

    @Override
    public List<RecordPermissionDO> selectList(LambdaQueryWrapper<RecordPermissionDO> lambdaQueryWrapper) {
        return recordPermissionMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public RecordPermissionRespVO createRecordPermission(RecordPermissionSaveReqVO createReqVO) {
        // 插入
        RecordPermissionDO recordPermission = BeanUtils.toBean(createReqVO, RecordPermissionDO.class);
        recordPermission.setCancelFlag("0");
        recordPermission.setExpirationStatus("0");
        recordPermissionMapper.insert(recordPermission);
        // 返回
        return BeanUtils.toBean(recordPermission, RecordPermissionRespVO.class);
    }

    @Override
    public Integer updatePermission(LambdaUpdateWrapper<RecordPermissionDO> updateWrapper) {
        return recordPermissionMapper.update(updateWrapper);
    }

    @Override
    public void updateRecordPermission(RecordPermissionSaveReqVO updateReqVO) {
        // 校验存在
        validateRecordPermissionExists(updateReqVO.getId());
        // 更新
        RecordPermissionDO updateObj = BeanUtils.toBean(updateReqVO, RecordPermissionDO.class);
        recordPermissionMapper.updateById(updateObj);
    }

    @Override
    public void deleteRecordPermission(Long id) {
        // 校验存在
        validateRecordPermissionExists(id);
        // 删除
        recordPermissionMapper.deleteById(id);
    }

    @Override
    public void deleteRecordPermissionListByIds(List<Long> ids) {
        // 校验存在
        validateRecordPermissionExists(ids);
        // 删除
        recordPermissionMapper.deleteByIds(ids);
    }

    private void validateRecordPermissionExists(List<Long> ids) {
        List<RecordPermissionDO> list = recordPermissionMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(RECORD_PERMISSION_NOT_EXISTS);
        }
    }

    private void validateRecordPermissionExists(Long id) {
        if (recordPermissionMapper.selectById(id) == null) {
            throw exception(RECORD_PERMISSION_NOT_EXISTS);
        }
    }

    @Override
    public RecordPermissionDO getRecordPermission(Long id) {
        return recordPermissionMapper.selectById(id);
    }

    @Override
    public PageResult<RecordPermissionDO> getRecordPermissionPage(RecordPermissionPageReqVO pageReqVO) {
        return recordPermissionMapper.selectPage(pageReqVO);
    }

    /**
     * 权限到期，定时回收权限
     * 检测 expireDate <= 当前时间 ，将其更新为已过期，且自动作废（expireStatus = 1）
     * <p>
     * JobHandler 名称: updateRecordStatusJob
     * 推荐 Cron: 0 0 0 * * ?（每天零点执行）
     */
    @Override
    public Integer withdrawPermissionJob() {
        log.info("[withdrawPermissionJob] 开始执行文件记录生效状态更新任务");
        try {
            Integer expireJob = expireDateExpireJob();
//            Integer saved = saveEndDateExpireJob();
            log.info("[withdrawPermissionJob] 任务执行成功，共更新 {} 条记录", expireJob);
            XxlJobHelper.handleSuccess(String.format("任务执行成功，共更新 %d 条记录", expireJob));
        } catch (Exception e) {
            log.error("[withdrawPermissionJob] 任务执行失败：{}", e.getMessage(), e);
            throw e;
        }
        return 0;
    }

    @Override
    public IPage<RecordJoinPermissionRespVO> selectRecordByPermission(RecordPermissionPageReqVO pageReqVO) {
        Page<RecordPermissionPageReqVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        String targetType = pageReqVO.getTargetType();
        Long targetId = pageReqVO.getTargetId();
        if (RecordConstants.TargetType.USER.equals(targetType)) pageReqVO.setUserId(targetId);
        else if (RecordConstants.TargetType.DEPT.equals(targetType)) {
            List<Long> deptId = new ArrayList<>();
            deptId.add(targetId);
            pageReqVO.setUserDeptIds(deptId);
        }
        pageReqVO.setSourceType(RecordConstants.PermissionSourceType.RECORD);
        return recordPermissionMapper.selectRecordByPermission(page, pageReqVO);
    }

    @Override
    public IPage<RecordJoinPermissionRespVO> selectPermissionByRecord(RecordRecordPageReqVO pageReqVO) {
        Page<RecordPermissionPageReqVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        return recordPermissionMapper.selectPermissionByRecord(page, pageReqVO);
    }

    @Override
    public boolean insertBatch(List<RecordPermissionDO> toInsert) {
        return recordPermissionMapper.insertBatch(toInsert);
    }

    @Override
    public boolean updateBatch(List<RecordPermissionDO> toUpdate) {
        return recordPermissionMapper.updateBatch(toUpdate);
    }

    //权限到期，定时回收权限
    public Integer expireDateExpireJob() {
        LambdaUpdateWrapper<RecordPermissionDO> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(RecordPermissionDO::getExpirationStatus, "0"); // 未过期
        updateWrapper.le(RecordPermissionDO::getExpirationDate, LocalDateTime.now()); // 过期时间小于当前时间
        updateWrapper.set(RecordPermissionDO::getExpirationStatus, "1");
        updateWrapper.set(RecordPermissionDO::getSaveFlag, "0"); // 回收没有需要保留的权限
        return recordPermissionMapper.update(updateWrapper);
    }

    //权限保留日期到期，定时回收权限
//    public Integer saveEndDateExpireJob() {
//        LambdaUpdateWrapper<RecordPermissionDO> updateWrapper = Wrappers.lambdaUpdate();
//        updateWrapper.eq(RecordPermissionDO::getSaveFlag, "1"); // 保留
//        updateWrapper.le(RecordPermissionDO::getSaveEndDate, LocalDateTime.now()); // 保留时间小于当前时间
//        updateWrapper.set(RecordPermissionDO::getSaveFlag, "0");
//        return recordPermissionMapper.update(updateWrapper);
//    }


}