package com.ym.mec.biz.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.ym.mec.biz.dal.dao.FinancialExpenditureDao;
import com.ym.mec.biz.dal.dto.FinancialExpenditureDto;
import com.ym.mec.biz.dal.entity.FinancialExpenditure;
import com.ym.mec.biz.dal.enums.ExpenditureTypeEnum;
import com.ym.mec.biz.dal.enums.FeeProjectEnum;
import com.ym.mec.biz.dal.enums.GoodsType;
import com.ym.mec.biz.dal.enums.TemplateTypeEnum;
import com.ym.mec.biz.dal.page.FinancialExpenditureQueryInfo;
import com.ym.mec.biz.service.FinancialExpenditureService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.QueryInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.excel.IniFileUtil;
import com.ym.mec.util.excel.POIUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FinancialExpenditureServiceImpl extends BaseServiceImpl<Long, FinancialExpenditure> implements FinancialExpenditureService {
	
	@Autowired
	private FinancialExpenditureDao financialExpenditureDao;

	@Override
	public BaseDAO<Long, FinancialExpenditure> getDAO() {
		return financialExpenditureDao;
	}

	private static final Logger LOGGER = LoggerFactory.getLogger(FinancialExpenditureServiceImpl.class);

	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<FinancialExpenditure> importFinancialExpenditure(MultipartFile file) throws Exception {
		Map<String, List<Map<String, Object>>> sheetsListMap = POIUtil.importExcel(new ByteArrayInputStream(file.getBytes()), 2, file.getOriginalFilename());
		InputStream inputStream = new ClassPathResource("columnMapper.ini").getInputStream();
		Map<String,String> columns = IniFileUtil.readIniFile(inputStream,TemplateTypeEnum.FINANCIAL_EXPENDITURE.getMsg());
		List<FinancialExpenditure> financialExpenditures = new ArrayList<>();
		Map<String, Integer> organMap = getMap("organization", "name_", "id_", true, String.class, Integer.class);
		Map<String, Integer> cooperationOrganMap = getMap("cooperation_organ", "name_", "id_", true, String.class, Integer.class);
//		Map<String, Integer> phoneMap = getMap("sys_user", "phone_", "id_", true, String.class, Integer.class);
		for (String e : sheetsListMap.keySet()) {
			List<Map<String, Object>> sheet = sheetsListMap.get(e);
			List<Object> collect = sheet.stream().map(m -> m.get("钉钉流程编号")).collect(Collectors.toList());
			if(collect == null || collect.size() == 0){
				continue;
			}
			List<String> list = financialExpenditureDao.countBydingTalk(collect);
			if(list != null && list.size() > 0){
				throw new BizException("导入数据错误  重复的钉钉流程编号:{}",list.get(0));
			}

			valueIsNull: for (Map<String, Object> row : sheet) {

				if (row.size() == 0){
					continue;
				}
				JSONObject objectMap = new JSONObject();
				for (String s : row.keySet()) {
					if(!columns.containsKey(s)){
						continue;
					}
					String columnValue = columns.get(s);
					if (columnValue.equals("type")) {
						for (ExpenditureTypeEnum expenditureType : ExpenditureTypeEnum.values()) {
							if (expenditureType.getDesc().equals(row.get(s).toString())) {
								objectMap.put(columnValue, expenditureType);
								break;
							}
						}
						continue;
					}
					if (columnValue.equals("dingtalkProcessNo")) {
						if(StringUtils.isEmpty(row.get(s).toString())){
							LOGGER.error("支出记录导入异常：钉钉流程编号不可为空 param:{}",objectMap);
							continue valueIsNull;
						}
					}
					if (columnValue.equals("feeProject")) {
						for (FeeProjectEnum feeProject : FeeProjectEnum.values()) {
							if (feeProject.getDesc().equals(row.get(s).toString())) {
								objectMap.put(columnValue, feeProject);
								break;
							}
						}
						continue;
					}
					if (columnValue.equals("amount")) {
						if(StringUtils.isEmpty(row.get(s).toString())){
							LOGGER.error("支出记录导入异常：费用不可为空 param:{}",objectMap);
							continue valueIsNull;
						}else {
							objectMap.put("amount", row.get(s));
						}
						continue;
					}
					if (columnValue.equals("organName") && StringUtils.isNotEmpty(row.get(s).toString())) {
						Integer integer = organMap.get(row.get(s));
						if(integer == null){
							LOGGER.error("支出记录导入异常：分部校验失败 param:{}",objectMap);
							continue valueIsNull;
						}else {
							objectMap.put("organId", integer);
						}
						continue;
					}
					if (columnValue.equals("cooperationOrganName") && StringUtils.isNotEmpty(row.get(s).toString())) {
						Integer integer = cooperationOrganMap.get(row.get(s));
						if(integer == null){
							LOGGER.error("支出记录导入异常：合作单位校验失败 param:{}",objectMap);
						}else {
							objectMap.put("cooperationOrganId", integer);
						}
						continue;
					}
					if (columnValue.equals("paymentTime") && StringUtils.isNotEmpty(row.get(s).toString())) {
						String toString = row.get(s).toString();
						if(StringUtils.isNotEmpty(toString)){
							Date date = DateUtil.stringToDate(toString, DateUtil.DEFAULT_PATTERN);
							if(date == null){
								throw new BizException("导入数据错误  付款时间格式错误");
							}else {
								objectMap.put(columnValue, DateUtil.format(date,DateUtil.DEFAULT_PATTERN));
							}
						}
						continue;
					}
					objectMap.put(columnValue, row.get(s));
				}
				FinancialExpenditure financialExpenditure = null;
				try {
					financialExpenditure = JSONObject.parseObject(objectMap.toJSONString(),FinancialExpenditure.class);
					financialExpenditures.add(financialExpenditure);
				} catch (Exception ex) {
					throw new BizException("导入数据出错,请检查Excel表格");
				}
			}
		}
		if(financialExpenditures.size() != 0){
			financialExpenditureDao.batchInsert(financialExpenditures);
		}
		return financialExpenditures;
	}

	@Override
	public PageInfo<FinancialExpenditureDto> queryFinancialExpenditurePage(FinancialExpenditureQueryInfo queryInfo){
		PageInfo<FinancialExpenditureDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<FinancialExpenditureDto> dataList = null;
		int count = financialExpenditureDao.findFinancialExpenditureCount(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = financialExpenditureDao.queryFinancialExpenditurePage(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public void batchDel(String ids) {
		if(StringUtils.isEmpty(ids)){
			throw new BizException("参数校验失败");
		}
		financialExpenditureDao.batchDel(ids);
	}
}