/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 大恒泰山系统
 * 创建日期:2022/8/22
 */
package org.springblade.modules.baseinfo.region.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import org.springblade.constant.BusinessConstant;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.etl.entity.EtlAdCdEntity;
import org.springblade.etl.service.IEtlAdCdService;
import org.springblade.modules.baseinfo.org.entity.DeptRegionEntity;
import org.springblade.modules.baseinfo.org.service.IDeptRegionService;
import org.springblade.modules.baseinfo.region.dto.OrgRegionInfoDTO;
import org.springblade.modules.baseinfo.region.dto.RegionInfoDTO;
import org.springblade.modules.baseinfo.region.entity.OrgRegionInfoEntity;
import org.springblade.modules.baseinfo.region.entity.RegionInfoEntity;
import org.springblade.modules.baseinfo.region.entity.RegionTreeNodeEntity;
import org.springblade.modules.baseinfo.region.service.IBaseRegionService;
import org.springblade.modules.baseinfo.region.service.IOrgRegionService;
import org.springblade.modules.baseinfo.region.vo.RegionInfoVO;
import org.springblade.modules.baseinfo.region.wrapper.RegionInfoWrapper;
import org.springblade.modules.system.entity.Region;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IRegionService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;


/***
 * Date:2022/8/22
 * Title:行政区划管理
 * Description：对本文件的详细描述，原则上不能少于30字
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@RestController
@RequestMapping("galaxy-business/baseinfo/region")
@AllArgsConstructor
@Api(value = "行政区划管理", tags = "行政区划管理")
public class BaseRegionController extends BladeController {
    private final IBaseRegionService baseRegionService;
    private final IDeptService deptService;
    private final IRegionService regionService;
    private final IEtlAdCdService etlAdCdService;
    private final IOrgRegionService orgRegionService;
    private final IDeptRegionService deptRegionService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    @GetMapping("/children/list")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "分页")
    public R<List<RegionInfoEntity>> childrenList() {
        BladeUser user = AuthUtil.getUser();
        if (BusinessConstant.ROLE_SYS_ADMIN.equals(user.getRoleName())) {
            LambdaQueryWrapper<RegionInfoEntity> wrapper = Wrappers.<RegionInfoEntity>query().lambda();
            wrapper.eq(RegionInfoEntity::getIsDeleted, 0);
            wrapper.eq(RegionInfoEntity::getParentCode, BusinessConstant.REGION_NM_ADCODE);
            List<RegionInfoEntity> list = baseRegionService.list(wrapper);
            return R.data(list);
        } else if (BusinessConstant.ROLE_ORG_ADMIN.equals(user.getRoleName()) || BusinessConstant.ROLE_COMPANY_ADMIN.equals(user.getRoleName())) {
            LambdaQueryWrapper<DeptRegionEntity> deptRegionEntityLambdaQueryWrapper = Wrappers.<DeptRegionEntity>query().lambda();
            deptRegionEntityLambdaQueryWrapper.eq(DeptRegionEntity::getIsDeleted, 0);
            deptRegionEntityLambdaQueryWrapper.eq(DeptRegionEntity::getDeptId, Func.toLong(user.getDeptId()));
            DeptRegionEntity deptRegionEntity = deptRegionService.getOne(deptRegionEntityLambdaQueryWrapper);
            LambdaQueryWrapper<RegionInfoEntity> regionInfoEntityLambdaQueryWrapper = Wrappers.<RegionInfoEntity>query().lambda();
            regionInfoEntityLambdaQueryWrapper.eq(RegionInfoEntity::getIsDeleted, 0);
            regionInfoEntityLambdaQueryWrapper.eq(RegionInfoEntity::getParentCode, deptRegionEntity.getAdcd());
            List<RegionInfoEntity> list = baseRegionService.list(regionInfoEntityLambdaQueryWrapper);
            return R.data(list);
        }
        return R.data(null);
    }

    @GetMapping("/children/list/{parentCode}")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "分页")
    public R<List<RegionInfoEntity>> childrenList(@PathVariable(name = "parentCode") String parentCode) {
        LambdaQueryWrapper<RegionInfoEntity> wrapper = Wrappers.<RegionInfoEntity>query().lambda();
        wrapper.eq(RegionInfoEntity::getIsDeleted, 0);
        wrapper.eq(RegionInfoEntity::getParentCode, parentCode);
        List<RegionInfoEntity> list = baseRegionService.list(wrapper);
        return R.data(list);
    }

    @GetMapping("/lazy-tree")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentCode", value = "行政区划代码", paramType = "query", dataType = "string"),
    })
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "树")
    public R<List<RegionTreeNodeEntity>> lazyTree(@ApiIgnore RegionInfoDTO dto) {
        List<RegionTreeNodeEntity> nodeEntities = new LinkedList<>();
        BladeUser user = AuthUtil.getUser();
        if (dto.getParentCode() == null || dto.getParentCode().length() == 0) {
            LambdaQueryWrapper<DeptRegionEntity> wrapper = Wrappers.<DeptRegionEntity>query().lambda();
            wrapper.eq(DeptRegionEntity::getDeptId, Func.toLong(user.getDeptId()));
            DeptRegionEntity deptRegionEntity = this.deptRegionService.getOne(wrapper);
            if (null != deptRegionEntity) {
                dto.setAdcd(deptRegionEntity.getAdcd());
            }
            dto.setParentCode(null);
        }
        List<RegionInfoEntity> list = this.baseRegionService.selectList(dto);
        for (RegionInfoEntity entity : list) {
            RegionTreeNodeEntity nodeEntity = new RegionTreeNodeEntity();
            nodeEntity.setId(entity.getAdcd());
            nodeEntity.setValue(entity.getAdcd());
            if ("00".equals(entity.getAdcd())) {
                nodeEntity.setTitle("全国");
            } else {
                nodeEntity.setTitle(entity.getAdnm());
            }
            nodeEntity.setKey(entity.getAdcd());
            nodeEntity.setParentId(entity.getParentCode());
            dto.setAdcd(null);
            dto.setParentCode(entity.getAdcd());
            long count = this.baseRegionService.getCount(dto);
            if (count > 0) {
                nodeEntity.setHasChildren(true);
            } else {
                nodeEntity.setHasChildren(false);
            }
            nodeEntities.add(nodeEntity);
        }
        return R.data(nodeEntities);
    }

    @GetMapping("/tree")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "树")
    public R<List<RegionTreeNodeEntity>> regionTree() {
        BladeUser user = AuthUtil.getUser();
        List<RegionTreeNodeEntity> nodeEntities = new LinkedList<>();
        DeptRegionEntity deptRegionEntity = this.deptRegionService.getByDeptId(Func.toLong(user.getDeptId()));
        if (null != deptRegionEntity) {
            ValueOperations<String, String> opsHash = redisTemplate.opsForValue();
            String regionJson = opsHash.get("region.tree." + user.getDeptId());
            if (null != regionJson) {
                nodeEntities = JSON.parseObject(regionJson, new TypeReference<List<RegionTreeNodeEntity>>() {
                });
            } else {
                RegionInfoEntity root = this.baseRegionService.getByCode(deptRegionEntity.getAdcd());
                if (null != root) {
                    RegionTreeNodeEntity rootNode = new RegionTreeNodeEntity();
                    rootNode.setId(root.getAdcd());
                    rootNode.setValue(root.getAdcd());
                    rootNode.setTitle(root.getAdnm());
                    rootNode.setText(root.getAdnm());
                    rootNode.setKey(root.getAdcd());
                    rootNode.setParentId(root.getParentCode());
                    getChildren(rootNode, root);
                    if (rootNode.getChildren() != null && rootNode.getChildren().size() > 0) {
                        rootNode.setHasChildren(true);
                    } else {
                        rootNode.setHasChildren(false);
                    }
                    nodeEntities.add(rootNode);
                }
            }
        }
        return R.data(nodeEntities);
    }

    private boolean getChildren(RegionTreeNodeEntity nodeEntity, RegionInfoEntity regionInfoEntity) {
        RegionInfoDTO dto = new RegionInfoDTO();
        dto.setParentCode(regionInfoEntity.getAdcd());
        List<RegionInfoEntity> list = this.baseRegionService.selectList(dto);
        if (null != list && list.size() > 0) {
            List<RegionTreeNodeEntity> nodeEntities = new LinkedList<>();
            for (RegionInfoEntity entity : list) {
                RegionTreeNodeEntity node = new RegionTreeNodeEntity();
                node.setId(entity.getAdcd());
                node.setValue(entity.getAdcd());
                node.setTitle(entity.getAdnm());
                node.setText(entity.getAdnm());
                node.setKey(entity.getAdcd());
                node.setParentId(entity.getParentCode());
                getChildren(node, entity);
                if (node.getChildren() != null && node.getChildren().size() > 0) {
                    node.setHasChildren(true);
                } else {
                    node.setHasChildren(false);
                }
                nodeEntities.add(node);
            }
            nodeEntity.setChildren(nodeEntities);
        }
        return true;
    }


    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "详情", notes = "传入RegionInfoEntity")
    public R<RegionInfoVO> detail(RegionInfoDTO regionInfoDTO) {
//        if (regionInfoDTO.getAdcd()==null) {
//            regionInfoDTO.setAdcd(regionInfoDTO.getCode());
//        }
        if (regionInfoDTO.getDeptId() == null) {
            return R.fail("参数错误");
        }
        LambdaQueryWrapper<DeptRegionEntity> queryWrapper = Wrappers.<DeptRegionEntity>query().lambda();
        queryWrapper.eq(DeptRegionEntity::getDeptId, regionInfoDTO.getDeptId());
        DeptRegionEntity deptRegionEntity = this.deptRegionService.getOne(queryWrapper);
        if (null == deptRegionEntity) {
            return R.fail("无关联数据");
        }
        RegionInfoEntity detail = this.baseRegionService.getByCode(deptRegionEntity.getAdcd());

        detail.setAdcd(detail.getAdcd());
        detail.setAdnm(detail.getAdnm());

        return R.data(RegionInfoWrapper.build().entityVO(detail));
    }

    /**
     * 新增或修改
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入RegionInfoDTO")
    public R submit(@RequestBody RegionInfoDTO regionInfoDTO) {

//        OrgRegionInfoDTO dto = new OrgRegionInfoDTO();
////        dto.setDeptId(Func.toLong(regionInfoDTO.getDeptId()));
////        dto.setIsDeleted(0);
        //dto.setAdcd(regionInfoDTO.getCode());
        LambdaQueryWrapper<DeptRegionEntity> queryWrapper = Wrappers.<DeptRegionEntity>query().lambda();
        queryWrapper.eq(DeptRegionEntity::getDeptId, Func.toLong(regionInfoDTO.getDeptId()));

        DeptRegionEntity deptRegionEntity = this.deptRegionService.getOne(queryWrapper);
        if (null == deptRegionEntity) {
            deptRegionEntity = new DeptRegionEntity();
        }
        deptRegionEntity.setAdcd(regionInfoDTO.getCode());
        deptRegionEntity.setDeptId(Func.toLong(regionInfoDTO.getDeptId()));
        this.deptRegionService.saveOrUpdate(deptRegionEntity);

//        LambdaQueryWrapper<RegionInfoEntity> queryWrapper = Wrappers.<RegionInfoEntity>query().lambda();
//        queryWrapper.eq(RegionInfoEntity::getAdcd, regionInfoDTO.getCode());
//        queryWrapper.eq(RegionInfoEntity::getIsDeleted, 0);
//        RegionInfoEntity entity = baseRegionService.getOne(queryWrapper);
//        boolean status = false;
//        if (entity != null) {
//            entity.setAdcd(regionInfoDTO.getCode());
//            entity.setAdnm(regionInfoDTO.getName());
//            entity.setStatus(1);
//            entity.setIsDeleted(0);
//            status = baseRegionService.updateById(entity);
//        } else {
//            entity = new RegionInfoEntity();
//            entity.setAdcd(regionInfoDTO.getCode());
//            entity.setAdnm(regionInfoDTO.getName());
//            entity.setParentCode(regionInfoDTO.getParentCode());
//            entity.setStatus(1);
//            entity.setIsDeleted(0);
//            entity.setAncestors(regionInfoDTO.getAncestors() + "," + regionInfoDTO.getParentCode());
//            status = baseRegionService.save(entity);
//        }

        return R.status(true);
    }

    /**
     * 删除
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ID数组")
    public R remove(@ApiParam(value = "主键集合") @RequestParam String id) {
        LambdaUpdateWrapper<RegionInfoEntity> queryWrapper = Wrappers.<RegionInfoEntity>update().lambda();
        queryWrapper.eq(RegionInfoEntity::getAdcd, id);
        boolean temp = baseRegionService.remove(queryWrapper);
//		dataTaskManager.deptUpdateTask();
        return R.status(temp);
    }

    /**
     * 从宏图数据导入
     */
    @PostMapping("/import")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "regionLevel", value = "行政区划层级", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "isCovered", value = "是否覆盖", paramType = "query", dataType = "int"),
    })
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "导入", notes = "传入RegionInfoDTO")
    public R importSubmit(@RequestBody RegionInfoDTO regionInfoDTO) {
        if (regionInfoDTO.getIsCovered() == 1) {
            LambdaUpdateWrapper<RegionInfoEntity> updateWrapper = Wrappers.<RegionInfoEntity>update().lambda();
            updateWrapper.ne(RegionInfoEntity::getAdcd, "00");
            updateWrapper.eq(RegionInfoEntity::getIsDeleted, 0);
            baseRegionService.remove(updateWrapper);
        }
        List<EtlAdCdEntity> list = etlAdCdService.selectList("0");
        if (null != list && list.size() == 1) {
            String code = list.get(0).getAdcd();
            LambdaQueryWrapper<RegionInfoEntity> requestWrapper = Wrappers.<RegionInfoEntity>query().lambda();
            requestWrapper.eq(RegionInfoEntity::getAdcd, code);
            requestWrapper.eq(RegionInfoEntity::getIsDeleted, 0);
            RegionInfoEntity regionInfoEntity = baseRegionService.getOne(requestWrapper);
            if (null != regionInfoEntity) {
                regionInfoEntity.setAdnm(list.get(0).getAdnm());
                baseRegionService.updateById(regionInfoEntity);
            } else {
                regionInfoEntity = new RegionInfoEntity();
                regionInfoEntity.setAdcd(code);
                regionInfoEntity.setAdnm(list.get(0).getAdnm());
                regionInfoEntity.setParentCode("00");
                regionInfoEntity.setAncestors("00");
                regionInfoEntity.setStatus(1);
                regionInfoEntity.setIsDeleted(0);
                baseRegionService.save(regionInfoEntity);
            }
            importAdcd(regionInfoDTO.getRegionLevel(), 2, code, "00," + code);
        }
//		dataTaskManager.deptUpdateTask();
        return R.status(true);
    }

    private boolean importAdcd(int level, int currLevel, String parentCode, String ancestors) {
        if (currLevel > level) {
            return true;
        }
        List<EtlAdCdEntity> list = etlAdCdService.selectList(parentCode);
        if (null != list && list.size() > 0) {
            for (EtlAdCdEntity adCdEntity : list) {
                LambdaQueryWrapper<RegionInfoEntity> requestWrapper = Wrappers.<RegionInfoEntity>query().lambda();
                requestWrapper.eq(RegionInfoEntity::getAdcd, adCdEntity.getAdcd());
                requestWrapper.eq(RegionInfoEntity::getIsDeleted, 0);
                RegionInfoEntity regionInfoEntity = baseRegionService.getOne(requestWrapper);
                if (null != regionInfoEntity) {
                    regionInfoEntity.setAdnm(adCdEntity.getAdnm());
                    baseRegionService.updateById(regionInfoEntity);
                } else {
                    regionInfoEntity = new RegionInfoEntity();
                    regionInfoEntity.setAdcd(adCdEntity.getAdcd());
                    regionInfoEntity.setAdnm(adCdEntity.getAdnm());
                    regionInfoEntity.setParentCode(parentCode);
                    regionInfoEntity.setAncestors(ancestors);
                    regionInfoEntity.setStatus(1);
                    regionInfoEntity.setIsDeleted(0);
                    baseRegionService.save(regionInfoEntity);
                }
                importAdcd(level, currLevel + 1, adCdEntity.getAdcd(), ancestors + "," + adCdEntity.getAdcd());
            }
        }
        return true;
    }

}
