package com.tofly.xrtygis.custom.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.xrtygis.commons.Constant;
import com.tofly.xrtygis.custom.entity.dto.TablelinkUserDto;
import com.tofly.xrtygis.custom.entity.dto.TablelinkpipeDto;
import com.tofly.xrtygis.custom.service.TheOnlineCheckService;
import com.tofly.xrtygis.em.ExcelExportFileTypeEnum;
import com.tofly.xrtygis.entity.DmaWater;
import com.tofly.xrtygis.entity.Dmaregion;
import com.tofly.xrtygis.entity.Watermeter;
import com.tofly.xrtygis.entity.vo.ChargeDetailInfoVo;
import com.tofly.xrtygis.entity.vo.ChargeUserInfoVo;
import com.tofly.xrtygis.entity.vo.ResultUserWaterMeterInfoVo;
import com.tofly.xrtygis.entity.vo.UserWaterMeterInfoVo;
import com.tofly.xrtygis.service.DmaWaterService;
import com.tofly.xrtygis.service.DmaregionService;
import com.tofly.xrtygis.service.WatermeterService;
import com.tofly.xrtygis.util.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 综合展示-线上核对
 *
 * @author 泡泡
 */
@RestController
@RequestMapping("/onlineCheck")
@AllArgsConstructor
@Api(tags = "综合展示-线上核对")
public class TheOnlineCheckController {

    private final TheOnlineCheckService theOnlineCheckService;
    private final WatermeterService watermeterService;
    private final DmaregionService dmaregionService;
    private final DmaWaterService dmaWaterService;

    @PostMapping("/bindLine")
    @ApiOperation("总表绑定管线")
    public ResultRespone bindLine(@RequestBody TablelinkpipeDto dto) {
        return ResultRespone.success(theOnlineCheckService.bindLine(dto));
    }

    @PostMapping("/saveTable")
    @ApiOperation("新增水表信息采集数据表")
    public ResultRespone saveTable(@RequestBody Watermeter dto) {
        return ResultRespone.success(watermeterService.save(dto));
    }

    @PostMapping("/updateTable")
    @ApiOperation("通过ID修改水表信息采集数据表")
    public ResultRespone updateTable(@RequestBody Watermeter dto) {
        return ResultRespone.success(watermeterService.updateById(dto));
    }

