package xiaoqu.home.open.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import xiaoqu.home.open.aop.AvoidRepeatSubmit;
import xiaoqu.home.open.controller.export.ObjectExport;
import xiaoqu.home.open.controller.input.grid.GridBatchAddInput;
import xiaoqu.home.open.controller.input.grid.GridReadFileModel;
import xiaoqu.home.open.controller.input.object.ObjectInsert;
import xiaoqu.home.open.controller.input.object.ObjectPageInput;
import xiaoqu.home.open.controller.input.object.ObjectReadFileModel;
import xiaoqu.home.open.controller.output.FileUploadOutput;
import xiaoqu.home.open.model.db1.Building;
import xiaoqu.home.open.model.db1.District;
import xiaoqu.home.open.model.db1.User;
import xiaoqu.home.open.model.db2.Object;
import xiaoqu.home.open.model.db2.ObjectType;
import xiaoqu.home.open.publicBean.BaseOutput;
import xiaoqu.home.open.publicBean.PageOutput;
import xiaoqu.home.open.service.RedisService4;
import xiaoqu.home.open.service.RedisService5;
import xiaoqu.home.open.service.db1.DistrictService;
import xiaoqu.home.open.service.db2.ObjectService;
import xiaoqu.home.open.service.db2.ObjectTypeService;
import xiaoqu.home.open.task.bean.DeleteEntityNotice;
import xiaoqu.home.open.task.bean.NameModifyNotice;
import xiaoqu.home.open.utils.DateToConverter;
import xiaoqu.home.open.utils.ResultResponseBeanUtil;
import xiaoqu.home.open.utils.UserUtils;
import xiaoqu.home.open.utils.WrapperUtils;
import xiaoqu.home.open.utils.poi.ExcelUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 */
@Api(value = "对象相关")
@Controller
@RequestMapping("/object")
@Slf4j
public class ObjectController {
    @Autowired
    ObjectService objectService;
    @Autowired
    ObjectTypeService objectTypeService;
    @Autowired
    DistrictService districtService;
    @Autowired
    RedisService5 redisService5;
    @Autowired
    RedisService4 redisService4;

    @ApiOperation(value = "对象分页查询")
    @ResponseBody
    @RequestMapping(value = "/objectPageList", method = RequestMethod.POST)
    public BaseOutput<PageOutput<Object>> objectPageList(HttpServletRequest request, @RequestBody ObjectPageInput input) {
        log.info("【objectPageList】input" + JSONObject.toJSONString(input));
        QueryWrapper<Object> wrapper = WrapperUtils.getWrapper(false);
        PageOutput<Object> output = new PageOutput<>();
        if(input.getTreeFlag()!=null&&input.getTreeFlag()==1){
            wrapper.and(wrapperq -> wrapperq.eq("name", input.getName()).or().eq("parent_name", input.getName()));
            input.setName(null);
        }
        input.setTreeFlag(null);
        WrapperUtils.beanToWrapper(wrapper, input);
        Page<Object> pageList = new Page<>(input.getPage(), input.getRows());
        List<Object> objectList = objectService.page(pageList, wrapper).getRecords();
        for (Object object:objectList) {
            if(object.getModifyId()==0){
                object.setModifyTime(null);
            }
        }
        output.setPage(pageList.getCurrent());
        output.setRecords(pageList.getTotal());
        output.setTotal(pageList.getPages());
        output.setRows(objectList);

        return ResultResponseBeanUtil.success(output);
    }


