package org.xyzh.system.service.impl;

import jakarta.annotation.Resource;
import java.util.Date;
import java.util.List;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xyzh.api.system.service.AclService;
import org.xyzh.api.system.vo.AclVO;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.sys.TbSysAclDTO;
import org.xyzh.common.dto.sys.TbSysAclPolicyDTO;
import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.common.utils.StringUtils;
import org.xyzh.system.mapper.acl.TbSysAclMapper;
import org.xyzh.system.mapper.acl.TbSysAclPolicyMapper;

/**
 * @description    访问控制列表服务实现类
 * @filename    AclServiceImpl.java
 * @author    yslg
 * @copyright yslg
 * @since 2025-12-05
 */
@DubboService(
    version = "1.0.0",
    group = "system",
    timeout = 3000,
    retries = 0
)
public class AclServiceImpl implements AclService {

    private static final Logger logger = LoggerFactory.getLogger(AclServiceImpl.class);
    private static final String MSG_ACL_PARAM_REQUIRED = "访问控制列表参数不能为空";
    private static final String MSG_ACL_ID_REQUIRED = "访问控制列表ID不能为空";
    private static final String MSG_POLICY_PARAM_REQUIRED = "访问控制策略参数不能为空";
    private static final String MSG_POLICY_ID_REQUIRED = "访问控制策略ID不能为空";
    private static final String MSG_PAGE_PARAM_REQUIRED = "分页参数不能为空";

    @Resource
    private TbSysAclMapper aclMapper;

    @Resource
    private TbSysAclPolicyMapper aclPolicyMapper;

    // ================= ACL 管理 =================
    @Override
    public ResultDomain<TbSysAclDTO> insertAcl(TbSysAclDTO aclDTO) {
        if (aclDTO == null) {
            return ResultDomain.failure(MSG_ACL_PARAM_REQUIRED);
        }
        if (StringUtils.isBlank(aclDTO.getAclId())) {
            aclDTO.setAclId(IdUtil.generateID());
        }
        if (aclDTO.getCreateTime() == null) {
            aclDTO.setCreateTime(new Date());
        }
        if (aclDTO.getDeleted() == null) {
            aclDTO.setDeleted(false);
        }
        if (aclDTO.getAllow() == null) {
            aclDTO.setAllow(true);
        }
        if (aclDTO.getIncludeDescendants() == null) {
            aclDTO.setIncludeDescendants(false);
        }
        
        int rows = aclMapper.insertAcl(aclDTO);
        if (rows > 0) {
            logger.info("新增访问控制列表成功, aclId={}", aclDTO.getAclId());
            return ResultDomain.success("新增访问控制列表成功", aclDTO);
        }
        logger.warn("新增访问控制列表失败, aclId={}", aclDTO.getAclId());
        return ResultDomain.failure("新增访问控制列表失败");
    }

    @Override
    public ResultDomain<TbSysAclDTO> updateAcl(TbSysAclDTO aclDTO) {
        if (aclDTO == null || StringUtils.isBlank(aclDTO.getAclId())) {
            return ResultDomain.failure(MSG_ACL_ID_REQUIRED);
        }
        aclDTO.setUpdateTime(new Date());
        
        int rows = aclMapper.updateAcl(aclDTO);
        if (rows > 0) {
            logger.info("更新访问控制列表成功, aclId={}", aclDTO.getAclId());
            return ResultDomain.success("更新访问控制列表成功", aclDTO);
        }
        logger.warn("更新访问控制列表失败, aclId={}", aclDTO.getAclId());
        return ResultDomain.failure("更新访问控制列表失败");
    }

