package pwc.taxtech.atms.dao;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.common.CommonConstants;
import pwc.taxtech.atms.common.CommonUtils;
import pwc.taxtech.atms.entity.AccountMapping;
import pwc.taxtech.atms.entity.AccountMappingExample;
import pwc.taxtech.atms.entity.EnterpriseAccount;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class AccountMappingDao {
    @Autowired
    AccountMappingMapper mapper;
    @Autowired
    EnterpriseAccountDao epAccountDao;
    @Autowired
    AccountMappingManualDao mappingManualDao;

    public void delByEpAccountCodeList(List<String> codeList) {
        if (CollectionUtils.isNotEmpty(codeList)) {
            AccountMappingExample example = new AccountMappingExample();
            AccountMappingExample.Criteria criteria = example.createCriteria();
            criteria.andEnterpriseAccountCodeIn(codeList);
            mapper.deleteByExample(example);
        }
    }

    public boolean isStdExists(String accountSetId, String enterpirseAccountCode, String industryId, String orgId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountCodeEqualTo(enterpirseAccountCode);
        criteria.andEnterpriseAccountSetIdEqualTo(accountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        criteria.andIndustryIdEqualTo(industryId);
        criteria.andStandardAccountCodeNotEqualTo(CommonConstants.EmptyStdCode);
        return mapper.countByExample(example) > 0;
    }

    private void updateToTable(String accountCode, String accountSetId, String stdAccountCode,
                               String industryId, String enterpriseAccountId, String orgId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountCodeEqualTo(accountCode);
        criteria.andEnterpriseAccountSetIdEqualTo(accountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        criteria.andIndustryIdEqualTo(industryId);
        mapper.deleteByExample(example);

        AccountMapping mapping = new AccountMapping();
        mapping.setId(CommonUtils.getUUID());
        mapping.setEnterpriseAccountCode(accountCode);
        mapping.setEnterpriseAccountSetId(accountSetId);
        mapping.setOrganizationId(orgId);
        mapping.setStandardAccountCode(stdAccountCode);
        mapping.setIndustryId(industryId);
        mapper.insertSelective(mapping);
    }

    public void mapStdAccountByCode(String accountSetId, String stdAccountCode, String accountCode,
                                    String industryId, String orgId, boolean bOverwrite, int acctLevel) {

        String enterpriseAccountId = epAccountDao.getEpAccountId(accountCode, accountSetId);

        if (StringUtils.isBlank(stdAccountCode))
            stdAccountCode = CommonConstants.NullStdCode;

        //region 新逻辑
        if (!bOverwrite) {
            if (!isStdExists(accountSetId, accountCode, industryId, orgId)) {
                updateToTable(accountCode, accountSetId, stdAccountCode, industryId, enterpriseAccountId, orgId);
            }
        } else {
            updateToTable(accountCode, accountSetId, stdAccountCode, industryId, enterpriseAccountId, orgId);
        }
        //endregion
    }

    public List<AccountMapping> getAccountMapping(String epAccountCode, String epAccountSetId, String orgId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountCodeEqualTo(epAccountCode);
        criteria.andEnterpriseAccountSetIdEqualTo(epAccountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        return mapper.selectByExample(example);
    }

    public List<AccountMapping> getAccountMapping(String epAccountSetId, String orgId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountSetIdEqualTo(epAccountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        return mapper.selectByExample(example);
    }

    public void delMapping(String epAccountCode, String epAccountSetId, String orgId, String industryId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountCodeEqualTo(epAccountCode);
        criteria.andEnterpriseAccountSetIdEqualTo(epAccountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        criteria.andIndustryIdEqualTo(industryId);
        mapper.deleteByExample(example);
    }

    public void delMapping(String epAccountSetId, String orgId, String industryId) {
        AccountMappingExample example = new AccountMappingExample();
        AccountMappingExample.Criteria criteria = example.createCriteria();
        criteria.andEnterpriseAccountSetIdEqualTo(epAccountSetId);
        criteria.andOrganizationIdEqualTo(orgId);
        criteria.andIndustryIdEqualTo(industryId);
        mapper.deleteByExample(example);
    }

    public void clearMapping(List<EnterpriseAccount> eaList, String industryId,
                             String orgId, Boolean isToClearAllMapping) {
        if (CollectionUtils.isEmpty(eaList)) {
            return;
        }
        List<String> codeList = eaList.stream().map(EnterpriseAccount::getCode).collect(Collectors.toList());
        if (!isToClearAllMapping) {
            for (EnterpriseAccount ea : eaList) {
                delMapping(ea.getCode(), ea.getEnterpriseAccountSetId(), industryId, orgId);
                //同时删除手动对应表的对应关系
                mappingManualDao.delMapping(ea.getFullName(), ea.getEnterpriseAccountSetId(), industryId, orgId);

                clearChildMapping(ea.getCode(), ea.getEnterpriseAccountSetId(), industryId, orgId, codeList);
            }
        } else {
            delMapping(eaList.get(0).getEnterpriseAccountSetId(), industryId, orgId);
        }
    }

    private void clearChildMapping(String eaCode, String setId, String industryId, String orgId, List<String> codeList) {
        List<EnterpriseAccount> list = epAccountDao.getEpAccountBy(eaCode, setId);
        for (EnterpriseAccount row : list) {
            String code = row.getCode();
            //如果在本身的id里面包含了,说明第一次遍历的时候已经更新过数据库了,不需要再一次更新
            if (codeList.contains(code)) continue;
            //string updatesql = "UPDATE EnterpriseAccount SET StdCode=NULL WHERE id=@id";
            delMapping(code, setId, orgId, industryId);
            clearChildMapping(row.getCode(), row.getEnterpriseAccountSetId(), industryId, orgId, codeList);
        }
    }
}