    @ApiOperation(value = "增加/修改对象信息")
    @ResponseBody
    @AvoidRepeatSubmit
    @RequestMapping(value = "/addOrUpdateObject", method = RequestMethod.POST)
    public BaseOutput<String> addOrUpdateObject(HttpServletRequest request, @RequestBody ObjectInsert input) {
//        User user = UserUtils.getUser(request);
//        log.info("【addOrUpdateObject】User:" +user.getName()+",参数："+ JSONObject.toJSONString(input));
        if (input.getDistrictId() == null || input.getDistrictId() == 0) {
            return ResultResponseBeanUtil.fail("请选择站点");
        }
        District district = districtService.getById(input.getDistrictId());

        if (input.getId() != null) {
            Object curObject = objectService.getById(input.getId());
            if (curObject == null) {
                return ResultResponseBeanUtil.fail("记录不存在,请确认");
            }
            NameModifyNotice nameModifyNotice = null;

            if (!curObject.getName().equals(input.getName())) {

                QueryWrapper<Object> wrapper = WrapperUtils.getWrapper(false);
                wrapper.eq("district_id", curObject.getDistrictId());
                wrapper.eq("name", input.getName());
                wrapper.eq("parent_id", curObject.getParentId());
                wrapper.eq("level", input.getLevel());
                int count = objectService.count(wrapper);
                if (count > 0) {
                    return ResultResponseBeanUtil.fail("记录已存在，请修改后再提交");
                }
                nameModifyNotice = new NameModifyNotice();

                nameModifyNotice.setId(curObject.getId());
                nameModifyNotice.setLevel(1);
                nameModifyNotice.setNewName(input.getName());
                nameModifyNotice.setOldName(curObject.getName());
                nameModifyNotice.setType(2);
                nameModifyNotice.setClassName("Object");
                // 更新名称
                curObject.setName(input.getName());
            }


            curObject.setStatus(input.getStatus());
            curObject.setMemo(input.getMemo()!=null?input.getMemo():"");
            curObject.setSort(input.getSort());
            objectService.updateById(curObject);
            //防止修改失败
            if (nameModifyNotice != null) {
                redisService4.lPush("NameModifyNotice", JSON.toJSONString(nameModifyNotice));
            }

            return ResultResponseBeanUtil.success("修改成功");

        } else {
            QueryWrapper<Object> wrapper = WrapperUtils.getWrapper(false);
            wrapper.eq("district_id", input.getDistrictId());
            wrapper.eq("name", input.getName());
            wrapper.eq("parent_id", input.getParentId()!=null?input.getParentId():0);
            wrapper.eq("level", input.getLevel());
            int count = objectService.count(wrapper);
            if (count > 0) {
                return ResultResponseBeanUtil.fail("记录已存在，请修改后再提交");
            }

            Object object = new Object();
            if (district == null) {
                return ResultResponseBeanUtil.fail("站点信息异常");
            }
            String agentName = redisService5.get("name:Agent:" + district.getAgentId());
            String propertyName = redisService5.get("name:Properyt:" + district.getPropertyId());
            Long objectTypeId = getObjectTypeId(input, district);
            object.setAgentId(district.getAgentId());
            object.setPropertyId(district.getPropertyId());
            object.setDistrictId(district.getId());
            object.setDistrictName(district.getDistrictName());
            object.setAgentName(agentName);
            object.setPropertyName(propertyName);
            object.setTypeId(objectTypeId);
            BeanUtils.copyProperties(input, object);
            if (input.getLevel() == 1) {
                object.setParentName("");
                object.setParentId(0L);
            }
            object.setId(null);
            objectService.save(object);
            return ResultResponseBeanUtil.success("添加成功");

        }


    }

    private Long getObjectTypeId(ObjectInsert input, District district) {
        QueryWrapper<ObjectType> wrapper = WrapperUtils.getWrapper(false);
        wrapper.eq("name", input.getParentName());
        wrapper.eq("district_id", district.getAgentId());
        wrapper.eq("property_id", district.getPropertyId());
        wrapper.eq("agent_id", district.getId());
        List<ObjectType> list = objectTypeService.list(wrapper);
        ObjectType objectType;
        if (list.isEmpty()) {
            objectType = new ObjectType();
            objectType.setAgentId(district.getAgentId());
            objectType.setPropertyId(district.getPropertyId());
            objectType.setDistrictId(district.getId());
            objectType.setName(input.getName());
            objectTypeService.save(objectType);
        } else {
            objectType = list.get(0);
        }
        return objectType.getId();
    }

    @ApiOperation(value = "删除对象信息")
    @ResponseBody
    @AvoidRepeatSubmit
    @RequestMapping(value = "/removeObject", method = RequestMethod.POST)
    public BaseOutput<String> removeObject(HttpServletRequest request, @RequestBody ObjectInsert input) {
//        User user = UserUtils.getUser(request);
//        log.info("【addOrUpdateObject】User:" +user.getName()+",参数："+ JSONObject.toJSONString(input));
        if (input.getId() != null) {
            Object curObject = objectService.getById(input.getId());
            if (curObject.getLevel() == 1) {
                QueryWrapper<Object> wrapper = WrapperUtils.getWrapper(false);
                wrapper.eq("parent_id", input.getId());
                int count = objectService.count(wrapper);
                if (count > 0) {
                    return ResultResponseBeanUtil.fail("存在下级，不能删除");

                }
            }
            if (curObject != null) {
                curObject.setSoftDelete(1);
                objectService.updateById(curObject);
                DeleteEntityNotice deleteEntityNotice = new DeleteEntityNotice();
                deleteEntityNotice.setId(curObject.getId());
                deleteEntityNotice.setLevel(1);
                deleteEntityNotice.setType(2);
                redisService4.lPush("DeleteEntityNotice", JSON.toJSONString(deleteEntityNotice));
            } else {
                return ResultResponseBeanUtil.fail("当前对象未找到");
            }
        }
        return ResultResponseBeanUtil.success("删除成功");

    }


