package com.hzs.system.base.controller.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzs.common.core.annotation.AccessPermissions;
import com.hzs.common.core.constant.CacheConstants;
import com.hzs.common.core.constant.msg.AreaMsgConstants;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.domain.EnumEntity;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.system.base.BdArea;
import com.hzs.common.domain.system.base.ext.AreaCache;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.system.base.service.IBdAreaService;
import com.hzs.system.base.vo.BdAreaVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 行政区划 前端控制器
 */
@RestController
@RequestMapping("/manage/area")
public class BdAreaController extends BaseController {

    @Autowired
    private IBdAreaService areaService;
    @Autowired
    private RedisService redisService;

    /**
     * 查询所有的地区
     *
     * @return
     */
    @AccessPermissions("Division")
    @GetMapping("list")
    public TableDataInfo list(BdArea area) {
        LambdaQueryWrapper<BdArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(BdArea::getCode);
        queryWrapper.eq(BdArea::getPkCountry, SecurityUtils.getPkCountry());
        if (StringUtils.isBlank(area.getName()) && StringUtils.isBlank(area.getCode())) {
            queryWrapper.eq(BdArea::getParent, 0);
        }
        if (StringUtils.isNotBlank(area.getName())) {
            queryWrapper.eq(BdArea::getName, area.getName());
        }
        if (StringUtils.isNotBlank(area.getCode())) {
            queryWrapper.eq(BdArea::getCode, area.getCode());
        }
        startPage();
        List<BdArea> list = areaService.list(queryWrapper);
        List<BdAreaVo> resultList = new ArrayList<>();
        for (BdArea bdArea : list) {
            BdAreaVo bdAreaVo = BeanUtil.copyProperties(bdArea, BdAreaVo.class);
            LambdaQueryWrapper<BdArea> areaWrapper = new LambdaQueryWrapper<>();
            areaWrapper.eq(BdArea::getParent, bdAreaVo.getParent());
            int count = areaService.count(areaWrapper);
            bdAreaVo.setLevelCount(count);
            resultList.add(bdAreaVo);
        }
        TableDataInfo rspData = getDataTable(list);
        rspData.setRows(resultList);
        return rspData;
    }

