package com.tofly.xrtygis.custom.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.xrtygis.custom.entity.dto.TablelinkUserDto;
import com.tofly.xrtygis.custom.entity.dto.TablelinkpipeDto;
import com.tofly.xrtygis.custom.mapper.GetMaxIdMapper;
import com.tofly.xrtygis.custom.mapper.TheOnlineCheckMapper;
import com.tofly.xrtygis.custom.service.TheOnlineCheckService;
import com.tofly.xrtygis.entity.Tablelinkpipe;
import com.tofly.xrtygis.entity.Tablelinkuser;
import com.tofly.xrtygis.service.TablelinkpipeService;
import com.tofly.xrtygis.service.TablelinkuserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 综合展示线上核对
 *
 * @author 泡泡
 */
@Service
@AllArgsConstructor
public class TheOnlineCheckServiceImpl implements TheOnlineCheckService {

    private final TablelinkpipeService tablelinkpipeService;
    private final TablelinkuserService tablelinkuserService;

    private final TheOnlineCheckMapper theOnlineCheckMapper;
    private final GetMaxIdMapper getMaxIdMapper;

    private final static String TABLE_LINK_USER = "TF_YWPN_TABLELINKUSER_W";
    private final static String TABLE_LINK_PIPE = "TF_YWPN_TABLELINKPIPE_W";
    //未添加前总条数
    private static Double COUNT_SUM = 0D;
    //当前数据条数
    private static Double NOW_COUNT = 0D;
    //添加数据条数
    private static Double INSERT_COUNT = 0D;

    /**
     * 确认水表是否为总表
     * D
     *
     * @param code 水表编号
     * @return Boolean
     */
    @Override
    public Long isSumTable(Long code) {
        return theOnlineCheckMapper.isSumTable(code);
    }

    /**
     * 总表与管线绑定
     *
     * @param dto 总表与管线关联表
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean bindLine(TablelinkpipeDto dto) {

        if (null == dto) {
            throw new ToflyDeniedException("传入数据为空");
        }
        List<Tablelinkpipe> link = dto.getLink();
        if (link == null || link.isEmpty()) {
            throw new ToflyDeniedException("未传入信息");
        }
        List<Tablelinkpipe> list = tablelinkpipeService.list();

        Long maxId = getMaxIdMapper.getMaxId(TABLE_LINK_PIPE);

        if (!list.isEmpty()) {

            List<String> pipeSidList = list.stream().map(Tablelinkpipe::getPipeSid).collect(Collectors.toList());
            List<Long> tableIdList = list.stream().map(Tablelinkpipe::getTableId).collect(Collectors.toList());

            List<Tablelinkpipe> collect1 = link.stream().filter(t -> !tableIdList.contains(t.getTableId())).collect(Collectors.toList());

            if (!collect1.isEmpty()) {
                List<Tablelinkpipe> collect2 = collect1.stream().filter(t -> !pipeSidList.contains(t.getPipeSid())).collect(Collectors.toList());
                if (!collect2.isEmpty()) {
                    for (Tablelinkpipe tp : collect2) {
                        tp.setId(maxId);
                        maxId++;
                    }
                    theOnlineCheckMapper.insertPipeTable(collect2);
                }
            }
        } else {
            for (Tablelinkpipe tp : link) {
                tp.setId(maxId);
                maxId++;
            }
            theOnlineCheckMapper.insertPipeTable(link);
        }
        return true;
    }

    /**
     * 查询总表信息
     *
     * @return list
     */
    @Override
    public List<Map<String, Object>> selectSunTable() {
        return theOnlineCheckMapper.selectSumTableInfo();
    }

    /**
     * 显示管线与表信息关联
     *
     * @param page page
     * @return page
     */
    @Override
    public Page viewTablePipe(Page page, String type) {
        return theOnlineCheckMapper.viewTablePipe(page, Short.parseShort(type));
    }

