package pwc.taxtech.atms.service.impl;

import cn.pwc.soap.client.GLBalanceClient;
import cn.pwc.soap.client.common.BasicUser;
import cn.pwc.soap.client.domain.GLBalanceDto;
import cn.pwc.soap.client.domain.GlBalanceParam;
import cn.pwc.soap.client.domain.SoapResponse;
import com.alibaba.fastjson.JSON;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.common.ServiceException;
import pwc.taxtech.atms.common.config.SystemConfig;
import pwc.taxtech.atms.common.util.CommonUtil;
import pwc.taxtech.atms.constant.Constant;
import pwc.taxtech.atms.dao.EnterpriseAccountMapper;
import pwc.taxtech.atms.dao.EnterpriseAccountSetOrgMapper;
import pwc.taxtech.atms.dao.OrganizationMapper;
import pwc.taxtech.atms.entity.*;
import pwc.taxtech.atms.vat.dao.GlBalanceMapper;
import pwc.taxtech.atms.vat.entity.GlBalance;
import pwc.taxtech.atms.vat.entity.GlBalanceExample;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class LgGlBalanceService extends BaseService {
    @Resource
    private SystemConfig systemConfig;
    @Resource(name = "enterpriseAccountMapper")
    private EnterpriseAccountMapper accountMapper;
    @Resource(name = "enterpriseAccountSetOrgMapper")
    private EnterpriseAccountSetOrgMapper setOrgMapper;
    @Resource
    private GlBalanceMapper glBalanceMapper;
    @Resource
    private OrganizationMapper organizationMapper;

    /**
     * 科目余额数据同步
     *
     * @param org    Organization
     * @param period YYYY-MM
     * @throws ServiceException ex
     */
    public void queryGlBalance(Organization org, String period) throws ServiceException {
        if (StringUtils.isBlank(systemConfig.getLongiApiGlBalance())) {
            throw new ServiceException("EmptyUrlError");
        }
        //查找mapping
        EnterpriseAccountSetOrgExample setOrgExample = new EnterpriseAccountSetOrgExample();
        setOrgExample.createCriteria().andOrganizationIdEqualTo(org.getId());
        EnterpriseAccountSetOrg accountSetOrg = setOrgMapper.selectByExample(setOrgExample).get(0);
        //查找企业账套
        EnterpriseAccountExample accountExample = new EnterpriseAccountExample();
        accountExample.createCriteria().andEnterpriseAccountSetIdEqualTo(accountSetOrg.getEnterpriseAccountSetId());
        List<EnterpriseAccount> accountList = accountMapper.selectByExample(accountExample);
        for (EnterpriseAccount account : accountList) {
            SoapResponse<List<GLBalanceDto>> response = GLBalanceClient.queryGLBalance(systemConfig.getLongiApiGlBalance(),
                    new GlBalanceParam(org.getClientCode(), period, account.getCode()),
                    StringUtils.isAnyBlank(systemConfig.getLongiApiBasicUser(), systemConfig.getLongiApiBasicPwd()) ?
                            null : new BasicUser(systemConfig.getLongiApiBasicUser(), systemConfig.getLongiApiBasicPwd()));
            if (response.getStatus() != SoapResponse.SUCCESS) {
                logger.error("queryGLBalance error." + JSON.toJSONString(response));
                throw new ServiceException("ErrorResponse");
            }
            //分组求和 需求确认by  sherry
            response.getData().stream().collect(Collectors.groupingBy(o -> StringUtils.joinWith("_",
                    o.getSegment1(), o.getSegment3(), o.getSegment4()))).values().forEach(list -> {
                GlBalance glBalance = new GlBalance();
                GLBalanceDto sum = sum(list);
                beanUtil.copyProperties(sum, glBalance);

                glBalance.setPeriodName(period);
                GlBalanceExample example = new GlBalanceExample();
                example.createCriteria().andSegment1EqualTo(glBalance.getSegment1()).andSegment3EqualTo(glBalance.getSegment3())
                        .andSegment4EqualTo(glBalance.getSegment4()).andPeriodNameEqualTo(period);
                List<GlBalance> tmpList;
                if ((tmpList = glBalanceMapper.selectByExample(example)).size() > 0) {
                    glBalance.setId(tmpList.get(0).getId());
                    glBalanceMapper.updateByPrimaryKeySelective(glBalance);
                } else {
                    glBalance.setId(idService.nextId());
                    glBalanceMapper.insertSelective(glBalance);
                }
            });

        }
    }

    /**
     * 科目余额数据同步
     *
     * @param orgId  String
     * @param period YYYY-MM
     * @throws ServiceException ex
     */
    public void queryGlBalance(String orgId, String period) throws ServiceException {
        Organization org = organizationMapper.selectByPrimaryKey(orgId);
        if (null == org) {
            return;
        }
        queryGlBalance(org, period);
    }

    /**
     * @param orgId      String
     * @param fromPeriod Integer
     * @param toPeriod   Integer
     * @throws ServiceException ex
     */
    public void queryGlBalance(String orgId, Integer fromPeriod, Integer toPeriod) throws ServiceException {
        Calendar calendar = Calendar.getInstance();
        for (int i = fromPeriod; i <= toPeriod; i++) {
            calendar.set(Calendar.MONTH, i - 1);
            SimpleDateFormat dateFormat = new SimpleDateFormat(Constant.DateFormat.YEAR_MONTH);
            queryGlBalance(orgId, dateFormat.format(calendar.getTime()));
        }
    }

    private GLBalanceDto sum(List<GLBalanceDto> list) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        GLBalanceDto result = list.get(0);
        list.subList(1, list.size()).forEach(o -> {
            result.setBeginCrBalance(CommonUtil.add(result.getBeginCrBalance(), o.getBeginCrBalance()));
            result.setBeginDrBalance(CommonUtil.add(result.getBeginDrBalance(), o.getBeginDrBalance()));
            result.setEndCrBalance(CommonUtil.add(result.getEndCrBalance(), o.getEndCrBalance()));
            result.setEndDrBalance(CommonUtil.add(result.getEndDrBalance(), o.getEndDrBalance()));
            result.setPtdCr(CommonUtil.add(result.getPtdCr(), o.getPtdCr()));
            result.setPtdDr(CommonUtil.add(result.getPtdDr(), o.getPtdDr()));
            result.setYtdCr(CommonUtil.add(result.getYtdCr(), o.getYtdCr()));
            result.setYtdDr(CommonUtil.add(result.getYtdDr(), o.getYtdDr()));
        });
        return result;
    }

}