package pwc.taxtech.atms.service.impl;

import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pwc.taxtech.atms.common.AuthUserHelper;
import pwc.taxtech.atms.common.CommonUtils;
import pwc.taxtech.atms.common.OperateLogType;
import pwc.taxtech.atms.common.OperationModule;
import pwc.taxtech.atms.dto.BatchUpdateTaxRuleDto;
import pwc.taxtech.atms.dto.TaxPayerReportRuleDto;
import pwc.taxtech.atms.dto.TaxPayerReportRuleDtoOperation;
import pwc.taxtech.atms.dto.TaxRuleSettingDto;
import pwc.taxtech.atms.dto.TaxRuleSettingOperation;
import pwc.taxtech.atms.dto.organization.OrganizationDto;
import pwc.taxtech.atms.entitiy.OrganizationServiceTemplateGroup;
import pwc.taxtech.atms.entitiy.OrganizationServiceTemplateGroupExample;
import pwc.taxtech.atms.entitiy.TaxPayerReportRule;
import pwc.taxtech.atms.entitiy.TaxPayerReportRuleExample;
import pwc.taxtech.atms.entitiy.TaxRuleSetting;
import pwc.taxtech.atms.entitiy.TaxRuleSettingOrganization;
import pwc.taxtech.atms.entitiy.TaxRuleSettingOrganizationExample;
import pwc.taxtech.atms.service.OperationLogService;
import pwc.taxtech.atms.service.RuleEngineeConfigService;

@Service
public class RuleEngineeConfigServiceImpl extends AbstractService implements RuleEngineeConfigService {

	@Autowired
	OperationLogService operationService;
	
	@Autowired
	private AuthUserHelper authUserHelper;

	@Override
	public List<TaxPayerReportRuleDto> getTaxPayerReportMapping() {
		List<String> orgIDs = organizationMapper.selectOnlyIDAndParentID().stream().map(OrganizationDto::getID)
				.collect(Collectors.toList());
		List<TaxPayerReportRule> rules = taxPayerReportRuleMapper.selectByExample(new TaxPayerReportRuleExample());
		List<TaxPayerReportRule> filterRules = new ArrayList<>();

		for (TaxPayerReportRule rule : rules) {
			String[] selectedOrgIds = rule.getOrganizationID().split(",");
			boolean isAtLeastOrgExisted = false;

			for (String selectedOrgId : selectedOrgIds) {
				if (orgIDs.contains(selectedOrgId)) {
					isAtLeastOrgExisted = true;
				}
			}

			if (isAtLeastOrgExisted || rule.getIsDefault()) {
				filterRules.add(rule);
			}
		}

		List<TaxPayerReportRuleDto> dtoList = new ArrayList<>();
		for (TaxPayerReportRule rule : filterRules) {
			TaxPayerReportRuleDto ruleDto = new TaxPayerReportRuleDto();
			CommonUtils.copyProperties(rule, ruleDto);
			ruleDto.setOrgs(new ArrayList<>(Arrays.asList(rule.getOrganizationID().split(","))));
			dtoList.add(ruleDto);
		}
		return dtoList;
	}

	@Override
	public List<TaxRuleSettingDto> getTaxRuleSetting() {
		List<TaxRuleSettingDto> trsdList = taxRuleSettingMapper.GetTaxRuleSetting();

		List<String> orgIDs = trsdList.stream().map(TaxRuleSettingDto::getOrganizationID).collect(Collectors.toList());
		for (TaxRuleSettingDto trsd : trsdList) {
			trsd.setOrgs(orgIDs);
		}
		return trsdList;
	}