    /**
     * 总表管线确认
     *
     * @param codes 水表编号
     * @return boolean
     */
    @Override
    public boolean confirmTablePipe(String codes, String type) {

        if (StringUtils.isEmpty(type)) {
            throw new ToflyDeniedException("未选择确认方式");
        }

        switch (type) {
            case "0":
                if (codes == null || "".equals(codes)) {
                    throw new ToflyDeniedException("传入水表编号为空");
                }
                tablelinkpipeService.update(Wrappers.<Tablelinkpipe>lambdaUpdate()
                        .in(Tablelinkpipe::getSid, Arrays.asList(codes.split(",")))
                        .ne(Tablelinkpipe::getState, "1")
                        .set(Tablelinkpipe::getState, "1"));
                break;
            case "1":
                tablelinkpipeService.update(Wrappers.<Tablelinkpipe>lambdaUpdate()
                        .ne(Tablelinkpipe::getState, "1")
                        .set(Tablelinkpipe::getState, "1"));
                break;
            default:
        }
        return true;
    }

    /**
     * 查询未关联客户信息
     *
     * @param str  用户编号/用户地址/用户姓名
     * @param page page
     * @return page
     */
    @Override
    public Page unaffiliatedCustomer(Page page, String str) {
        return theOnlineCheckMapper.unaffiliatedCustomer(page, str);
    }

    /**
     * 用户关联总表
     *
     * @param dto dto
     * @return boolean
     */
    @Override
    public boolean userToTable(TablelinkUserDto dto) {
        if (dto == null) {
            throw new ToflyDeniedException("传入数据为空");
        }
        Long tableId = dto.getTableId();
        if (tableId == null) {
            throw new ToflyDeniedException("未指定关联总表");
        }
        Tablelinkpipe table = tablelinkpipeService.getOne(Wrappers.<Tablelinkpipe>lambdaQuery()
                .eq(Tablelinkpipe::getTableId, tableId));

        if (table == null) {
            throw new ToflyDeniedException("该表未与总线关联");
        }

        if (this.isSumTable(table.getTableId()) == 0) {
            throw new ToflyDeniedException("该表不为总表");
        }

        List<Map<String, String>> info = dto.getInfo();
        if (info.isEmpty()) {
            throw new ToflyDeniedException("未传入客户信息");
        }
        List<Tablelinkuser> list = new ArrayList<>();

        Long maxId = getMaxIdMapper.getMaxId(TABLE_LINK_USER);

        Tablelinkuser user;

        for (Map<String, String> m : info) {
            user = new Tablelinkuser();
            user.setId(maxId);
            user.setKhbh(m.get("khbh"));
            user.setTableId(tableId);
            user.setSid(m.get("sbbh"));
            user.setState("0");

            maxId++;
            list.add(user);
        }
        return theOnlineCheckMapper.insertUserToTable(list);
    }

    /**
     * 确认水表与总表
     *
     * @param codes 客户编号
     * @return boolean
     */
    @Override
    public boolean confirmTableUser(String tableId, String codes, String type) {

        if (StringUtils.isEmpty(type)) {
            throw new ToflyDeniedException("未选中确认方式");
        }
        if ("0".equals(type)) {
            if (StringUtils.isEmpty(tableId)) {
                throw new ToflyDeniedException("总表id不能为空");
            }

            if (!StringUtils.isEmpty(tableId) && StringUtils.isEmpty(codes)) {
                tablelinkuserService.update(Wrappers.<Tablelinkuser>lambdaUpdate()
                        .in(Tablelinkuser::getTableId, Arrays.asList(tableId.split(",")))
                        .ne(Tablelinkuser::getState, 1)
                        .set(Tablelinkuser::getState, 1));
            } else {
                tablelinkuserService.update(Wrappers.<Tablelinkuser>lambdaUpdate()
                        .in(Tablelinkuser::getKhbh, Arrays.asList(codes.split(",")))
                        .ne(Tablelinkuser::getState, 1)
                        .set(Tablelinkuser::getState, 1));
            }
        } else {
            tablelinkuserService.update(Wrappers.<Tablelinkuser>lambdaUpdate()
                    .ne(Tablelinkuser::getState, 1)
                    .set(Tablelinkuser::getState, 1));
        }
        return true;
    }