    @Override
    public ResultDomain<Boolean> deleteAcl(TbSysAclDTO aclDTO) {
        if (aclDTO == null || StringUtils.isBlank(aclDTO.getAclId())) {
            return ResultDomain.failure(MSG_ACL_ID_REQUIRED);
        }
        aclDTO.setDeleteTime(new Date());
        
        int rows = aclMapper.deleteAcl(aclDTO);
        if (rows > 0) {
            logger.info("删除访问控制列表成功, aclId={}", aclDTO.getAclId());
            return ResultDomain.success("删除访问控制列表成功", true);
        }
        logger.warn("删除访问控制列表失败, aclId={}", aclDTO.getAclId());
        return ResultDomain.failure("删除访问控制列表失败");
    }

    @Override
    public ResultDomain<AclVO> getAclPage(PageRequest<AclVO> pageRequest) {
        if (pageRequest == null) {
            return ResultDomain.failure(MSG_PAGE_PARAM_REQUIRED);
        }

        AclVO filter = pageRequest.getFilter();
        if (filter == null) {
            filter = new AclVO();
        }

        // 转换为 DTO
        TbSysAclDTO aclDTO = new TbSysAclDTO();
        aclDTO.setAclId(filter.getAclId());
        aclDTO.setObjectType(filter.getObjectType());
        aclDTO.setObjectId(filter.getObjectId());
        aclDTO.setPrincipalType(filter.getPrincipalType());
        aclDTO.setPrincipalId(filter.getPrincipalId());
        aclDTO.setPrincipalDeptId(filter.getPrincipalDeptId());

        // 获取总数
        int total = aclMapper.getAclCount(aclDTO);

        // 分页查询
        PageParam pageParam = pageRequest.getPageParam();
        List<AclVO> list = aclMapper.getAclPageByFilter(aclDTO, pageParam);

        pageParam.setTotal(total);
        PageDomain<AclVO> pageDomain = new PageDomain<>(pageParam, list);
        return ResultDomain.success("查询成功", pageDomain);
    }

    @Override
    public ResultDomain<AclVO> getAclList(AclVO filter) {
        if (filter == null) {
            filter = new AclVO();
        }

        // 转换为 DTO
        TbSysAclDTO aclDTO = new TbSysAclDTO();
        aclDTO.setAclId(filter.getAclId());
        aclDTO.setObjectType(filter.getObjectType());
        aclDTO.setObjectId(filter.getObjectId());
        aclDTO.setPrincipalType(filter.getPrincipalType());
        aclDTO.setPrincipalId(filter.getPrincipalId());
        aclDTO.setPrincipalDeptId(filter.getPrincipalDeptId());

        List<AclVO> list = aclMapper.getAclByFilter(aclDTO);
        return ResultDomain.success("查询成功", list);
    }

    @Override
    public ResultDomain<AclVO> getAclByObjectId(String objectId) {
        if (StringUtils.isBlank(objectId)) {
            return ResultDomain.failure("对象ID不能为空");
        }

        List<AclVO> list = aclMapper.getAclByObjectId(objectId);
        return ResultDomain.success("查询成功", list);
    }

    // ================= ACL Policy 管理 =================
    @Override
    public ResultDomain<TbSysAclPolicyDTO> insertAclPolicy(TbSysAclPolicyDTO aclPolicyDTO) {
        if (aclPolicyDTO == null) {
            return ResultDomain.failure(MSG_POLICY_PARAM_REQUIRED);
        }
        if (StringUtils.isBlank(aclPolicyDTO.getPolicyId())) {
            aclPolicyDTO.setPolicyId(IdUtil.generateID());
        }
        if (aclPolicyDTO.getCreateTime() == null) {
            aclPolicyDTO.setCreateTime(new Date());
        }
        if (aclPolicyDTO.getDeleted() == null) {
            aclPolicyDTO.setDeleted(false);
        }
        if (aclPolicyDTO.getDefaultAllow() == null) {
            aclPolicyDTO.setDefaultAllow(true);
        }
        if (aclPolicyDTO.getApplyToChildren() == null) {
            aclPolicyDTO.setApplyToChildren(true);
        }
        
        int rows = aclPolicyMapper.insertAclPolicy(aclPolicyDTO);
        if (rows > 0) {
            logger.info("新增访问控制策略成功, policyId={}", aclPolicyDTO.getPolicyId());
            return ResultDomain.success("新增访问控制策略成功", aclPolicyDTO);
        }
        logger.warn("新增访问控制策略失败, policyId={}", aclPolicyDTO.getPolicyId());
        return ResultDomain.failure("新增访问控制策略失败");
    }