    @PostMapping("/tableDmaBind")
    @ApiOperation("总表绑定/解除Dma分区")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableIds", value = "总表id列表,多个以,分隔", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "dmaId", value = "分区id", required = true, dataType = "Long")
    })
    public ResultRespone tableDmaBind(String tableIds, Long dmaId) {
        Dmaregion dmaregion = dmaregionService.getOne(new QueryWrapper<Dmaregion>().lambda().eq(Dmaregion::getId,dmaId));
        if(dmaregion.getPartitionLevel() == null || dmaregion.getPartitionLevel() == 0){
            throw new ToflyDeniedException("此分区的分区级别为空或为0");
        }
        Integer dmaLevel = dmaregion.getPartitionLevel();
        List<Long> tableIdList = Arrays.stream(tableIds.split(Constant.CSV)).map(s -> Long.parseLong(s.trim())).distinct().collect(Collectors.toList());
        //判断总表是否在同一分区级别已经绑定其他分区
        tableIdList.forEach(info -> {
            List<Integer> dmaLevelList = theOnlineCheckService.getDmaLevelListByTableId(info,dmaId);
            if(dmaLevelList != null && dmaLevelList.size() != 0){
                for (Integer one : dmaLevelList) {
                    if(one.equals(dmaLevel)){
                        Watermeter watermeter = watermeterService.getOne(new QueryWrapper<Watermeter>().lambda().eq(Watermeter::getId,info));
                        throw new ToflyDeniedException("编号为" + watermeter.getSid() + "的总表在同一分区级别下已绑定其他分区");
                    }
                }
            }
        });
        //解绑
        dmaWaterService.remove(new QueryWrapper<DmaWater>().lambda().eq(DmaWater::getDmaId, dmaId));
        //绑定总表
        tableIdList.forEach(info -> {
            DmaWater dmaWater = new DmaWater();
            dmaWater.setDmaId(dmaId);
            dmaWater.setWaterMeterId(info);
            dmaWaterService.save(dmaWater);
        });
        return ResultRespone.success();
    }

    @GetMapping("/getTableDmaBindList")
    @ApiOperation("查询总表关联/未关联Dma分区信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dmaId", value = "分区id,查询已绑定信息传入", required = false, dataType = "Long"),
            @ApiImplicitParam(name = "flag", value = "flag为1则为查询已绑定总表信息,0查询未绑定信息", required = false, dataType = "String")
    })
    public ResultRespone tableDmaNotBindList(Long dmaId, String flag) {
        Set<Long> collect = new HashSet<>();
        List<Watermeter> list = new ArrayList<>();
        if (null != dmaId) {
            collect = dmaWaterService.list(new QueryWrapper<DmaWater>().lambda().eq(DmaWater::getDmaId, dmaId)).stream().map(DmaWater::getWaterMeterId).collect(Collectors.toSet());
        }
        if ("1".equals(flag)) {
            if (collect.size() > 0) {
                list = watermeterService.list(new QueryWrapper<Watermeter>().lambda().in(Watermeter::getId, collect).eq(Watermeter::getIssum, 1L).orderByDesc(Watermeter::getCreateTime));
            }
        } else {
            if (collect.size() > 0) {
                list = watermeterService.list(new QueryWrapper<Watermeter>().lambda().notIn(Watermeter::getId, collect).eq(Watermeter::getIssum, 1L).orderByDesc(Watermeter::getCreateTime));
            } else {
                list = watermeterService.list(new QueryWrapper<Watermeter>().lambda().eq(Watermeter::getIssum, 1L).orderByDesc(Watermeter::getCreateTime));
            }
        }
        return ResultRespone.success(list);
    }

    @GetMapping("/getTableDmaUserBindList")
    @ApiOperation("查询总表用户的DMA分区绑定列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dmaId", value = "分区id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "inputcontent", value = "模糊查询字段", dataType = "String"),
            @ApiImplicitParam(name = "tableLikeStr", value = "总表地址和编码模糊查询", dataType = "String"),
            @ApiImplicitParam(name = "export", value = "是否导出 1导出", required = false, dataType = "String")
    })
    public ResultRespone getTableDmaUserBindList(HttpServletResponse response,String export, Page page, Long dmaId, String inputcontent, String tableLikeStr) {
        // 判断是否导出
        if(!"1".equals(export)){
            return ResultRespone.success(theOnlineCheckService.getTableDmaUserBindList(page, dmaId, inputcontent, tableLikeStr));
        }else {
            List<ResultUserWaterMeterInfoVo> tableDmaUserBindList = theOnlineCheckService.getTableDmaUserBindList(dmaId, inputcontent,tableLikeStr);
            ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.EXPORT_TABLE_DMA_USER_BIND_LIST;
            //将查询的结果转json字符串的格式，因为导出的时候只能传一个字符串
            // 从模型类型枚举根据templateServiceType获取策略对应模板数据
            Map<String, Object> dataMap = new HashMap<>(12);
            dataMap.put("list", tableDmaUserBindList);
            ExcelUtil.export(dataMap, excelExportFileTypeEnum, Constant.FILE_PATH_TEST_EXPORT_EXCEL, response);
            return null;
        }


    }

    @GetMapping("/getTableUserBindList")
    @ApiOperation("查询总表的用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "linkStr", value = "模糊查询字段", dataType = "String"),
            @ApiImplicitParam(name = "cbbmc", value = "抄表本名称", dataType = "String"),
            @ApiImplicitParam(name = "cbpqLikeStr", value = "抄表片区模糊查询字段", dataType = "String")
    })
    public ResultRespone getTableUserBindList(Page page, String linkStr, String cbbmc, String cbpqLikeStr) {
        return ResultRespone.success(theOnlineCheckService.getTableUserBindList(page, linkStr, cbbmc, cbpqLikeStr));
    }

    @GetMapping("/tableInfo")
    @ApiOperation("查询总表信息")
    public ResultRespone selectSunTable() {
        return ResultRespone.success(theOnlineCheckService.selectSunTable());
    }

    @GetMapping("/viewTablePipe")
    @ApiOperation("显示管线、关联客户数、总表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "确认状态：0未确认、1已确认、2自动匹配 、3查询全部", dataType = "string"),
            @ApiImplicitParam(name = "likeStr", value = "水表编号和地址模糊查询", dataType = "string")
    })
    public ResultRespone viewTablePipe(Page page, String type, String likeStr) {
        return ResultRespone.success(theOnlineCheckService.viewTablePipe(page, type, likeStr));
    }

    @GetMapping("/deleteTableById")
    @ApiOperation("通过ID删除用户水表信息绑定用户绑定管线")
    @ApiImplicitParam(name = "id", value = "id", dataType = "long")
    public ResultRespone deleteTableById(Long id) {
        return ResultRespone.success(theOnlineCheckService.deleteTableById(id));
    }

    @PutMapping("/confirmTablePipe")
    @ApiOperation("确认管线与总表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "0：选中确认 1:全部确认", required = true, dataType = "string"),
            @ApiImplicitParam(name = "tableId", value = "总表id", dataType = "string")
    })

    public ResultRespone confirmTablePipe(String tableId, String type) {
        return ResultRespone.success(theOnlineCheckService.confirmTablePipe(tableId, type));
    }

    @GetMapping("customerInfo")
    @ApiOperation("未关联客户信息查询")
    @ApiImplicitParam(name = "str", value = "条件：客户姓名/客户编号/客户地址", dataType = "string")
    public ResultRespone unaffiliatedCustomer(Page page, String str) {
        return ResultRespone.success(theOnlineCheckService.unaffiliatedCustomer(page, str));
    }

    @PostMapping("/userToTable")
    @ApiOperation("用户关联总表")
    public ResultRespone userToTable(@RequestBody TablelinkUserDto dto) {
        return ResultRespone.success(theOnlineCheckService.userToTable(dto));
    }

    @PutMapping("/confirmTableUser")
    @ApiOperation("确认客户-总表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "codes", value = "客户编号，多个‘,’分割", dataType = "string"),
            @ApiImplicitParam(name = "tableId", value = "总表id，多个‘,’分割", dataType = "string"),
            @ApiImplicitParam(name = "type", value = "0：选中确认 1:全部确认", required = true, dataType = "string")
    })

    public ResultRespone confirmTableUser(String tableId, String codes, String type) {
        return ResultRespone.success(theOnlineCheckService.confirmTableUser(tableId, codes, type));
    }

    @GetMapping("/associatedCustomer")
    @ApiOperation("查询关联客户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "0:分页查询 1:全部查询", required = true, dataType = "string"),
            @ApiImplicitParam(name = "tableIds", value = "总表id多个以,分隔", required = true, dataType = "string"),
            @ApiImplicitParam(name = "likeStr", value = "客户编号、客户姓名和地址模糊查询", dataType = "string")
    })
    public ResultRespone associatedCustomer(Page page, String tableIds, String code, String likeStr) {
        if ("0".equals(code)) {
            return ResultRespone.success(theOnlineCheckService.associatedCustomer(page, tableIds, likeStr));
        } else {
            return ResultRespone.success(theOnlineCheckService.associatedCustomer(tableIds, likeStr));
        }
    }

    @PostMapping("/removeUser")
    @ApiOperation("移除用户表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "id,多个‘,’分割", dataType = "string"),
            @ApiImplicitParam(name = "tableId", value = "总表id", dataType = "string")
    })

    public ResultRespone removeUser(String tableId, String ids) {
        return ResultRespone.success(theOnlineCheckService.removeUser(tableId, ids));
    }

    @PutMapping("/moveUserTable")
    @ApiOperation("用户表更换总表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableId", value = "总表id", required = true, dataType = "string"),
            @ApiImplicitParam(name = "codes", value = "客户编号", required = true, dataType = "string"),
            @ApiImplicitParam(name = "origTableId", value = "源总表id", required = true, dataType = "string")
    })
    public ResultRespone moveUserTable(String tableId, String codes, String origTableId) {
        return ResultRespone.success(theOnlineCheckService.moveUserTable(tableId, codes, origTableId));
    }

    @PutMapping("/inTheTable")
    @ApiOperation("总表换表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldId", value = "旧表总表id", required = true, dataType = "string"),
            @ApiImplicitParam(name = "newId", value = "表总表id", required = true, dataType = "string")
    })
    public ResultRespone inTheTable(String oldId, String newId) {
        return ResultRespone.success(theOnlineCheckService.inTheTable(oldId, newId));
    }

    @PutMapping("/setPlotName")
    @ApiOperation("设置小区名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "小区名称", required = true, dataType = "string"),
            @ApiImplicitParam(name = "tableCode", value = "水表编号", required = true, dataType = "string")
    })
    public ResultRespone setPlotName(String name, String tableCode) {
        return ResultRespone.success(theOnlineCheckService.setPlotName(name, tableCode));
    }

    @PostMapping("/autoMatch")
    @ApiOperation("自动匹配关联客户表")
    public ResultRespone autoMatch() {
        return ResultRespone.success(theOnlineCheckService.autoMatch());
    }

    @GetMapping("/getSchedule")
    @ApiOperation("获取自动匹配进度进度")
    public ResultRespone getInsertSchedule() {
        return ResultRespone.success(theOnlineCheckService.getInsertSchedule());
    }

    @PostMapping("/stopArea")
    @ApiOperation("停水区域查询")
    public ResultRespone waterStopArea(Page page, String valves, String likeStr) {
        return ResultRespone.success(theOnlineCheckService.waterStopArea(page, valves, likeStr));
    }

    @GetMapping("/getTableInArea")
    @ApiOperation("区域查询用水量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lon", value = "区域各顶点的横坐标数组", required = true, dataType = "Double[]"),
            @ApiImplicitParam(name = "lat", value = "区域各顶点的纵坐标数组", required = true, dataType = "Double[]"),
            @ApiImplicitParam(name = "code", value = "0:查看全部 1：同期对比", required = true, dataType = "string"),
            @ApiImplicitParam(name = "strTime", value = "开始时间yyyyMM", dataType = "string"),
            @ApiImplicitParam(name = "endTime", value = "结束时间yyyyMM", dataType = "string"),
            @ApiImplicitParam(name = "likeStr", value = "模糊查询", dataType = "string"),
    })
    public ResultRespone getTableInArea(Page page, Double[] lon, Double[] lat, String strTime, String endTime, String code, String likeStr) {
        return ResultRespone.success(theOnlineCheckService.getTableInArea(page, lon, lat, strTime, endTime, code, likeStr));
    }

    @GetMapping("/useWaterHistory")
    @ApiOperation("查看用户用水历史")
    public ResultRespone useWaterHistory(Page page, String yhbh, String startTime, String endTime) {
        return ResultRespone.success(theOnlineCheckService.useWaterHistory(page, yhbh, startTime, endTime));
    }

    @GetMapping("/getYxUserInfoPage")
    @ApiOperation("获取营销用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "meterReadingArea", value = "抄表区域", dataType = "string"),
            @ApiImplicitParam(name = "yhbhs", value = "用户编号,多个以,分隔", dataType = "string"),
            @ApiImplicitParam(name = "likeStr", value = "模糊查询", dataType = "string"),
    })
    public ResultRespone getYxUserInfoPage(Page page, String meterReadingArea, String yhbhs, String likeStr) {
        return ResultRespone.success(theOnlineCheckService.getYxUserInfoPage(page, meterReadingArea, yhbhs, likeStr));
    }

    @GetMapping("/getYxChargeDetail")
    @ApiOperation("获取营销缴费明细")
    public ResultRespone<Page<ChargeDetailInfoVo>> getYxChargeDetail(Page page, @RequestParam(value = "userId", required = false) Long userId) {
        return ResultRespone.success(theOnlineCheckService.getYxChargeDetail(page, userId));
    }

    @GetMapping("/getYxChargeUserInfo")
    @ApiOperation("获取营销客户信息档案")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "likeStr", value = "模糊查询", dataType = "string"),
            @ApiImplicitParam(name = "chargeArea", value = "营业区域查询", dataType = "long"),
            @ApiImplicitParam(name = "sex", value = "性别查询", dataType = "string"),
    })
    public ResultRespone<Page<ChargeUserInfoVo>> getYxChargeUserInfo(Page page, String likeStr, Long chargeArea, String sex) {
        return ResultRespone.success(theOnlineCheckService.getYxChargeUserInfo(page, likeStr, chargeArea, sex));
    }

    @GetMapping("/getYxChargeUserInfoList")
    @ApiOperation("获取营销客户信息档案列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "likeStr", value = "模糊查询", dataType = "string"),
            @ApiImplicitParam(name = "chargeArea", value = "营业区域查询", dataType = "long"),
            @ApiImplicitParam(name = "sex", value = "性别查询", dataType = "string"),
    })
    public ResultRespone<List<ChargeUserInfoVo>> getYxChargeUserInfoList(String likeStr, Long chargeArea, String sex) {
        return ResultRespone.success(theOnlineCheckService.getYxChargeUserInfoList(likeStr, chargeArea, sex));
    }

    @GetMapping("/getMeterReadingAreaList")
    @ApiOperation("获取营销抄表区域列表")
    public ResultRespone getMeterReadingAreaList() {
        return ResultRespone.success(theOnlineCheckService.getMeterReadingAreaList());
    }

}