	@Override
	@Transactional(readOnly = true)
	public void savetaxrulesettings(BatchUpdateTaxRuleDto batchUpdateTaxRule) {
		for (TaxRuleSettingOperation trso : batchUpdateTaxRule.getTaxRuleSettingOperations()) {
			TaxRuleSetting taxRuleSetting = new TaxRuleSetting();
			CommonUtils.copyProperties(trso.getTaxRuleSetting(), taxRuleSetting);
			taxRuleSetting.setTaxBase(String.valueOf(Integer.parseInt(trso.getTaxRuleSetting().getTaxBase())/100));
			taxRuleSetting.setCreateTime(new Date());
			taxRuleSetting.setUpdateTime(new Date());

			if ("Add".equals(trso.getAction())) {
				SaveTaxRuleSettingOrg(trso, taxRuleSetting, authUserHelper.getCurrentUserID(), null);
				taxRuleSettingMapper.insert(taxRuleSetting);
			} else if ("Update".equals(trso.getAction())) {
				TaxRuleSettingOrganizationExample trsoExample = new TaxRuleSettingOrganizationExample();
				trsoExample.createCriteria().andOrganizationIDEqualTo(taxRuleSetting.getID());
				taxRuleSettingOrganizationMapper.deleteByExample(trsoExample);
				TaxRuleSetting old = taxRuleSettingMapper.selectByPrimaryKey(taxRuleSetting.getID());
				SaveTaxRuleSettingOrg(trso, taxRuleSetting, authUserHelper.getCurrentUserID(), old);
				old.setIsDefault(taxRuleSetting.getIsDefault());
				old.setName(taxRuleSetting.getName());
				old.setTaxBase(taxRuleSetting.getTaxBase());
				old.setTaxRate(taxRuleSetting.getTaxRate());
				old.setGroupName(taxRuleSetting.getGroupName());
				old.setCreateTime(taxRuleSetting.getCreateTime());
				old.setUpdateTime(taxRuleSetting.getUpdateTime());
				taxRuleSettingMapper.updateByPrimaryKey(old);
			} else if ("Delete".equals(trso.getAction())) {
				TaxRuleSettingOrganizationExample trsoExample = new TaxRuleSettingOrganizationExample();
				trsoExample.createCriteria().andOrganizationIDEqualTo(taxRuleSetting.getID());
				taxRuleSettingOrganizationMapper.deleteByExample(trsoExample);

				taxRuleSettingMapper.deleteByPrimaryKey(taxRuleSetting.getID());
				operationService.deleteDataAddLog(taxRuleSetting, OperationModule.RuleEngineConfig, authUserHelper.getCurrentUserID(),
						"DeleteRuleEngineConfiguration", "", taxRuleSetting.getName(),
						OperateLogType.OperationLogRuleEngine);
			}
		}
		
		for(TaxPayerReportRuleDtoOperation tprrdo:batchUpdateTaxRule.getTaxPayerReportRuleOperations()) {
			TaxPayerReportRuleDto reportDto = tprrdo.getTaxPayerReportRule();
			TaxPayerReportRule taxPayerReportRule = new TaxPayerReportRule();
			CommonUtils.copyProperties(reportDto, taxPayerReportRule);
			StringBuilder sb = new StringBuilder();
			for(String s: reportDto.getOrgs()){
				sb.append(s).append(",");
			}
			String tempStr = sb.toString();
			taxPayerReportRule.setOrganizationID(tempStr.substring(0,tempStr.length()-2));
			taxPayerReportRule.setCreateTime(new Date());
			taxPayerReportRule.setUpdateTime(new Date());
			SaveOrganizationServiceTemplateGroup(taxPayerReportRule,tprrdo.getAction());
			if("Add".equals(tprrdo.getAction())) {
				taxPayerReportRuleMapper.insert(taxPayerReportRule);
				operationService.addDataAddLog(taxPayerReportRule, OperationModule.RuleEngineConfig, authUserHelper.getCurrentUserID(),
                       "AddRuleEngineConfiguration", "纳税类型", "纳税类型添加特殊机构", OperateLogType.OperationLogRuleEngine);
			}
			else if("Update".equals(tprrdo.getAction())) {
				TaxPayerReportRule old = taxPayerReportRuleMapper.selectByPrimaryKey(reportDto.getID());
				TaxPayerReportRule original = new TaxPayerReportRule();
				CommonUtils.copyProperties(old, original);

				old.setIsDefault(taxPayerReportRule.getIsDefault());
				old.setOrganizationID(taxPayerReportRule.getOrganizationID());
				old.setTaxPayerType(taxPayerReportRule.getTaxPayerType());
				old.setTemplateGroupID(taxPayerReportRule.getTemplateGroupID());
				old.setCreateTime(taxPayerReportRule.getCreateTime());
				old.setUpdateTime(taxPayerReportRule.getUpdateTime());
				
				taxPayerReportRuleMapper.updateByPrimaryKey(old);
				operationService.updateDataAddLog(original, taxPayerReportRule, OperationModule.RuleEngineConfig, authUserHelper.getCurrentUserID(),
      "UpdateRuleEngineConfiguration", "纳税类型", taxPayerReportRule.getIsDefault() ? "默认纳税类型或默认纳税报表" : "纳税类型更新特殊机构", OperateLogType.OperationLogRuleEngine);
				
			}
			else if("Delete".equals(tprrdo.getAction())) {
				taxPayerReportRuleMapper.deleteByPrimaryKey(taxPayerReportRule.getID());
				operationService.deleteDataAddLog(reportDto, OperationModule.RuleEngineConfig, authUserHelper.getCurrentUserID(),
						"DeleteRuleEngineConfiguration", "纳税类型", "纳税类型删除特殊机构", OperateLogType.OperationLogRuleEngine);
			}
		}
	}