    /**
     * 获取下级
     *
     * @param parent
     * @return
     */
    @GetMapping("get-level-list")
    public AjaxResult getLevelList(Integer parent) {
        List<BdArea> list = new ArrayList<>();
        if (parent == null) {
            return AjaxResult.success(list);
        }
        LambdaQueryWrapper<BdArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BdArea::getParent, parent);
        queryWrapper.eq(BdArea::getPkCountry, SecurityUtils.getPkCountry());
        queryWrapper.orderByAsc(BdArea::getPkId);
        list = areaService.list(queryWrapper);
        List<BdAreaVo> resultList = new ArrayList<>();
        for (BdArea bdArea : list) {
            BdAreaVo bdAreaVo = BeanUtil.copyProperties(bdArea, BdAreaVo.class);
            LambdaQueryWrapper<BdArea> areaWrapper = new LambdaQueryWrapper<>();
            areaWrapper.eq(BdArea::getParent, bdAreaVo.getPkId());
            int count = areaService.count(areaWrapper);
            bdAreaVo.setLevelCount(count);
            resultList.add(bdAreaVo);
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 查询全部数据
     *
     * @return
     */
    @GetMapping("find-all")
    public AjaxResult findAll(Integer pkCountry) {
        if (null == pkCountry) {
            pkCountry = SecurityUtils.getPkCountry();
        }

        List<AreaCache> list = areaService.getAreaList(pkCountry);
        List<Tree<String>> resultList = new ArrayList<>();
        TreeNodeConfig defaultConfig = TreeNodeConfig.DEFAULT_CONFIG;
        defaultConfig.setWeightKey("pkId");
        // 行政区划中不存国家信息了，此处直接从0开始取省
        List<Tree<String>> build = TreeUtil.build(list, "0", defaultConfig, (node, tree) -> {
            tree.setId(node.getPkId().toString());
            tree.setName(node.getName());
            tree.setParentId(node.getParent().toString());
            tree.putExtra("pkId", node.getPkId().toString());
            tree.putExtra("parent", node.getParent().toString());
        });
        if (build != null) {
            resultList.addAll(build);
        }

        return AjaxResult.success(resultList);
    }

    /**
     * 添加地区
     *
     * @param area
     * @return
     */
    @PostMapping("save")
    public AjaxResult save(@RequestBody BdArea area) {
        if (area.getParent() == null) {
            area.setParent(0);
        }
        // 名称不允许重复
        if (StringUtils.isBlank(area.getName())) {
            LambdaQueryWrapper<BdArea> qw = new LambdaQueryWrapper<>();
            qw.eq(BdArea::getName, area.getName());
            qw.eq(BdArea::getParent, area.getParent());
            qw.eq(BdArea::getPkCountry, SecurityUtils.getPkCountry());
            int count = areaService.count(qw);
            if (count > 0) {
                return AjaxResult.error(TransactionUtils.getContent(AreaMsgConstants.AREA_NAME_EXIST));
            }
        }
        area.setPkCountry(SecurityUtils.getPkCountry());
        area.setPkCreator(SecurityUtils.getUserId());
        area.setCreationTime(new Date());
        String redisKey = CacheConstants.BD_AREA + SecurityUtils.getPkCountry();
        redisService.deleteObject(redisKey);
        return toAjax(areaService.save(area));
    }


    /**
     * 修改地区
     *
     * @param area
     * @return
     */
    @PostMapping("update")
    public AjaxResult update(@RequestBody BdArea area) {
        if (areaService.getById(area.getPkId()) == null) {
            return AjaxResult.error(AreaMsgConstants.AREA_NOT_EXIST);
        }
        // 名称不允许重复
        if (StringUtils.isBlank(area.getName())) {
            LambdaQueryWrapper<BdArea> qw = new LambdaQueryWrapper<>();
            qw.eq(BdArea::getName, area.getName());
            qw.eq(BdArea::getParent, area.getParent());
            qw.eq(BdArea::getPkCountry, SecurityUtils.getPkCountry());
            qw.notIn(BdArea::getPkId, area.getPkId());
            int count = areaService.count(qw);
            if (count > 0) {
                return AjaxResult.error(TransactionUtils.getContent(AreaMsgConstants.AREA_NAME_EXIST));
            }
        }
        area.setPkModified(SecurityUtils.getUserId());
        area.setModifiedTime(new Date());
        String redisKey = CacheConstants.BD_AREA + SecurityUtils.getPkCountry();
        redisService.deleteObject(redisKey);
        return toAjax(areaService.updateById(area));
    }

    /**
     * 删除地区
     *
     * @param pkId
     * @return
     */
    @DeleteMapping("/{pkId}")
    public AjaxResult delete(@PathVariable Integer pkId) {
        areaService.removeById(pkId);
        String redisKey = CacheConstants.BD_AREA + SecurityUtils.getPkCountry();
        redisService.deleteObject(redisKey);
        return AjaxResult.success();
    }


    /**
     * 更新状态 启用状态（0=是,1=否）
     *
     * @param pkId
     * @param enable
     * @return
     */
    @PostMapping("/updateEnable/{pkId}/{enable}")
    public AjaxResult updateEnable(@PathVariable Integer pkId, @PathVariable Integer enable) {
        BdArea bdArea = new BdArea();
        bdArea.setPkId(pkId);
        bdArea.setEnableState(enable);
        areaService.updateById(bdArea);
        return AjaxResult.success();
    }

    /**
     * 查询树形图 省市区
     *
     * @return
     */
    @RequestMapping("/tree")
    public AjaxResult tree() {
        List<AreaCache> areaList = areaService.getAreaList(SecurityUtils.getPkCountry());
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setDeep(3);

        //0表示最顶层的id是0
        List<Tree<String>> build = TreeUtil.build(areaList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getPkId().toString());
                    tree.setParentId(treeNode.getParent().toString());
                    tree.setName(treeNode.getName());
                });
        return AjaxResult.success(build);
    }

    /**
     * 查询详情
     *
     * @param pkId
     * @return
     */
    @GetMapping("detail")
    public AjaxResult detail(Integer pkId) {
        return AjaxResult.success(areaService.getById(pkId));
    }

    /**
     * 导出列表
     *
     * @param area
     * @return
     */
    @PostMapping("/export")
    public void export(BdArea area, HttpServletResponse response) {
        LambdaQueryWrapper<BdArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(BdArea::getCode);
        queryWrapper.eq(BdArea::getPkCountry, SecurityUtils.getPkCountry());
        if (StringUtils.isBlank(area.getName()) && StringUtils.isBlank(area.getCode())) {
            queryWrapper.eq(BdArea::getParent, 0);
        }
        if (StringUtils.isNotBlank(area.getName())) {
            queryWrapper.eq(BdArea::getName, area.getName());
        }
        if (StringUtils.isNotBlank(area.getCode())) {
            queryWrapper.eq(BdArea::getCode, area.getCode());
        }
        startPage();
        List<BdArea> list = areaService.list(queryWrapper);
        List<BdAreaVo> resultList = new ArrayList<>();
        for (BdArea bdArea : list) {
            BdAreaVo bdAreaVo = BeanUtil.copyProperties(bdArea, BdAreaVo.class);
            LambdaQueryWrapper<BdArea> areaWrapper = new LambdaQueryWrapper<>();
            areaWrapper.eq(BdArea::getParent, bdAreaVo.getParent());
            int count = areaService.count(areaWrapper);
            bdAreaVo.setLevelCount(count);
            resultList.add(bdAreaVo);
        }
        ExcelUtil<BdAreaVo> util = new ExcelUtil<>(BdAreaVo.class);
        util.exportExcel(response, resultList, "行政区划导出");
    }

    /**
     * 查询地区名称
     *
     * @param pkIdList 地区ID列表
     * @return
     */
    @GetMapping("/query-name")
    public AjaxResult queryName(@RequestParam List<Integer> pkIdList) {
        // 返回数据
        List<EnumEntity> enumEntityList = new ArrayList<>();

        LambdaQueryWrapper<BdArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(BdArea::getPkId, pkIdList);
        List<BdArea> list = areaService.list(queryWrapper);
        for (BdArea bdArea : list) {
            enumEntityList.add(new EnumEntity(bdArea.getPkId(), bdArea.getName()));
        }

        return AjaxResult.success(enumEntityList);
    }


}
