package com.zt.plat.module.qms.business.config.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigPermissionSaveReqVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigWarehouseLocationPageReqVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigWarehouseLocationRespVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigWarehouseLocationSaveReqVO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigPermissionDO;
import com.zt.plat.module.qms.enums.QmsPermissionConstant;
import com.zt.plat.module.qms.enums.QmsWarehouseLocationConstant;
import com.zt.plat.module.system.api.permission.PermissionApi;
import com.zt.plat.module.system.api.permission.RoleApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigWarehouseLocationDO;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;

import com.zt.plat.module.qms.business.config.dal.mapper.ConfigWarehouseLocationMapper;

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

/**
 * 存放位置 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class ConfigWarehouseLocationServiceImpl implements ConfigWarehouseLocationService {

    @Resource private ConfigPermissionService configPermissionService;

    @Resource
    private ConfigWarehouseLocationMapper configWarehouseLocationMapper;

    @Autowired
    private PermissionApi permissionApi;
    @Autowired
    private PermissionCommonApi permissionCommonApi;

    @Override
    public ConfigWarehouseLocationRespVO save(ConfigWarehouseLocationSaveReqVO reqVo) {
        Long id = reqVo.getId();
        //处理权限
        List<ConfigPermissionSaveReqVO> primissionList = reqVo.getPermissionList();
        ConfigWarehouseLocationDO entity = BeanUtils.toBean(reqVo, ConfigWarehouseLocationDO.class);
        if(id == null){
            checkCodeUniqueWithoutId(reqVo);
            configWarehouseLocationMapper.insert(entity);
            id = entity.getId();
            reqVo.setId( id);
        }else {
            checkCodeUnique(reqVo);
            configWarehouseLocationMapper.updateById(entity);
        }
        for(ConfigPermissionSaveReqVO permission : primissionList){
            permission.setSourceId( id);
            permission.setSourceType(QmsPermissionConstant.SAMPLE_WAREHOUSE_ADMIN);
        }
        configPermissionService.savePermissionListWithAutoDelete(primissionList, id, QmsPermissionConstant.SAMPLE_WAREHOUSE_ADMIN, null);
        return BeanUtils.toBean(reqVo, ConfigWarehouseLocationRespVO.class);
    }

    @Override
    public ConfigWarehouseLocationDO getLocationByCode(String code, String warehouseType) {
        LambdaQueryWrapper<ConfigWarehouseLocationDO> query = new LambdaQueryWrapper<>();
        query.eq(ConfigWarehouseLocationDO::getCode, code);
        if(!ObjectUtils.isEmpty(warehouseType))
            query.eq(ConfigWarehouseLocationDO::getWarehouseType, warehouseType);
        query.eq(ConfigWarehouseLocationDO::getDataType, QmsWarehouseLocationConstant.DATA_TYPE_LOCATION);
//        query.last("limit 1");
        List<ConfigWarehouseLocationDO> list = configWarehouseLocationMapper.selectList(query);
        if(list.size() > 1)
            throw exception(CONFIG_WAREHOUSE_LOCATION_CODE_DUPLICATE);
        if(list.isEmpty())
            return null;
        return list.get(0);
    }

    @Override
    public ConfigWarehouseLocationDO getByCode(String code) {
        LambdaQueryWrapper<ConfigWarehouseLocationDO> query = new LambdaQueryWrapper<>();
        query.eq(ConfigWarehouseLocationDO::getCode, code);
        List<ConfigWarehouseLocationDO> list = configWarehouseLocationMapper.selectList(query);
        if(list.size() > 1)
            throw exception(CONFIG_WAREHOUSE_LOCATION_CODE_DUPLICATE);
        if(list.isEmpty())
            return null;
        return list.get(0);
    }

    @Override
    public ConfigWarehouseLocationRespVO createConfigWarehouseLocation(ConfigWarehouseLocationSaveReqVO reqVo) {
        // 插入
        checkCodeUniqueWithoutId(reqVo);
        ConfigWarehouseLocationDO configWarehouseLocation = BeanUtils.toBean(reqVo, ConfigWarehouseLocationDO.class);
        configWarehouseLocationMapper.insert(configWarehouseLocation);
        // 返回
        return BeanUtils.toBean(configWarehouseLocation, ConfigWarehouseLocationRespVO.class);
    }

    @Override
    public void updateConfigWarehouseLocation(ConfigWarehouseLocationSaveReqVO reqVo) {
        // 校验存在
        validateConfigWarehouseLocationExists(reqVo.getId());
        checkCodeUnique(reqVo);
        // 更新
        ConfigWarehouseLocationDO updateObj = BeanUtils.toBean(reqVo, ConfigWarehouseLocationDO.class);
        configWarehouseLocationMapper.updateById(updateObj);
    }

    @Override
    public void checkCodeUnique(ConfigWarehouseLocationSaveReqVO reqVo) {
        String code = reqVo.getCode();
        if(ObjectUtils.isEmpty(code)){
            return;
        }
        ConfigWarehouseLocationDO dbData1 = getConfigWarehouseLocation(reqVo.getId());
        if(!code.equals(dbData1.getCode())){
            ConfigWarehouseLocationDO dbData = getByCode(code);
            if(dbData != null){
                throw exception(CONFIG_WAREHOUSE_LOCATION_CODE_DUPLICATE);
            }
        }
    }

    @Override
    public void checkCodeUniqueWithoutId(ConfigWarehouseLocationSaveReqVO reqVo) {
        String code = reqVo.getCode();
        if(ObjectUtils.isEmpty(code))
            return;
        ConfigWarehouseLocationDO dbData = getByCode(code);
        if(dbData != null){
            throw exception(CONFIG_WAREHOUSE_LOCATION_CODE_DUPLICATE);
        }
    }

    @Override
    public void deleteConfigWarehouseLocation(Long id) {
        // 校验存在
        validateConfigWarehouseLocationExists(id);
        // 删除
        configWarehouseLocationMapper.deleteById(id);
    }

    @Override
        public void deleteConfigWarehouseLocationListByIds(List<Long> ids) {
        // 校验存在
        validateConfigWarehouseLocationExists(ids);
        // 删除
        configWarehouseLocationMapper.deleteByIds(ids);
        }

    private void validateConfigWarehouseLocationExists(List<Long> ids) {
        List<ConfigWarehouseLocationDO> list = configWarehouseLocationMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(CONFIG_WAREHOUSE_LOCATION_NOT_EXISTS);
        }
    }

    private void validateConfigWarehouseLocationExists(Long id) {
        if (configWarehouseLocationMapper.selectById(id) == null) {
            throw exception(CONFIG_WAREHOUSE_LOCATION_NOT_EXISTS);
        }
    }

    @Override
    public ConfigWarehouseLocationDO getConfigWarehouseLocation(Long id) {
        return configWarehouseLocationMapper.selectById(id);
    }

    @Override
    public PageResult<ConfigWarehouseLocationRespVO> getConfigWarehouseLocationPage(ConfigWarehouseLocationPageReqVO pageReqVO) {
        // 获取当前用户角色
        CommonResult<Set<Long>> userRoleIdsRes = permissionApi.getUserRoleIdListByUserId(SecurityFrameworkUtils.getLoginUserId());
        Set<Long> userRoleIds = userRoleIdsRes.getData();
        pageReqVO.setRoleIds(userRoleIds);
        CommonResult<Boolean> hasAnyRoles = permissionCommonApi.hasAnyRoles(SecurityFrameworkUtils.getLoginUserId(), QmsPermissionConstant.ADMIN_ROLE);
        pageReqVO.setAdminFlag(hasAnyRoles.getData());
        if (CollUtil.isNotEmpty(userRoleIds)) {
            // 先查询有权限的仓库 ID 列表
            List<ConfigPermissionDO> permissionList = configPermissionService.getPermissionListByTargetIds(new ArrayList<>(userRoleIds));

            if (CollUtil.isNotEmpty(permissionList)) {
                // 使用 IN 条件查询库位（库位的 parentId 在有权限的仓库 ID 中）
                List<Long> authorizedWarehouseIds = permissionList.stream().map(ConfigPermissionDO::getSourceId).distinct().toList();
                pageReqVO.setAuthorizedWarehouseIds(authorizedWarehouseIds);
            }
        }
        return configWarehouseLocationMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ConfigWarehouseLocationDO> selectListWithPermission(ConfigWarehouseLocationPageReqVO pageReqVO) {
        return configWarehouseLocationMapper.selectListWithPermission(pageReqVO);
    }

    @Override
    public List<ConfigWarehouseLocationDO> getListByIds(List<Long> ids) {

        return configWarehouseLocationMapper.selectByIds(ids);
    }

    @Override
    public List<ConfigWarehouseLocationDO> getLocationsByWarehouseIds(List<Long> warehouseIds) {
        if (CollUtil.isEmpty(warehouseIds)) return Collections.emptyList();
        return configWarehouseLocationMapper.selectList(Wrappers.lambdaQuery(ConfigWarehouseLocationDO.class)
                .eq(ConfigWarehouseLocationDO::getDataType, QmsWarehouseLocationConstant.DATA_TYPE_LOCATION)
                .in(ConfigWarehouseLocationDO::getParentId, warehouseIds));
    }
}