package com.kxs.product.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kxs.common.core.constant.CommonConstants;
import com.kxs.common.core.constant.SecurityConstants;
import com.kxs.common.core.constant.enums.ErrorTypeEnum;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.core.util.R;
import com.kxs.common.core.util.RetOps;
import com.kxs.common.security.util.SecurityUtils;
import com.kxs.product.api.amqp.rabbit.RabbitGdActQueueMQ;
import com.kxs.product.api.dto.kxsapp.gd.GdDqReportDTO;
import com.kxs.product.api.dto.kxsapp.gd.GdReportDTO;
import com.kxs.product.api.dto.kxsapp.gd.GdReportPutDTO;
import com.kxs.product.api.model.KxsGdReport;
import com.kxs.product.api.vo.kxsapp.gd.GdDotNumVO;
import com.kxs.product.api.vo.kxsapp.gd.GdDqDotNumVO;
import com.kxs.product.api.vo.kxsapp.gd.GdReportListVO;
import com.kxs.product.api.vo.kxsapp.machine.MachineUnBindListVO;
import com.kxs.product.biz.constant.enums.GdReportEnum;
import com.kxs.product.biz.mapper.KxsGdReportMapper;
import com.kxs.product.biz.service.KxsGdReportService;
import com.kxs.product.biz.service.KxsGdService;
import com.kxs.product.biz.util.GdRsaUtils;
import com.kxs.user.api.feign.RemoteKxsUserService;
import com.kxs.user.api.model.KxsUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * 广电报备入网表(KxsGdReport)表服务实现类
 *
 * @author 系统
 * @since 2024-04-23 10:44:23
 */
@Service("kxsGdReportService")
@RequiredArgsConstructor
@Slf4j
public class KxsGdReportServiceImpl extends ServiceImpl<KxsGdReportMapper, KxsGdReport> implements KxsGdReportService {

    private final RemoteKxsUserService remoteKxsUserService;

    private final KxsGdService kxsGdService;


    @Override
    public Boolean addReport(GdReportPutDTO param) {


        R<Boolean> booleanR = remoteKxsUserService.checkMobileCode(param.getPutMobile(), param.getCode(), SecurityConstants.FROM_IN);
        if (booleanR.getStatus() != CommonConstants.SUCCESS || !booleanR.getData()) {
            throw new GlobalCustomerException(booleanR.getMsg());
        }
        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserByCode(param.getUserCode(), SecurityConstants.FROM_IN);
        KxsUser user = RetOps.of(kxsUserR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));