    @Override
    public ResultDomain<TbSysAclPolicyDTO> updateAclPolicy(TbSysAclPolicyDTO aclPolicyDTO) {
        if (aclPolicyDTO == null || StringUtils.isBlank(aclPolicyDTO.getPolicyId())) {
            return ResultDomain.failure(MSG_POLICY_ID_REQUIRED);
        }
        aclPolicyDTO.setUpdateTime(new Date());
        
        int rows = aclPolicyMapper.updateAclPolicy(aclPolicyDTO);
        if (rows > 0) {
            logger.info("更新访问控制策略成功, policyId={}", aclPolicyDTO.getPolicyId());
            return ResultDomain.success("更新访问控制策略成功", aclPolicyDTO);
        }
        logger.warn("更新访问控制策略失败, policyId={}", aclPolicyDTO.getPolicyId());
        return ResultDomain.failure("更新访问控制策略失败");
    }

    @Override
    public ResultDomain<Boolean> deleteAclPolicy(TbSysAclPolicyDTO aclPolicyDTO) {
        if (aclPolicyDTO == null || StringUtils.isBlank(aclPolicyDTO.getPolicyId())) {
            return ResultDomain.failure(MSG_POLICY_ID_REQUIRED);
        }
        aclPolicyDTO.setDeleteTime(new Date());
        
        int rows = aclPolicyMapper.deleteAclPolicy(aclPolicyDTO);
        if (rows > 0) {
            logger.info("删除访问控制策略成功, policyId={}", aclPolicyDTO.getPolicyId());
            return ResultDomain.success("删除访问控制策略成功", true);
        }
        logger.warn("删除访问控制策略失败, policyId={}", aclPolicyDTO.getPolicyId());
        return ResultDomain.failure("删除访问控制策略失败");
    }

    @Override
    public ResultDomain<AclVO> getAclPolicyPage(PageRequest<AclVO> pageRequest) {
        if (pageRequest == null) {
            return ResultDomain.failure(MSG_PAGE_PARAM_REQUIRED);
        }

        AclVO filter = pageRequest.getFilter();
        if (filter == null) {
            filter = new AclVO();
        }

        // 转换为 DTO
        TbSysAclPolicyDTO aclPolicyDTO = new TbSysAclPolicyDTO();
        aclPolicyDTO.setPolicyId(filter.getPolicyId());
        aclPolicyDTO.setName(filter.getPolicyName());
        aclPolicyDTO.setObjectType(filter.getPolicyObjectType());

        // 获取总数
        int total = aclPolicyMapper.getAclPolicyCount(aclPolicyDTO);

        // 分页查询
        PageParam pageParam = pageRequest.getPageParam();
        List<AclVO> list = aclPolicyMapper.getAclPolicyPageByFilter(aclPolicyDTO, pageParam);

        pageParam.setTotal(total);
        PageDomain<AclVO> pageDomain = new PageDomain<>(pageParam, list);
        return ResultDomain.success("查询成功", pageDomain);
    }

    @Override
    public ResultDomain<AclVO> getAclPolicyList(AclVO filter) {
        if (filter == null) {
            filter = new AclVO();
        }

        // 转换为 DTO
        TbSysAclPolicyDTO aclPolicyDTO = new TbSysAclPolicyDTO();
        aclPolicyDTO.setPolicyId(filter.getPolicyId());
        aclPolicyDTO.setName(filter.getPolicyName());
        aclPolicyDTO.setObjectType(filter.getPolicyObjectType());

        List<AclVO> list = aclPolicyMapper.getAclPolicyByFilter(aclPolicyDTO);
        return ResultDomain.success("查询成功", list);
    }
}
