package com.usky.vpp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.usky.vpp.domain.VppCustomer;
import com.usky.vpp.domain.VppDrEvent;
import com.usky.vpp.domain.VppDrParticipation;
import com.usky.vpp.domain.VppResourcePoint;
import com.usky.vpp.domain.VppSite;
import com.usky.vpp.mapper.VppCustomerMapper;
import com.usky.vpp.mapper.VppDrParticipationMapper;
import com.usky.vpp.mapper.VppResourcePointMapper;
import com.usky.vpp.mapper.VppSiteMapper;
import com.usky.vpp.service.VppUnDrSyncService;
import com.usky.vpp.util.VppAuditHelper;
import com.usky.vpp.util.VppDrParticipationHelper;
import com.usky.vpp.util.VppUnEventParser;
import com.usky.vpp.util.VppUnPayloadHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
public class VppUnDrSyncServiceImpl implements VppUnDrSyncService {

    private static final int PARTICIPATE_STATUS_ACCEPT = 1;

    @Autowired
    private VppCustomerMapper customerMapper;
    @Autowired
    private VppSiteMapper siteMapper;
    @Autowired
    private VppResourcePointMapper resourcePointMapper;
    @Autowired
    private VppDrParticipationMapper participationMapper;

    @Override
    public void syncOptContent(VppDrEvent event, List<Map<String, Object>> optList, boolean clearing) {
        if (event == null || optList == null || optList.isEmpty()) {
            return;
        }
        for (Map<String, Object> item : optList) {
            syncOne(event, item, clearing);
        }
    }

    @Override
    public void syncTargetResources(VppDrEvent event, List<Map<String, Object>> resources, boolean clearing) {
        if (event == null || resources == null || resources.isEmpty()) {
            return;
        }
        for (Map<String, Object> resource : resources) {
            syncOne(event, resource, clearing);
        }
    }

    private void syncOne(VppDrEvent event, Map<String, Object> item, boolean clearing) {
        String account = VppUnPayloadHelper.getString(item, "account");
        if (!StringUtils.hasText(account)) {
            return;
        }
        BigDecimal load = resolveLoadKw(item);
        if (load == null) {
            return;
        }

        VppCustomer customer = customerMapper.selectOne(new LambdaQueryWrapper<VppCustomer>()
                .eq(VppCustomer::getAccountNo, account)
                .eq(VppCustomer::getDeleteFlag, VppAuditHelper.NOT_DELETED)
                .last("LIMIT 1"));
        if (customer == null) {
            return;
        }

        VppSite site = siteMapper.selectOne(new LambdaQueryWrapper<VppSite>()
                .eq(VppSite::getCustomerId, customer.getId())
                .eq(VppSite::getDeleteFlag, VppAuditHelper.NOT_DELETED)
                .last("LIMIT 1"));
        VppResourcePoint resourcePoint = null;
        if (site != null) {
            resourcePoint = resourcePointMapper.selectOne(new LambdaQueryWrapper<VppResourcePoint>()
                    .eq(VppResourcePoint::getSiteId, site.getId())
                    .eq(VppResourcePoint::getDeleteFlag, VppAuditHelper.NOT_DELETED)
                    .last("LIMIT 1"));
        }

        Long resourceId = resourcePoint != null ? resourcePoint.getId() : null;
        LambdaQueryWrapper<VppDrParticipation> wrapper = new LambdaQueryWrapper<VppDrParticipation>()
                .eq(VppDrParticipation::getEventId, event.getId())
                .eq(VppDrParticipation::getCustomerId, customer.getId())
                .eq(VppDrParticipation::getDeleteFlag, VppAuditHelper.NOT_DELETED);
        if (resourceId != null) {
            wrapper.eq(VppDrParticipation::getResourceId, resourceId);
        }

        VppDrParticipation participation = participationMapper.selectOne(wrapper);
        if (participation == null) {
            participation = new VppDrParticipation();
            participation.setEventId(event.getId());
            participation.setCustomerId(customer.getId());
            participation.setResourceId(resourceId);
            participation.setParticipateStatus(PARTICIPATE_STATUS_ACCEPT);
            participation.setDeclaredAt(LocalDateTime.now());
            VppAuditHelper.fillCreate(participation);
        }

        if (clearing) {
            participation.setClearedCapacityKw(load.abs());
        } else {
            participation.setDeclaredCapacityKw(load.abs());
        }
        VppDrParticipationHelper.refreshCompletionRate(participation);
        VppAuditHelper.fillUpdate(participation);
        if (participation.getId() == null) {
            participationMapper.insert(participation);
        } else {
            participationMapper.updateById(participation);
        }
    }

    private BigDecimal resolveLoadKw(Map<String, Object> item) {
        BigDecimal load = VppUnPayloadHelper.getDecimal(item, "load");
        if (load != null) {
            return load;
        }
        return VppUnEventParser.sumResourceLoadKw(java.util.Collections.singletonList(item), true);
    }
}
