package cn.superdesk.uniorder.dubbo.provider.invoice.customer.invoiced;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.invoice.InvoiceInvoicedOperationLogOperationTypeEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.invoice.customer.invoiced.InvoiceInvoiced;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dto.param.invoice.customer.invoiced.*;
import cn.superdesk.uniorder.dto.param.invoice.excel.*;
import cn.superdesk.uniorder.dto.vo.invoice.customer.invoiced.InvoiceInvoicedExcelExportVo;
import cn.superdesk.uniorder.dto.vo.invoice.customer.invoiced.InvoiceInvoicedHeadSum;
import cn.superdesk.uniorder.dubbo.facade.invoice.customer.invoiced.DubboInvoiceInvoicedService;
import cn.superdesk.uniorder.dubbo.facade.sys.notify.DubboSysNotifyService;
import cn.superdesk.uniorder.service.invoice.customer.invoiced.InvoiceInvoicedExportExcelService;
import cn.superdesk.uniorder.service.invoice.customer.invoiced.InvoiceInvoicedOperationLogService;
import cn.superdesk.uniorder.service.invoice.customer.invoiced.InvoiceInvoicedService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * @Description:
 * @Author: linjinyu
 * @Email linjinyu@avic-s.com
 * @CreateDate: 2021-03-16 17:29:47
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021-03-16 17:29:47
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service(version = "1.0.0", retries = -1, timeout = 600000)
public class DubboInvoiceInvoicedServiceImpl implements DubboInvoiceInvoicedService {

	@Autowired
	private InvoiceInvoicedService            invoiceInvoicedService;
	@Autowired
	private InvoiceInvoicedExportExcelService invoiceInvoicedExportExcelService;

	@Autowired
	private InvoiceInvoicedOperationLogService invoiceInvoicedOperationLogService;

	@Reference(version = "1.0.0", timeout = 10000, retries = -1)
	private DubboSysNotifyService dubboSysNotifyService;


	/****************************************** extends BaseService 部分 start ******************************************/

	@Override
	public void addObj(InvoiceInvoicedParam param) {

		InvoiceInvoiced invoiceInvoiced = AnBeanUtils.copy(param, InvoiceInvoiced.class);
		invoiceInvoicedService.insertSelective(invoiceInvoiced);

	}

	@Override
	public void updateObj(InvoiceInvoicedParam param) {

		InvoiceInvoiced invoiceInvoiced = AnBeanUtils.copy(param, InvoiceInvoiced.class);
		invoiceInvoicedService.updateByPrimaryKeySelective(invoiceInvoiced);
	}

	@Override
	public void deleteObj(Long id) {
		invoiceInvoicedService.deleteObj(id);
	}

	@Override
	public InvoiceInvoiced findById(Long id) {
		return invoiceInvoicedService.findById(id);
	}