	private void SaveTaxRuleSettingOrg(TaxRuleSettingOperation taxRuleSettingOperation, TaxRuleSetting taxRuleSetting,
			String userName, TaxRuleSetting old) {
		for (String org : taxRuleSettingOperation.getTaxRuleSetting().getOrgs()) {
			TaxRuleSettingOrganization trso = new TaxRuleSettingOrganization();
			trso.setID(CommonUtils.getUUID());
			trso.setOrganizationID(org);
			trso.setTaxSettingID(taxRuleSetting.getID());
			trso.setUpdateTime(new Date());
			trso.setCreateTime(new Date());
			if ("Add".equals(taxRuleSettingOperation.getAction())) {
				operationLogService.addDataAddLog(taxRuleSetting, OperationModule.RuleEngineConfig, userName,
						"AddRuleEngineConfiguration", taxRuleSetting.getName() + org, taxRuleSetting.getName(),
						OperateLogType.OperationLogRuleEngine);
			} else {
				TaxRuleSetting original = new TaxRuleSetting();
				CommonUtils.copyProperties(old, original);
				operationService.updateDataAddLog(original, taxRuleSetting, OperationModule.RuleEngineConfig, userName,
						"UpdateRuleEngineConfiguration", taxRuleSetting.getName(),
						taxRuleSetting.getIsDefault() ? "默认税基或默认税率" : taxRuleSetting.getName(),
						OperateLogType.OperationLogRuleEngine);
			}
		}
	}
	
	private void SaveOrganizationServiceTemplateGroup(TaxPayerReportRule taxPayerReportRule, String action) {
		OrganizationServiceTemplateGroupExample example = new OrganizationServiceTemplateGroupExample();
		example.createCriteria().andOrganizationIDEqualTo(taxPayerReportRule.getOrganizationID()).andServiceTypeIDEqualTo("2");
		Optional<OrganizationServiceTemplateGroup> thisOrgTemplate = organizationServiceTemplateGroupMapper.selectByExample(example).stream().findFirst();
		
		if("Delete".equals(action)) {
			thisOrgTemplate.ifPresent(organizationServiceTemplateGroup -> organizationServiceTemplateGroupMapper.deleteByPrimaryKey(organizationServiceTemplateGroup.getID()));
		}
		else
		{
			if(thisOrgTemplate.isPresent()) {
				OrganizationServiceTemplateGroup organizationServiceTemplateGroup = thisOrgTemplate.get();
				if(organizationServiceTemplateGroup.getTemplateGroupID().equals(taxPayerReportRule.getTemplateGroupID())) {
					//不用改
				}
				else
				{
					organizationServiceTemplateGroup.setTemplateGroupID(taxPayerReportRule.getTemplateGroupID());
					organizationServiceTemplateGroupMapper.updateByPrimaryKeySelective(organizationServiceTemplateGroup);
				}
			}
			else {
				OrganizationServiceTemplateGroup entity = new OrganizationServiceTemplateGroup();
				
				entity.setID(CommonUtils.getUUID());
				entity.setServiceTypeID("2");
				entity.setTemplateGroupID(taxPayerReportRule.getTemplateGroupID());
				entity.setOrganizationID(taxPayerReportRule.getOrganizationID());
				organizationServiceTemplateGroupMapper.insert(entity);
			}
		}
	}

}