package com.zcxk.rmcp.web.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.page.PageMethod;
import com.zcxk.core.oauth2.pojo.LoginUser;
import com.zcxk.core.common.util.BeanCopyUtils;
import com.zcxk.core.oauth2.util.UserUtil;
import com.zcxk.core.mysql.pageing.Pagination;
import com.zcxk.core.utils.DateUtil;
import com.zcxk.rmcp.api.dto.measurementsettlement.*;
import com.zcxk.rmcp.api.vo.XxlJobInfo;
import com.zcxk.rmcp.core.dao.DeviceMapper;
import com.zcxk.rmcp.core.dao.MeasurementInstanceMapper;
import com.zcxk.rmcp.core.dao.MeasurementRecordMapper;
import com.zcxk.rmcp.core.dao.MeasurementSettlementMapper;
import com.zcxk.rmcp.core.entity.Device;
import com.zcxk.rmcp.core.entity.MeasurementInstance;
import com.zcxk.rmcp.core.entity.MeasurementRecord;
import com.zcxk.rmcp.core.entity.MeasurementSettlement;
import com.zcxk.rmcp.web.service.MeasurementSettlementService;
import com.zcxk.rmcp.web.util.XxlJobUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.security.SecureRandom;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
 *
 * @author heyumin
 * @date 2021-07-30 9:44
 */
@Service
public class MeasurementSettlementServiceImpl implements MeasurementSettlementService {
    @Resource
    private MeasurementRecordMapper measurementRecordMapper;
    @Resource
    private MeasurementSettlementMapper measurementSettlementMapper;
    @Resource
    private MeasurementInstanceMapper measurementInstanceMapper;
    @Resource
    private DeviceMapper deviceMapper;
    @Autowired
    private XxlJobUtil xxlJobUtil;
    @Override
    public Pagination<MeasurementSettlementDto> pageMeasurementSettlement(MeasurementSettlementPageDto pageDto) {
        MeasurementSettlement measurementSettlement=new MeasurementSettlement();
        BeanCopyUtils.copyProperties(pageDto, measurementSettlement, MeasurementSettlement.class);
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
    
        List<MeasurementSettlementDto> measurementRecords = measurementSettlementMapper.
                selectList(measurementSettlement,UserUtil.getCurrentUser().getUserCondition());

        if (CollectionUtils.isEmpty(measurementRecords)){
            return new Pagination<>();
        }
        return new Pagination<>(measurementRecords);

    }

    @Override
    public Pagination<MeasurementSettlementDto> pageMeasurementSettlementRecord(MeasurementSettlementPageDto pageDto) {

        MeasurementSettlementDto measurementSettlementDto=new MeasurementSettlementDto();
        BeanCopyUtils.copyProperties(pageDto, measurementSettlementDto, MeasurementSettlementDto.class);
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
     
        List<MeasurementSettlementDto> measureInstances = measurementInstanceMapper.selectList(measurementSettlementDto,UserUtil.getCurrentUser().getUserCondition());

       return new Pagination<>(measureInstances);
    }

    @Override
    public void addPlan(MeasurementSettlementDto measurementSettlementDto) {
        MeasurementSettlement measurementSettlement=new MeasurementSettlement();
        BeanCopyUtils.copyProperties(measurementSettlementDto, measurementSettlement, MeasurementSettlement.class);
        LoginUser currentUser = UserUtil.getCurrentUser();
        measurementSettlement.setCreateBy(currentUser.getName());
        measurementSettlement.setCreateDate(new Date());
        measurementSettlement.setStatus(1);
        String tenantId=currentUser.getTenantId();
        measurementSettlement.setTenantId(tenantId);
        List<Device> devices = deviceMapper.findMeasurementDevice(measurementSettlementDto);
        measurementSettlement.setTotalWaterMeters(devices.size());
        measurementSettlementMapper.insert(measurementSettlement);
        String add = xxlJobUtil.add(setInfo(measurementSettlementDto));
        JSONObject jsonObject = JSON.parseObject(add);
        String taskId = jsonObject.getString("content");
        measurementSettlement.setTaskId(Long.parseLong(taskId));
        Integer id=measurementSettlement.getId();
        measurementSettlement=new MeasurementSettlement();
        measurementSettlement.setId(id);
        measurementSettlement.setTaskId(Long.valueOf(taskId));
        measurementSettlementMapper.update(measurementSettlement);


    }