	@Override
	public PageInfo<InvoiceInvoiced> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
		return invoiceInvoicedService.findByPaging(conditions, pageNun, pageSize);
	}

	@Override
	public List<InvoiceInvoiced> findAll(Map<String, Object> queryMap) {

		return invoiceInvoicedService.findAll(queryMap);
	}

	/****************************************** extends BaseService 部分   end ******************************************/


	@Override
	public void addInvoiceInvoiced(InvoiceInvoicedParam param) {

		InvoiceInvoiced invoiceInvoiced = AnBeanUtils.copy(param, InvoiceInvoiced.class);
		invoiceInvoicedService.addInvoiceInvoiced(invoiceInvoiced);
	}

	@Override
	public void updateInvoiceInvoiced(InvoiceInvoicedParam param) {

		InvoiceInvoiced invoiceInvoiced = AnBeanUtils.copy(param, InvoiceInvoiced.class);
		invoiceInvoicedService.updateInvoiceInvoiced(invoiceInvoiced);
	}

	@Override
	public void updateInvoiceInvoiced(InvoiceInvoiced entity) {

		invoiceInvoicedService.updateInvoiceInvoiced(entity);
	}

	@Override
	public void updateInvoiceInvoicedByPrimaryKeySelective(InvoiceInvoiced entity) {

		invoiceInvoicedService.updateInvoiceInvoicedByPrimaryKeySelective(entity);
	}

	public void updateOpFields(InvoiceInvoicedOpUpdateFieldsForm form, LoginSysUser loginSysUser) {

		InvoiceInvoiced entity = invoiceInvoicedService.findInvoiceInvoicedById(form.getId());

		InvoiceInvoiced forUpdate = new InvoiceInvoiced();
		forUpdate.setId(form.getId());

		if (null != form.getInvoiceTypeId()) {
			forUpdate.setInvoiceTypeId(form.getInvoiceTypeId());
			forUpdate.setInvoiceType(form.getInvoiceType());
		}

		if (null != form.getInvoicedDate()) {
			forUpdate.setInvoicedDate(form.getInvoicedDate());
		}

		if (null != form.getBackCollectionTime()) {
			forUpdate.setBackCollectionTime(form.getBackCollectionTime());
		}

		if (null != form.getRemarks()) {
			forUpdate.setRemarks(form.getRemarks());
		}

		forUpdate.setUpdateTime(DateUtil.date());
		forUpdate.setUpdateUserId(loginSysUser.getSysUserId());
		forUpdate.setUpdateUserName(loginSysUser.getFullName());

		invoiceInvoicedService.updateInvoiceInvoicedByPrimaryKeySelective(forUpdate);

		// 操作日志
		invoiceInvoicedOperationLogService.commonOperationLog(entity, forUpdate, form, loginSysUser, InvoiceInvoicedOperationLogOperationTypeEnum.编辑操作);
	}

	/**
	 * 更新备注
	 *
	 * @param form
	 * @param loginSysUser
	 */
	@Override
	public void updateOpRemark(InvoiceInvoicedOpUpdateFieldRamarkForm form, LoginSysUser loginSysUser) {

		InvoiceInvoiced entity = invoiceInvoicedService.findInvoiceInvoicedById(form.getId());

		InvoiceInvoiced forUpdate = new InvoiceInvoiced();
		forUpdate.setId(form.getId());
		forUpdate.setRemarks(form.getRemark());

		forUpdate.setUpdateTime(DateUtil.date());
		forUpdate.setUpdateUserId(loginSysUser.getSysUserId());
		forUpdate.setUpdateUserName(loginSysUser.getFullName());

		invoiceInvoicedService.updateInvoiceInvoicedByPrimaryKeySelective(forUpdate);

		// 操作日志
		invoiceInvoicedOperationLogService.commonOperationLog(entity, forUpdate, form, loginSysUser, InvoiceInvoicedOperationLogOperationTypeEnum.编辑操作_更新备注);
	}

	/**
	 * 产品美其言为 调整组织关系
	 *
	 * @param form
	 * @param loginSysUser
	 */
	public void batchUpdateFields(InvoiceInvoicedOpBatchUpdateFieldsForm form, LoginSysUser loginSysUser) {


		List<Long> ids = form.getInvoiceInvoicedIdList();

		ids.forEach(item -> {

			InvoiceInvoiced entity    = invoiceInvoicedService.findInvoiceInvoicedById(item);
			InvoiceInvoiced forUpdate = new InvoiceInvoiced();
			forUpdate.setId(item);

			/****************************************** 公司主体 start ******************************************/

			if (null != form.getSellerMainId()) {
				forUpdate.setSellerMainId(form.getSellerMainId());
				forUpdate.setSellerCompanyName(form.getSellerCompanyName());
				// TODO 还有要更新的
			}


			/****************************************** 项目 start ******************************************/

			if (null != form.getOutOrgId()) {
				forUpdate.setOutOrgId(form.getOutOrgId());
				forUpdate.setOutOrgName(form.getOutOrgName());
			}

			/****************************************** 项目企业 start ******************************************/

			if (null != form.getOutVirtId()) {
				forUpdate.setOutVirtId(form.getOutVirtId());
				forUpdate.setOutVirtName(form.getOutVirtName());
			}

			/****************************************** 客户经理 start ******************************************/

			if (null != form.getCustomerManagerId()) {
				forUpdate.setCustomerManagerId(form.getCustomerManagerId());
				forUpdate.setCustomerManagerName(form.getCustomerManagerName());
			}

			forUpdate.setUpdateTime(DateUtil.date());
			forUpdate.setUpdateUserId(loginSysUser.getSysUserId());
			forUpdate.setUpdateUserName(loginSysUser.getFullName());

			// TODO 优化点为 批量更新 有空再做吧
			invoiceInvoicedService.updateInvoiceInvoicedByPrimaryKeySelective(forUpdate);

			// 操作日志
			invoiceInvoicedOperationLogService.commonOperationLog(entity, forUpdate, form, loginSysUser, InvoiceInvoicedOperationLogOperationTypeEnum.编辑操作_调整组织关系);
		});
	}


	@Override
	public void deleteInvoiceInvoiced(Long id) {
		invoiceInvoicedService.deleteInvoiceInvoiced(id);
	}

	@Override
	public InvoiceInvoiced findInvoiceInvoicedById(Long id) {
		return invoiceInvoicedService.findInvoiceInvoicedById(id);
	}

	@Override
	public InvoiceInvoiced findInvoiceInvoicedByInvoiceNumber(String invoiceNumber) {
		return invoiceInvoicedService.findInvoiceInvoicedByInvoiceNumber(invoiceNumber);
	}

	@Override
	public R<List<InvoiceInvoiced>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {
		return invoiceInvoicedService.pageQuery(conditions, pageNun, pageSize);

	}

	@Override
	public R<List<InvoiceInvoicedExcelExportVo>> pageQueryByCriteria(InvoiceInvoicedQueryCriteria criteria) {
		return invoiceInvoicedService.pageQueryByCriteria(criteria);
	}

	@Override
	public List<InvoiceInvoicedExcelExportVo> queryByCriteria(InvoiceInvoicedQueryCriteria criteria) {
		return invoiceInvoicedService.queryByCriteria(criteria);
	}


	@Override
	public R<InvoiceInvoicedHeadSum> headSumInvoiceInvoiceds(InvoiceInvoicedQueryCriteria criteria) {
		return invoiceInvoicedService.headSumInvoiceInvoiceds(criteria);
	}


	/****************************************** excel export start ******************************************/

	@Override
	public String exportInvoiceInvoiceds(InvoiceInvoicedQueryCriteria criteria, LoginSysUser loginSysUser) {

		// 异步操作 包裹 mark by linjinyu at 20210305
		log.info("\n异步操作 包裹 外层 exportInvoiceInvoiceds params: \n{}", AnJsonUtils.toJson(criteria));

		CompletableFuture.runAsync(() -> {

			try {

				// 三步走 mark by linjinyu at 20210305
				// 1. 数据
				// 2. 生成excel
				// 3. 通知
				// TODO 排序 invoiced_date 升
				criteria.setOrderByClause("invoiced_date asc");
				List<InvoiceInvoicedExcelExportVo> exportData = queryByCriteria(criteria);

				SysNotify sysNotify = invoiceInvoicedExportExcelService.exportExcelInvoiceInvoiceds(exportData);

				// 通知
				dubboSysNotifyService.notifyExportExcelInvoiceInvoiceds(sysNotify, loginSysUser);


			} catch (Exception e2) {
				log.error("\n异步操作 包裹 内层 exportInvoiceInvoiceds{} -> 执行 异常:{}", AnJsonUtils.toJson(criteria), e2);
			}
		});

		return "导出任务已经接收,正在处理中...";
	}

	/****************************************** excel import start ******************************************/
	/**
	 * 基于 税局的 发票号码 来作唯一处理
	 *
	 * @param excelRow
	 * @param loginSysUser
	 */
	@Override
	public void saveOrUpdate4ThirdPartTaxationSzhtxxE6ExcelRowByInvoiceNumber(TaxationSzhtxxE6ExcelRow excelRow, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4ThirdPartTaxationSzhtxxE6ExcelRowByInvoiceNumber(excelRow, loginSysUser);
	}

	/**
	 * @param excelRowList
	 * @param loginSysUser
	 */
	@Override
	public void saveOrUpdate4ThirdPartTaxationSzhtxxE6ExcelRowListByInvoiceNumber(List<TaxationSzhtxxE6ExcelRow> excelRowList, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4ThirdPartTaxationSzhtxxE6ExcelRowListByInvoiceNumber(excelRowList, loginSysUser);
	}

	@Override
	public void saveOrUpdate4ThirdPartTaxationYqzs17WinV30ExcelRowByInvoiceNumber(TaxationYqzs17WinV30ExcelRow excelRow, LoginSysUser loginSysUser) {

		if (null == excelRow) {
			return;
		}
		invoiceInvoicedService.saveOrUpdate4ThirdPartTaxationYqzs17WinV30ExcelRowByInvoiceNumber(excelRow, loginSysUser);

	}

	@Override
	public void saveOrUpdate4ThirdPartTaxationYqzs17WinV30ExcelRowListByInvoiceNumber(List<TaxationYqzs17WinV30ExcelRow> excelRowList, LoginSysUser loginSysUser) {

		invoiceInvoicedService.saveOrUpdate4ThirdPartTaxationYqzs17WinV30ExcelRowListByInvoiceNumber(excelRowList, loginSysUser);
	}

	@Override
	public void saveOrUpdate4SuperdeskFinanceArtificial001ExcelRowByInvoiceNumber(SuperdeskFinanceArtificial001ExcelRow excelRow, LoginSysUser loginSysUser) {

		if (null == excelRow) {
			return;
		}

		invoiceInvoicedService.saveOrUpdate4SuperdeskFinanceArtificial001ExcelRowByInvoiceNumber(excelRow, loginSysUser);
	}

	@Override
	public void saveOrUpdate4SuperdeskFinanceArtificial001ExcelRowListByInvoiceNumber(List<SuperdeskFinanceArtificial001ExcelRow> excelRowList, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4SuperdeskFinanceArtificial001ExcelRowListByInvoiceNumber(excelRowList, loginSysUser);
	}


	@Override
	public void saveOrUpdate4InvoiceInvoicedHistoryExcelRowByInvoiceNumber(InvoiceInvoicedHistoryExcelRow excelRow, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4InvoiceInvoicedHistoryExcelRowByInvoiceNumber(excelRow, loginSysUser);
	}

	@Override
	public void saveOrUpdate4InvoiceInvoicedHistoryExcelRowListByInvoiceNumber(List<InvoiceInvoicedHistoryExcelRow> excelRowList, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4InvoiceInvoicedHistoryExcelRowListByInvoiceNumber(excelRowList, loginSysUser);
	}

	@Override
	public void saveOrUpdate4InvoiceInvoicedNormalExcelRowByInvoiceNumber(InvoiceInvoicedNormalExcelRow excelRow, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4InvoiceInvoicedNormalExcelRowByInvoiceNumber(excelRow, loginSysUser);
	}

	@Override
	public void saveOrUpdate4InvoiceInvoicedNormalExcelRowListByInvoiceNumber(List<InvoiceInvoicedNormalExcelRow> excelRowList, LoginSysUser loginSysUser) {
		invoiceInvoicedService.saveOrUpdate4InvoiceInvoicedNormalExcelRowListByInvoiceNumber(excelRowList, loginSysUser);
	}
}