    @ApiOperation(value = "对象记录导出")
    @PostMapping("/objectExport")
    public void objectExport(HttpServletRequest request, HttpServletResponse response, @RequestBody ObjectPageInput input) throws IOException {
        QueryWrapper<Object> wrapper = WrapperUtils.getWrapper(false);
//        User user = UserUtils.getUser(request);
//        log.info("【objectExport】user:" + user.getName() + ",参数：" + JSONObject.toJSONString(input));

//        Boolean aBoolean = authorityService.checkAuthorityIsagent(user.getAuthorityId());
//        wrapper = WrapperUtils.getByIsAgent(aBoolean, user.getAgentId(), wrapper);
        if(input.getTreeFlag()!=null&&input.getTreeFlag()==1){
            wrapper.and(wrapperq -> wrapperq.eq("name", input.getName()).or().eq("parent_name", input.getName()));
            input.setName(null);
        }
        input.setTreeFlag(null);

        WrapperUtils.beanToWrapper(wrapper, input);
        List<Object> objectList = objectService.list(wrapper);
        List<ObjectExport> newList = new ArrayList<>();
        ArrayList<String> strings = new ArrayList<>();

        String[] columns = new String[strings.size()];
        strings.toArray(columns);

//        String[] columns = (String[]) strings.toArray();
        for (Object object : objectList) {
            ObjectExport objectExport = new ObjectExport();
            BeanUtils.copyProperties(object, objectExport);


            if (object.getStatus() == 0) {
                objectExport.setStatusString("停用");
            } else if (object.getStatus() == 1) {
                objectExport.setStatusString("启用");
            }
            objectExport.setLevelString(object.getLevel() + "级");

            newList.add(objectExport);
        }
        String formattedDate = DateToConverter.getFormattedDate(new Date(), 10);
        ExcelUtil<ObjectExport> util = new ExcelUtil<>(ObjectExport.class);
        util.exportExcelByColumns(response, newList, "对象数据列表记录" + formattedDate, columns);
    }