    @Override
    public void updatePlan(MeasurementSettlementDto measurementSettlementDto) {
        MeasurementSettlement measurementSettlement=new MeasurementSettlement();
        BeanCopyUtils.copyProperties(measurementSettlementDto, measurementSettlement, MeasurementSettlement.class);
        LoginUser currentUser = UserUtil.getCurrentUser();
        measurementSettlementDto.setTenantId(currentUser.getTenantId());
        measurementSettlement.setUpdateBy(currentUser.getUsername());
        measurementSettlement.setUpdateDate(new Date());
        measurementSettlementMapper.update(measurementSettlement);
        XxlJobInfo xxlJobInfo = setInfo(measurementSettlementDto);
        xxlJobInfo.setId(measurementSettlementDto.getTaskId().intValue());
        xxlJobUtil.update(xxlJobInfo);
    }
    private XxlJobInfo setInfo(MeasurementSettlementDto measurementSettlementDto){
        XxlJobInfo xxlJobInfo=new XxlJobInfo();
        xxlJobInfo.setExecutorParam(JSON.toJSONString(measurementSettlementDto));
        xxlJobInfo.setJobDesc("执行结算:"+measurementSettlementDto.getPlanName());
        xxlJobInfo.setExecutorRouteStrategy("FIRST");
        xxlJobInfo.setGlueType("BEAN");
        xxlJobInfo.setJobCron(date2Cron(measurementSettlementDto.getSettlementTime()
                ,measurementSettlementDto.getBillingCycle()));
        xxlJobInfo.setExecutorHandler("measurementHandler");
        xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        xxlJobInfo.setExecutorTimeout(0);
        xxlJobInfo.setExecutorFailRetryCount(0);
        xxlJobInfo.setAuthor("admin");
        return  xxlJobInfo;
    }
    private String date2Cron(Date date,Integer period){
        LocalDate startDate = DateUtil.parseLocalDate(date);
        startDate=startDate.plusDays(1);
        Random r = new Random();
        String cron="";
        cron+=r.nextInt(59)+" ";
        cron+=r.nextInt(59)+" ";
        cron+=0+" ";
        cron+=startDate.getDayOfMonth()+" ";
        cron+=startDate.getMonth()+"/"+period+" ?";
        return cron;
    }
    @Override
    public void deletePlan(List<MeasurementSettlementDto> ids) {
        List<Integer>planIds=new ArrayList<>();
        List<Integer>taskIds=new ArrayList<>();
        ids.forEach(id->{
            planIds.add(id.getId());
            taskIds.add(id.getTaskId().intValue());
        });
        measurementSettlementMapper.deletePlan(planIds);
        xxlJobUtil.removeAll(taskIds);
    }

    @Override
    public void deleteAll() {
        List<MeasurementSettlementDto> measurementRecords = measurementSettlementMapper.
                selectList(new MeasurementSettlement(),UserUtil.getCurrentUser().getUserCondition());
        measurementSettlementMapper.deleteAll(UserUtil.getCurrentUser().getUserCondition());
        List<Integer>taskIds=new ArrayList<>();
        measurementRecords.forEach(measurementSettlementDto -> {
            taskIds.add(measurementSettlementDto.getTaskId().intValue());
        });
        xxlJobUtil.removeAll(taskIds);
    }


    @Override
    public Pagination<MeasurementRecordDto> pageMeasurementRecord(MeasurementRecordPageDto pageDto) {

        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
        List<MeasurementRecordDto> measurementSettlementDtos = measurementRecordMapper.selectList(pageDto);
        if (CollectionUtils.isEmpty(measurementSettlementDtos)){
            return new Pagination<>();
        }
        return new Pagination<>(measurementSettlementDtos);
    }

    @Override
    public void auditWater(List<MeasurementRecordDto> recordDtos) {
        List<Long>rids=new ArrayList<>();
        recordDtos.forEach(recordDto->{
            rids.add(recordDto.getId());
        });
        measurementRecordMapper.auditWater(rids);
        measurementInstanceMapper.modifyTheNumberOfAudits(rids.size(),
                recordDtos.get(0).getPlanId());
    }

    @Override
    public void auditAllWater(Integer planId) {
        measurementRecordMapper.auditAllWater(planId);
        measurementInstanceMapper.modifyAllTheNumberOfAudits(planId);
    }

    @Override
    public void modifyTheAmountOfWater(WaterConsumptionUpdateDto waterConsumptionUpdateDto) {
        MeasurementRecord measurementRecord=new MeasurementRecord();
        BeanCopyUtils.copyProperties(waterConsumptionUpdateDto, measurementRecord, MeasurementRecord.class);
        measurementRecord.setUpdateBy(UserUtil.getCurrentUser().getUsername());
        measurementRecord.setUpdateDate(new Date());
        measurementRecordMapper.update(measurementRecord);
    }

    @Override
    public void setBillingPeriod(MeasurementSettlementDto measurementSettlementDto) {
        MeasurementInstance measurementInstance=new MeasurementInstance();
        BeanCopyUtils.copyProperties(measurementSettlementDto, measurementInstance, MeasurementInstance.class);
        measurementInstanceMapper.update(measurementInstance);
    }
}