        KxsGdReport kxsGdReport = new KxsGdReport();
        BeanUtil.copyProperties(param, kxsGdReport);
        kxsGdReport.setUserId(user.getId());
        return this.save(kxsGdReport);
    }

    @Override
    public IPage<GdReportListVO> getByPage(Page<GdReportListVO> page, Integer status, Integer putType, String keyword) {

        Long userId = SecurityUtils.getUser().getId();
        return baseMapper.getByPage(page, userId, status, putType, keyword);
    }

    @Override
    public IPage<GdReportListVO> getDqByPage(Page<GdReportListVO> page, Integer status, String keyword) {

        Long userId = SecurityUtils.getUser().getId();

        return baseMapper.getDqByPage(page, userId, status, keyword);
    }

    @Override
    public GdDotNumVO dotNum(Integer putType) {

        Long userId = SecurityUtils.getUser().getId();
        GdDotNumVO gdDotNumVO = new GdDotNumVO();
        gdDotNumVO.setPendNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getUserId, userId)
                        .eq(KxsGdReport::getPutType, putType)
                        .eq(KxsGdReport::getStatus, GdReportEnum.PENDING.getType())))
                .orElse(0L));
        gdDotNumVO.setReportNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery()
                        .eq(KxsGdReport::getPutType, putType)
                        .eq(KxsGdReport::getUserId, userId).eq(KxsGdReport::getStatus, GdReportEnum.REPORT.getType())))
                .orElse(0L));
        gdDotNumVO.setCancelNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery()
                        .eq(KxsGdReport::getPutType, putType)
                        .eq(KxsGdReport::getUserId, userId).eq(KxsGdReport::getStatus, GdReportEnum.CANCEL.getType())))
                .orElse(0L));

        return gdDotNumVO;
    }

    @Override
    public Boolean cancelReport(KxsGdReport param) {

        Optional.ofNullable(param.getId()).orElseThrow(() -> new GlobalCustomerException("参数错误"));
        KxsGdReport kxsGdReport = this.getById(param.getId());
        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));
        if (Objects.equals(kxsGdReport.getStatus(), GdReportEnum.REPORT.getType())) {
            throw new GlobalCustomerException("该工单已报备，无法作废");
        }

        kxsGdReport.setStatus(GdReportEnum.CANCEL.getType());

        return this.updateById(kxsGdReport);
    }

    @Override
    public Boolean report(GdReportDTO param) {

        KxsGdReport kxsGdReport = this.getById(param.getId());

        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));
        if (!Objects.equals(kxsGdReport.getStatus(), GdReportEnum.PENDING.getType())) {
            throw new GlobalCustomerException("该工单状态错误");
        }
        //判断sn是否重复
        KxsGdReport report = this.getOne(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getGdSn, param.getGdSn()));
        if (report != null) {
            throw new GlobalCustomerException("该工单sn已报备");
        }
        KxsGdReport reportMobile = this.getOne(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getGdMobile, param.getGdMobile()));
        if (reportMobile != null) {
            throw new GlobalCustomerException("该工单广电手机号码已报备");
        }


        kxsGdReport.setStatus(GdReportEnum.REPORT.getType());
        kxsGdReport.setGdMobile(param.getGdMobile());
        kxsGdReport.setGdSn(param.getGdSn());

        return this.updateById(kxsGdReport);
    }

    @Override
    public Boolean updateData(KxsGdReport param) {

        Optional.ofNullable(param.getId()).orElseThrow(() -> new GlobalCustomerException("参数错误"));
        KxsGdReport kxsGdReport = this.getById(param.getId());
        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));

        if (Objects.equals(kxsGdReport.getIsCheck(), GdReportEnum.CHECK_SUC.getType())) {
            throw new GlobalCustomerException("该工单已匹配，无法更新");
        }


        return this.update(Wrappers.<KxsGdReport>lambdaUpdate()
                .eq(KxsGdReport::getId, param.getId())
                .set(KxsGdReport::getPutName, param.getPutName())
                .set(KxsGdReport::getGdSn, param.getGdSn())
                .set(KxsGdReport::getGdMobile, param.getGdMobile()));
    }

    @Override
    public R checkGdData(String startTime, String endTime) {

        kxsGdService.checkGdAsyncData(startTime, endTime);

        return R.ok();
    }

    @Override
    public IPage<MachineUnBindListVO> getByUnBindPage(Page<MachineUnBindListVO> page, String posSn) {

        Long userId = SecurityUtils.getUser().getId();
        return baseMapper.getByUnBindPage(page, userId, posSn);
    }

    @Override
    public Boolean dqReport(GdDqReportDTO param) {

        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(SecurityUtils.getUser().getId(), SecurityConstants.FROM_IN);
        KxsUser user = RetOps.of(kxsUserR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));

        KxsGdReport kxsGdReport = new KxsGdReport();
        BeanUtil.copyProperties(param, kxsGdReport);
        kxsGdReport.setUserId(user.getId());
        kxsGdReport.setUsername(user.getUsername());
        kxsGdReport.setUserCode(user.getUserCode());
        kxsGdReport.setStatus(GdReportEnum.REPORT.getType());

        return this.save(kxsGdReport);
    }

    @Override
    public GdDqDotNumVO dqDotNum() {

        Long userId = SecurityUtils.getUser().getId();
        GdDqDotNumVO gdDotNumVO = new GdDqDotNumVO();
        gdDotNumVO.setAllNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getUserId, userId)
                        .eq(KxsGdReport::getPutType, GdReportEnum.DQ.getType())))
                .orElse(0L));
        gdDotNumVO.setReportNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery()
                        .eq(KxsGdReport::getUserId, userId)
                        .eq(KxsGdReport::getStatus, GdReportEnum.REPORT.getType())
                        .eq(KxsGdReport::getPutType, GdReportEnum.DQ.getType())))
                .orElse(0L));
        gdDotNumVO.setEndNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery()
                        .eq(KxsGdReport::getUserId, userId)
                        .eq(KxsGdReport::getPutType, GdReportEnum.DQ.getType())
                        .eq(KxsGdReport::getIsCheck, GdReportEnum.CHECK_SUC)
                        .eq(KxsGdReport::getStatus, GdReportEnum.CANCEL.getType())))
                .orElse(0L));

        return gdDotNumVO;
    }

    @Override
    public void acceptActData(Map<String, Object> param) {

        log.info("接收到广电交易数据:{}", JSON.toJSONString(param));
        kxsGdService.checkGdAsyncData(param);

    }


}