    /**
     * 查询关联总表客户信息
     *
     * @param page page
     * @return page
     */
    @Override
    public Page associatedCustomer(Page page, Integer tableId) {
        return theOnlineCheckMapper.affiliatedCustomer(page, tableId);
    }

    /**
     * 查询关联总表客户信息
     *
     * @param tableId 表id
     * @return page
     */
    @Override
    public List<Map<String, Object>> associatedCustomer(Integer tableId) {
        return theOnlineCheckMapper.affiliatedCustomer(tableId);
    }

    /**
     * 移除总表-客户关联
     *
     * @param ids ids
     * @return boolean
     */
    @Override
    public boolean removeUser(String tableId, String ids) {
        if (tableId != null && !"".equals(tableId) && StringUtils.isEmpty(ids)) {
            tablelinkuserService.remove(Wrappers.<Tablelinkuser>lambdaQuery()
                    .eq(Tablelinkuser::getTableId, tableId));
        } else {
            tablelinkuserService.removeByIds(Arrays.asList(ids.split(",")));
        }
        return true;
    }

    /**
     * 客户-总表移动
     *
     * @param tableId 总表id
     * @param codes   客户编号
     * @return boolean
     */
    @Override
    public boolean moveUserTable(String tableId, String codes) {
        if (tableId == null) {
            throw new ToflyDeniedException("未选定总表");
        }
        if (codes == null) {
            throw new ToflyDeniedException("未选定转移水表");
        }
        return tablelinkuserService.update(Wrappers.<Tablelinkuser>lambdaUpdate()
                .in(Tablelinkuser::getKhbh, Arrays.asList(codes.split(",")))
                .set(Tablelinkuser::getTableId, tableId)
                .set(Tablelinkuser::getState, "0"));
    }

    /**
     * 总表换表
     *
     * @param oldId 旧表id
     * @param newId 新表id
     * @return boolean
     */
    @Override
    public boolean inTheTable(String oldId, String newId) {
        if (StringUtils.isEmpty(oldId)) {
            throw new ToflyDeniedException("未传入旧表信息");
        }
        if (StringUtils.isEmpty(newId)) {
            throw new ToflyDeniedException("未传入新表信息");
        }
        return tablelinkuserService.update(Wrappers.<Tablelinkuser>lambdaUpdate()
                .eq(Tablelinkuser::getTableId, oldId)
                .set(Tablelinkuser::getTableId, newId)
                .set(Tablelinkuser::getState, 0));
    }


    /**
     * 设置小区名称
     *
     * @param name      小区名称
     * @param tableCode 水表编号
     * @return boolean
     */
    @Override
    public boolean setPlotName(String name, String tableCode) {
        if (name == null) {
            throw new ToflyDeniedException("未设置小区名称");
        }
        return theOnlineCheckMapper.updatePlotName(name, Arrays.asList(tableCode.split(",")));
    }

    /**
     * 自动匹配
     *
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean autoMatch(Long current,Long size) {
        Page page = new Page();
        page.setCurrent(current);
        page.setSize(size);
        Page<Map<String, Object>> mapPage = theOnlineCheckMapper.unaffiliatedCustomer2(page);
        List<Map<String, Object>> maps = this.selectSunTable();
        if (!maps.isEmpty()) {
            List<Tablelinkuser> info = new ArrayList<>();
            for (Map<String, Object> map : maps) {
                if (!StringUtils.isEmpty(map.get("address"))) {
                    List<Map<String, Object>> matchInfo = mapPage.getRecords();
                    if (!matchInfo.isEmpty()){
                        List<Map<String, Object>> collect = matchInfo.stream()
                                .filter(m -> m.get("yhdz").toString().contains(map.get("address").toString()))
                                .collect(Collectors.toList());

                        if (!collect.isEmpty()) {
                            Long maxId = getMaxIdMapper.getMaxId(TABLE_LINK_USER);
                            Tablelinkuser user;
                            for (Map<String, Object> m : collect) {
                                user = new Tablelinkuser();
                                user.setSid(m.get("sid") == null ? null : m.get("sid").toString());
                                user.setKhbh(m.get("yhbh") == null ? null : m.get("yhbh").toString());
                                user.setState("0");
                                user.setTableId(Long.parseLong(map.get("id").toString()));
                                user.setId(maxId);
                                maxId++;

                                info.add(user);
                            }

                            if (!info.isEmpty()) {
                                theOnlineCheckMapper.insertUserToTable(info);
                                info.clear();
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

    /**
     * 获取添加进度
     *
     * @return double
     */
    @Override
    public Double getInsertSchedule() {
        NOW_COUNT = theOnlineCheckMapper.getNowNum();
        return new BigDecimal(NOW_COUNT).subtract(new BigDecimal(COUNT_SUM)).divide(new BigDecimal(INSERT_COUNT), 2).doubleValue();
    }