    @ApiOperation(value = "上传对象导入文件", notes = "上传对象导入文件")
    @ResponseBody
    @RequestMapping(value = "/uploadFileObject", method = RequestMethod.POST)
    public BaseOutput<FileUploadOutput> uploadFileObject(@RequestParam(value = "file") MultipartFile file, HttpServletRequest request) throws Exception {
        // 将读取的文件内容放到redis里 uploadFileObject
        FileUploadOutput fileUploadOutput = new FileUploadOutput();
        String districtId = request.getParameter("districtId");
//        String districtId = "1";
        if (districtId == null) {
            return ResultResponseBeanUtil.fail("请上传站点ID");
        }
        String originalFilename = file.getOriginalFilename();
        if (originalFilename.indexOf("xlsx") > 0 || originalFilename.indexOf("xls") > 0 || originalFilename.indexOf("XLSX") > 0 || originalFilename.indexOf("XLS") > 0) {
            Long redisKey = System.currentTimeMillis();
            InputStream inputStream = file.getInputStream();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);// 从第三行读取
            List<ObjectReadFileModel> entities = ExcelImportUtil.importExcel(inputStream, ObjectReadFileModel.class, params);
            if (entities.size() > 0) {
                for (ObjectReadFileModel gridBatchInsertInput : entities) {
                    redisService4.lPush("ObjectFile:" + districtId + "_" + redisKey, com.alibaba.fastjson.JSON.toJSONString(gridBatchInsertInput));
                }
                fileUploadOutput.setFileId(redisKey);
                fileUploadOutput.setInfo("上传成功");
            } else {
                return ResultResponseBeanUtil.fail("上传的文件为空");
            }
        } else {
            return ResultResponseBeanUtil.fail("请上传excel文件，文件已.xlsx或.xls结尾");
        }
        return ResultResponseBeanUtil.success(fileUploadOutput);
    }

    @ApiOperation(value = "批量新增对象（开始导入）")
    @ResponseBody
    @AvoidRepeatSubmit
    @RequestMapping(value = "/batchAddObject", method = RequestMethod.POST)
    public BaseOutput<String> batchAddObject(HttpServletRequest request, @RequestBody GridBatchAddInput input) {
        Long fileId = input.getFileId();
        if (fileId == null) {
            return ResultResponseBeanUtil.fail("文件不存在或未上传成功");
        }
        Long districtId = input.getDistrictId();
        if (districtId == null || districtId == 0) {
            return ResultResponseBeanUtil.fail("请选择站点");
        }
        if (!redisService4.exists("ObjectFile:" + districtId + "_" + fileId)) {
            return ResultResponseBeanUtil.fail("文件不存在或未上传成功");
        }
        District district = districtService.getById(districtId);
        List<String> objectString = redisService4.lRangeAll("ObjectFile:" + districtId + "_" + fileId);
        List<String> memoList = new ArrayList<String>();
        User user = UserUtils.getUser(request);
        String agentName = redisService5.get("name:Agent:" + district.getAgentId());
        String propertyName = redisService5.get("name:Properyt:" + district.getPropertyId());
//		3条 错误记录，网格名称1,网格名称2,网格名称3
        StringBuilder stringBuilder = new StringBuilder();
        for (String objectJson : objectString) {
            ObjectReadFileModel objectReadFileModel = JSON.parseObject(objectJson, ObjectReadFileModel.class);
//			网格名称（必填）	网格级别（必选）	上级网格（非必填）	备注
//			A座					1级							没事
//			F1					2级				A座			没事
            if (objectReadFileModel.getName() == null) {
                memoList.add("对象名称为空");

                continue;
            }
            //对象重复性校验
            QueryWrapper<Object> checkwrapper = WrapperUtils.getWrapper(false);
            checkwrapper.eq("name", objectReadFileModel.getName());
            checkwrapper.eq("district_id", district.getId());

            // 级别
            String gridLevelString = objectReadFileModel.getLevel();
            if (gridLevelString == null) {
                memoList.add(objectReadFileModel.getName() + "->没有选择对象级别");
                continue;
            }
            if (!gridLevelString.endsWith("级")) {
                memoList.add(objectReadFileModel.getName() + "->对象级别填写有误");
                continue;
            }
            Integer objectLevel = null;
            try {
                objectLevel = Integer.parseInt(gridLevelString.split("级")[0]);
                if (objectLevel > 4) {// 不要大于4级
                    memoList.add(objectReadFileModel.getName() + "->对象级别填写有误");
                    continue;
                }

                String superiorName = objectReadFileModel.getParentName();
                if (objectLevel == 1) {
                    if (superiorName != null) {
                        memoList.add(objectReadFileModel.getName() + "->一级对象不能有上级对象");
                        continue;
                    }
                }
                if (objectLevel > 1) {
                    if (superiorName == null) {
                        memoList.add(objectReadFileModel.getName() + "->请填写上级对象");
                        continue;
                    }
                    QueryWrapper<Object> parentwrapper = WrapperUtils.getWrapper(false);
                    parentwrapper.eq("name", superiorName);
                    parentwrapper.eq("district_id", district.getId());
                    Object parent = objectService.getOne(parentwrapper);
                    if (parent == null) {
                        memoList.add(objectReadFileModel.getName() + "->上级对象未找到");
                        continue;
                    }
                    checkwrapper.eq("parent_id", parent.getId());

                }


                if (objectLevel==1){
                    checkwrapper.eq("parent_id", 0);
                }
                Integer curObject = objectService.count(checkwrapper);
                if (curObject > 0) {
                    //重复的不处理
//                memoList.add(objectReadFileModel.getName() + "->对象名称已存在");
                    continue;
                }


            } catch (Exception e) {
                e.printStackTrace();
            }


            Object object = new Object();
            object.setAgentId(district.getAgentId());
            object.setAgentName(agentName);
            object.setPropertyId(district.getPropertyId());
            object.setPropertyName(propertyName);
            object.setDistrictId(district.getId());
            object.setDistrictName(district.getDistrictName());
            object.setLevel(objectLevel);
            object.setName(objectReadFileModel.getName());
            if(objectLevel==2){
                QueryWrapper<Object> parentwrapper = WrapperUtils.getWrapper(false);
                parentwrapper.eq("name", objectReadFileModel.getParentName());
                parentwrapper.eq("level", 1);
                parentwrapper.eq("district_id", district.getId());
                List<Object> list = objectService.list(parentwrapper);
                if(list.size()>0){
                    Long id = list.get(0).getId();
                    object.setParentId(id);
                }else {
                    stringBuilder.append("1");
                }
            }
            object.setParentName(objectReadFileModel.getParentName());
            object.setStatus(1);
            object.setMemo(objectReadFileModel.getMemo());
            objectService.save(object);
        }
        if (memoList.size() > 0) {
            String memo = memoList.stream().map(me -> me).collect(Collectors.joining(";"));
            return ResultResponseBeanUtil.fail(memo);
        } else {
            if(stringBuilder.length()>0){
                return ResultResponseBeanUtil.success("添加成功,上级映射未找到");

            }else {
                return ResultResponseBeanUtil.success("添加成功");

            }
        }

    }

}
