package com.tofly.watermeter.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.watermeter.custom.entity.dto.FileRequest;
import com.tofly.watermeter.custom.entity.dto.InstallTableQueryDto;
import com.tofly.watermeter.custom.entity.dto.InstallationDto;
import com.tofly.watermeter.em.ApiCallEnum;
import com.tofly.watermeter.entity.Bwrksbdatail;
import com.tofly.watermeter.entity.Installation;
import com.tofly.watermeter.mapper.InstallationMapper;
import com.tofly.watermeter.service.BwrksbdatailService;
import com.tofly.watermeter.service.InstallationService;
import com.tofly.watermeter.util.service.CallAPIService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Bubble
 */
@Service
@AllArgsConstructor
public class InstallationServiceImpl extends ServiceImpl<InstallationMapper, Installation> implements InstallationService {

    private final CallAPIService callAPIService;

    private final BwrksbdatailService bwrksbdatailService;

    /**
     * 获取营业区域与片区
     *
     * @return list
     */
    @Override
    public List<Map> getAreaAndZone() {
        List<Map> result;
        Map areaResult =
                callAPIService.getApiResult(new HashMap<>(), "/api/v1/fish/area/find/condition/all");

        if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(areaResult.get("statusCode")))) {
            result = JSONObject.parseArray(String.valueOf(areaResult.get("data")), Map.class);
            if (CollectionUtil.isNotEmpty(result)) {
                for (Map map : result) {
                    Map params = new HashMap();
                    params.put("areaCode", map.get("code"));
                    Map zoneMap = callAPIService.getApiResult(params, "/api/v1/fish/zone/find/condition/all");
                    if (ApiCallEnum.STATUS_CODE_OK
                            .getCode()
                            .equals(String.valueOf(zoneMap.get("statusCode")))) {
                        map.put(
                                "zoneData", JSONObject.parseArray(String.valueOf(zoneMap.get("data")), Map.class));
                    } else {
                        throw new ToflyDeniedException("获取供水片区失败");
                    }
                }
            }
        } else {
            throw new ToflyDeniedException("获取营业区域失败");
        }
        return result;
    }

    @Override
    public List<Map> getRegion() {
        List<Map> result;
        Map apiResult =
                callAPIService.getApiResult(new HashMap<>(), "/api/v1/fish/region/find/tree/condition");
        if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(apiResult.get("statusCode")))) {
            result = JSONObject.parseArray(String.valueOf(apiResult.get("data")), Map.class);
        } else {
            throw new ToflyDeniedException("获取行政区划失败");
        }
        return result;
    }

    /**
     * 获取报装编号
     *
     * @param areaCode 区域编码
     * @return string
     */
    @Override
    public String getInstallationCode(String areaCode) {
        Map params = new HashMap();
        params.put("areaCode", areaCode);
        Map apiResult = callAPIService.getApiResult(params, "/api/v1/cattle/request/find/code");
        if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(apiResult.get("statusCode")))) {
            return String.valueOf(apiResult.get("data"));
        } else {
            throw new ToflyDeniedException("获取报装编号失败");
        }
    }

    /**
     * 报装文件上传接口
     *
     * @param files 文件列表
     * @return boolean
     */
    @Override
    public FileRequest upLoadInstallation(MultipartFile files) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("appId", 4330);
        params.put("type", 1);
        Map map = callAPIService.uploadFile(params,files, "/api/v1/rabbit/file/upload");
        if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(map.get("statusCode")))) {
            return JSONObject.parseObject(String.valueOf(map.get("data")), FileRequest.class);
        } else {
            throw new ToflyDeniedException("报装文件上传失败");
        }
    }

    /**
     * 报装登记接口
     *
     * @param dto dto
     * @return boolean
     */
    @Override
    public boolean insertInstallation(InstallationDto dto) {
        //报装登记
        Map apiResult = callAPIService.getApiResult(dto, "/api/v1/cattle/request/save");
        if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(apiResult.get("statusCode")))){
            return true;
        }else {
            throw new ToflyDeniedException(String.valueOf(apiResult.get("massage")));
        }
    }

    /**
     * 同步报装接口
     *
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncInstallation() {
        //查询条件
        InstallTableQueryDto dto = new InstallTableQueryDto();
        dto.setId("1011672977831362560");
        dto.setExportType(1);
        dto.setNeedSummary(0);
        dto.setQueryName("按条件");
        dto.setPageSize(500);
        dto.setParameters(new ArrayList<>());
        dto.setSortFields(new ArrayList<>());
        List<Map<String, Object>> parameters;
        Map<String, Object> param;
        parameters = new ArrayList<>();
        param = new HashMap<>(2);
        param.put("code","CREATE_TIME");
        List<Long> value = new ArrayList<>();
        //获取前1个月的数据
        value.add(DateUtil.offsetMonth(DateUtil.beginOfDay(new Date()),-1).getTime());
        value.add(System.currentTimeMillis());
        param.put("value", value);
        parameters.add(param);
        dto.setParameters(parameters);
        //页数
        Integer pageNum = 1;
        while (true){
            dto.setPageNum(pageNum);
            Map apiResult = callAPIService.getApiResult(dto,"/api/v1/seagull/query/execute");
            if (ApiCallEnum.STATUS_CODE_OK.getCode().equals(String.valueOf(apiResult.get("statusCode")))) {
                Map resultDataMap = JSONObject.parseObject(String.valueOf(JSONObject.parseObject(String.valueOf(apiResult.get("data")), Map.class).get("resultData")), Map.class);

                //接口查询返回数据
                List<Map> resultList = JSONObject.parseArray(String.valueOf(resultDataMap.get("list")), Map.class);
                //当数据不为空
                if ( CollectionUtils.isNotEmpty(resultList)){
                    //水表编号集合
                    List<String> tableCode = resultList.stream().map(m -> String.valueOf(m.get("METER_CODE"))).collect(Collectors.toList());
                    //查询本系统已出库水表与森鑫炬报装水表匹配的数据
                    List<Bwrksbdatail> tableList = bwrksbdatailService.list(Wrappers.<Bwrksbdatail>lambdaQuery().in(Bwrksbdatail::getBwSbbh, tableCode)
                            .isNotNull(Bwrksbdatail::getBzbh).eq(Bwrksbdatail::getBwSbzt, 2)
                            .select(Bwrksbdatail::getBwSbbh));
                    if (CollectionUtil.isNotEmpty(tableList)){
                        List<String> tableCodeList = tableList.stream().map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
                        //只处理未同步的水表
                        tableCode.removeAll(tableCodeList);
                        if (tableCode.size() > 0){
                            for (Map map : resultList) {
                                String meterCode = String.valueOf(map.get("METER_CODE"));
                                String code = String.valueOf(map.get("CODE"));
                                String userCode = String.valueOf(map.get("USER_CODE"));
                                //用户编号为空代表报装流程未走完
                                if (tableCode.contains(meterCode) && StringUtils.isNotBlank(userCode)){
                                    bwrksbdatailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                                            .set(Bwrksbdatail::getBwSbzt, 3)
                                            .set(Bwrksbdatail::getBzbh, code)
                                            .set(Bwrksbdatail::getBwKhbh, userCode)
                                            .set(Bwrksbdatail::getBwKhxm,String.valueOf(map.get("USER_NAME")))
                                            .set(Bwrksbdatail::getBwKhdz,String.valueOf(map.get("WATER_ADDRESS_REQUEST")))
                                            .set(Bwrksbdatail::getBwKhdh,String.valueOf(map.get("CONTACT_PHONE")))
                                            .set(Bwrksbdatail::getBwAzrq,new Date(Long.parseLong(String.valueOf(map.get("INSTALLER_TIME")))))
                                            .set(Bwrksbdatail::getSbazdz,String.valueOf(map.get("WATER_ADDRESS_REQUEST")))
                                            .set(Bwrksbdatail::getBwSbqd, Integer.parseInt(String.valueOf(map.get("START_READING"))))
                                            .set(Bwrksbdatail::getIssyc,1)
                                            .set(Bwrksbdatail::getBwAzry,String.valueOf(map.get("INSTALLER")))
                                            .set(Bwrksbdatail::getSynTime,new Date())
                                            .set(Bwrksbdatail::getMsg,"同步成功")
                                            .eq(Bwrksbdatail::getBwSbbh, meterCode));
                                }
                            }
                        }
                    }
                    pageNum++;
                }else {
                    break;
                }
            }
        }
        return true;
    }

}