    /**
     * 根据管线查看关联客户信息
     *
     * @param pipe 管线
     * @return list
     */
    @Override
    public List<Map<String, Object>> queryCustomerByPipe(String pipe) {
        if (StringUtils.isEmpty(pipe)) {
            throw new ToflyDeniedException("管线信息为空");
        }

        List<Map<String, Object>> result = new ArrayList<>(10);

        List<Map<String, Object>> customerInfo;

        List<String> pipeList = Arrays.asList(pipe.split(","));
        //管线查询关联表信息
        List<Tablelinkpipe> tablelinkpipes = tablelinkpipeService.list(Wrappers.<Tablelinkpipe>lambdaQuery()
                .in(Tablelinkpipe::getPipeSid, pipeList));
        //查询不为空
        if (!tablelinkpipes.isEmpty()) {
            //根据管线编号分组
            Map<String, List<Tablelinkpipe>> pipeCollect = tablelinkpipes.stream()
                    .collect(Collectors.groupingBy(Tablelinkpipe::getPipeSid));

            List<String> pielsList = tablelinkpipes.stream().distinct()
                    .map(Tablelinkpipe::getPipeSid).collect(Collectors.toList());

            for (String pipes : pielsList) {
                //当前管线编号存在
                if (pipeCollect.containsKey(pipes)) {
                    List<Tablelinkpipe> list = pipeCollect.get(pipes);
                    //且有值
                    if (!list.isEmpty()) {
                        //收集水表编号
                        List<Long> tableIdList = list.stream()
                                .map(Tablelinkpipe::getTableId).collect(Collectors.toList());
                        if (!tableIdList.isEmpty()) {
                            //水表编号查询关联用户
                            List<Tablelinkuser> userList = tablelinkuserService.list(Wrappers.<Tablelinkuser>lambdaQuery()
                                    .in(Tablelinkuser::getTableId, tableIdList));
                            if (!userList.isEmpty()) {
                                //查询出来的用户编号根据绑定水表编号分组
                                Map<Long, List<Tablelinkuser>> userCollect = userList.stream()
                                        .collect(Collectors.groupingBy(Tablelinkuser::getTableId));
                                if (!userCollect.isEmpty()) {
                                    for (Long tableId : tableIdList) {
                                        customerInfo = new ArrayList<>(10);
                                        //当前水表编号有绑定水表
                                        if (userCollect.containsKey(tableId)) {
                                            List<Tablelinkuser> linkuserList = userCollect.get(tableId);
                                            //且数据不为空
                                            if (!linkuserList.isEmpty()) {
                                                //收集客户编号
                                                List<String> customerList = linkuserList.stream()
                                                        .map(Tablelinkuser::getKhbh).collect(Collectors.toList());
                                                if (!customerList.isEmpty()) {
                                                    customerInfo = theOnlineCheckMapper.getCustomerInfo(customerList);
                                                    Map<String, Object> wateMeter = theOnlineCheckMapper.getWateMeter(tableId);
                                                    customerInfo.forEach(m->{
                                                        m.put("pipeSid",pipes);
                                                        m.put("x",wateMeter.get("x"));
                                                        m.put("y",wateMeter.get("y"));
                                                        m.put("address",wateMeter.get("address"));
                                                        m.put("village",wateMeter.get("village"));
                                                        result.add(m);
                                                    });
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
}
