/*
 *    Copyright (c) 2018-2025, hnqz All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: hnqz
 */
package com.qunzhixinxi.hnqz.admin.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
import com.qunzhixinxi.hnqz.admin.api.entity.SysDept;
import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
import com.qunzhixinxi.hnqz.admin.config.TaxNotifyConfig;
import com.qunzhixinxi.hnqz.admin.entity.WmDaAgent;
import com.qunzhixinxi.hnqz.admin.entity.WmDaDrugEnt;
import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
import com.qunzhixinxi.hnqz.admin.entity.WmTaskSettleNote;
import com.qunzhixinxi.hnqz.admin.entity.output.WmTaskSettleNoteOutput;
import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageMapper;
import com.qunzhixinxi.hnqz.admin.mapper.WmTaskSettleNoteMapper;
import com.qunzhixinxi.hnqz.admin.service.*;
import com.qunzhixinxi.hnqz.common.core.util.R;
import com.qunzhixinxi.hnqz.common.taxhelper.config.TaxHelperConfig;
import com.qunzhixinxi.hnqz.common.taxhelper.entity.model.TaxHelperSettlementModel;
import com.qunzhixinxi.hnqz.common.taxhelper.entity.request.TaxHelperSettlementRequest;
import com.qunzhixinxi.hnqz.common.taxhelper.entity.response.TaxHelperResponse;
import com.qunzhixinxi.hnqz.common.taxhelper.enums.TaxHelperCertStatus;
import com.qunzhixinxi.hnqz.common.taxhelper.service.TaxHelperService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author winter
 * @date 2021-03-03 18:15:22
 */
@Slf4j
@AllArgsConstructor
@Service
public class WmTaskSettleNoteServiceImpl extends ServiceImpl<WmTaskSettleNoteMapper, WmTaskSettleNote> implements WmTaskSettleNoteService {

	/**
	 * 待枚举
	 * 0-未结算 1-结算成功 2-结算失败  3-提交结算成功  9-提交结算申请
	 */

	private final WmTaskSettleNoteMapper wmTaskSettleNoteMapper;
	private final WmScorePackageMapper wmScorePackageMapper;
	private final SysUserService sysUserService;
	private final SysDeptService deptService;
	private final WmDaAgentService wmDaAgentService;
	private final WmDaDrugEntService wmDaDrugEntService;
	private final TaxHelperService taxHelperService;
	private final RedisTemplate redisTemplate;
	private final WmScorePackageService wmScorePackageService;

	private final TaxNotifyConfig taxNotifyConfig;

	/**
	 * 批量结算
	 *
	 * @param note
	 * @return
	 */
	@Override
	public R batchSettle(WmTaskSettleNote note) {

		String[] ids = note.getIdStr().split(",");
		StringBuilder noticeInfo = new StringBuilder();
		for (int i = 0; i < ids.length; i++) {
			String id = ids[i];
			WmTaskSettleNote settleNote = this.baseMapper.selectById(id);
			WmScorePackage wmScorePackage = wmScorePackageMapper.selectById(settleNote.getPackageId());

			if (9 != settleNote.getSettleNoteStatus() && 2 != settleNote.getSettleNoteStatus()) {
				continue;
			}
			if (StringUtils.isEmpty(settleNote.getUserId())) {
				continue;
			}
			SysUser sysUser = sysUserService.getById(settleNote.getUserId());
			SysDept dept = deptService.getById(sysUser.getDeptId());

			if (null != dept && StringUtils.isNotEmpty(dept.getAppId()) && "1".equals(dept.getSubjectType())) {
				log.info("税邦云结算开始：{} ", dept.getSubjectName());
			} else {
				return R.failed("结算信息配置有误");

			}
			String shCode = "";
			WmDaAgent agent = wmDaAgentService.selectByDeptId(dept.getDeptId());
			WmDaDrugEnt drugEnt = wmDaDrugEntService.selectByDeptId(dept.getDeptId());
			if (null != agent) {
				shCode = agent.getZjNumber();
			}else {
				shCode = drugEnt.getEntcode();
			}
			if(StringUtils.isNotEmpty(shCode)){
				log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码：{} ", shCode);
			}else {
				return R.failed("未配置企业的统一社会信用代码");
			}

			if (!Objects.equals(sysUser.getCertStatus(), TaxHelperCertStatus.CERT.getCode())) {
				noticeInfo.append(sysUser.getRealname() + "人员未认证或未绑卡，不能结算；");
				continue;
			}

			TaxHelperConfig config = new TaxHelperConfig();
			config.setAppId(dept.getAppId());
			config.setAppSecrete(dept.getAppSecret());
			config.setQueryUrl(dept.getQueryUrl());

			/**
			 * 开始结算
			 */
			TaxHelperSettlementModel taxHelperSettlementModel = new TaxHelperSettlementModel(config);
			taxHelperSettlementModel.setEnterpriseCode(shCode);

			taxHelperSettlementModel.setExtendFieldNames(Arrays.asList("报告下载地址"));
			taxHelperSettlementModel.setCount(1);

			taxHelperSettlementModel.setNotifyUrl(taxNotifyConfig.getNotifyUrl() + "/admin/taxhelper/" + sysUser.getUserId() +"/settlementNotify");
			TaxHelperSettlementModel.DetailedArr detailedArr = new TaxHelperSettlementModel.DetailedArr();
			detailedArr.setIdCard(sysUser.getIdCardNumber());
			detailedArr.setInputAmount(settleNote.getSettleAmount().doubleValue());
			detailedArr.setCategoryName(settleNote.getCategoryName());
			taxHelperSettlementModel.setDetailedArr(Arrays.asList(detailedArr));

			TaxHelperSettlementModel.AbstractArr abstractArr = new TaxHelperSettlementModel.AbstractArr();

			abstractArr.setIdCard(sysUser.getIdCardNumber());
			abstractArr.setNumber(1);
			abstractArr.setPrice(settleNote.getSettleAmount().doubleValue());
			abstractArr.setAmount(settleNote.getSettleAmount().doubleValue());

			// abstractArr.setExtendField1(taxNotifyConfig.getTaskUrl() +"/admin/api/h5PackagePage?current=1&size=20&id=" + wmScorePackage.getScorePackageName());
			abstractArr.setExtendField1(taxNotifyConfig.getTaskUrl() + "/#/h5/indexTask?id=" + note.getPackageId() + "&userId=" + note
					.getUserId());

			taxHelperSettlementModel.setAbstractArr(Arrays.asList(abstractArr));

			TaxHelperSettlementRequest taxHelperSettlementRequest = new TaxHelperSettlementRequest(taxHelperSettlementModel);

			TaxHelperResponse response = taxHelperService.settlement(taxHelperSettlementRequest);

			log.info("税邦云结算： {}", response);

			// 提交结算成功
			WmTaskSettleNote updateEntity = new WmTaskSettleNote();
			updateEntity.setId(settleNote.getId());
			if(response.success()){
				log.info("税邦云结算提交成功： {}", settleNote.getSettleNo());
				//streamId 获取不到
				if(StringUtils.isEmpty(response.getMessage())){
					log.info("税邦云结算提交成功 streamId 获取不到： {}", settleNote.getSettleNo());
					noticeInfo.append(sysUser.getRealname() + "：提交结算成功，业务流水号获取不到，请联系管理员；");
				}
				updateEntity.setUpdateTime(LocalDateTime.now());
				updateEntity.setSettleNoteStatus(3);

				updateEntity.setStreamId(response.getMessage());
				// 新增字段streamId
				this.baseMapper.updateById(updateEntity);
				noticeInfo.append(sysUser.getRealname() + "：提交结算成功；");
			}else {
				log.info("税邦云结算提交失败： {}",  settleNote.getSettleNo());
				updateEntity.setUpdateTime(LocalDateTime.now());
				updateEntity.setSettleNoteStatus(2);
				this.baseMapper.updateById(updateEntity);
				noticeInfo.append(sysUser.getRealname() + "：结算提交失败-" + response.getMessage() +"；");
			}
		}

		return R.ok("",noticeInfo.toString());

	}


	/**
	 * 单一结算
	 *
	 * @param note
	 * @return
	 */
	@Override
	public R singletSettle(WmTaskSettleNote note) {
		WmTaskSettleNote settleNote = this.baseMapper.selectById(note.getId());
		WmScorePackage wmScorePackage = wmScorePackageMapper.selectById(settleNote.getPackageId());
		if (9 != settleNote.getSettleNoteStatus() && 2 != settleNote.getSettleNoteStatus()) {
			return R.failed("状态异常，不能结算");
		}
		if (StringUtils.isEmpty(settleNote.getUserId())) {
			return R.failed("数据异常，不能结算");
		}
		SysUser sysUser = sysUserService.getById(settleNote.getUserId());

		if (!Objects.equals(sysUser.getCertStatus(), TaxHelperCertStatus.CERT.getCode())) {
			return R.failed("人员未认证或未绑卡，不能结算");
		}

		SysDept dept = deptService.getById(sysUser.getDeptId());

		if (null != dept && StringUtils.isNotEmpty(dept.getAppId()) && "1".equals(dept.getSubjectType())) {
			log.info("税邦云结算开始：{} ", dept.getSubjectName());
		} else {
			return R.failed("结算信息配置有误");
		}

//		WmDaAgent agent = wmDaAgentService.selectByDeptId(dept.getDeptId());
//		if(null !=agent && StringUtils.isNotEmpty(agent.getZjNumber()) ){
//			log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码：{} ", agent.getZjNumber());
//		}else {
//			return R.failed("未配置企业的统一社会信用代码");
//		}
		String shCode = "";
		WmDaAgent agent = wmDaAgentService.selectByDeptId(dept.getDeptId());
		WmDaDrugEnt drugEnt = wmDaDrugEntService.selectByDeptId(dept.getDeptId());
		if (null != agent) {
			shCode = agent.getZjNumber();
		}else {
			shCode = drugEnt.getEntcode();
		}
		if(StringUtils.isNotEmpty(shCode)){
			log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码：{} ", shCode);
		}else {
			return R.failed("未配置企业的统一社会信用代码");
		}

		TaxHelperConfig config = new TaxHelperConfig();
		config.setAppId(dept.getAppId());
		config.setAppSecrete(dept.getAppSecret());
		config.setQueryUrl(dept.getQueryUrl());

		/**
		 * 开始结算
		 */
		TaxHelperSettlementModel taxHelperSettlementModel = new TaxHelperSettlementModel(config);
		taxHelperSettlementModel.setEnterpriseCode(shCode);

		taxHelperSettlementModel.setExtendFieldNames(Arrays.asList("报告下载地址"));
		taxHelperSettlementModel.setCount(1);

		taxHelperSettlementModel.setNotifyUrl(taxNotifyConfig.getNotifyUrl() + "/admin/taxhelper/" + sysUser.getUserId() +"/settlementNotify");
		TaxHelperSettlementModel.DetailedArr detailedArr = new TaxHelperSettlementModel.DetailedArr();
		detailedArr.setIdCard(sysUser.getIdCardNumber());
		detailedArr.setInputAmount(settleNote.getSettleAmount().doubleValue());
		detailedArr.setCategoryName(settleNote.getCategoryName());
		taxHelperSettlementModel.setDetailedArr(Arrays.asList(detailedArr));

		TaxHelperSettlementModel.AbstractArr abstractArr = new TaxHelperSettlementModel.AbstractArr();

		abstractArr.setIdCard(sysUser.getIdCardNumber());
		abstractArr.setNumber(1);
		abstractArr.setPrice(settleNote.getSettleAmount().doubleValue());
		abstractArr.setAmount(settleNote.getSettleAmount().doubleValue());

		// abstractArr.setExtendField1(taxNotifyConfig.getTaskUrl() +"/admin/api/h5PackagePage?current=1&size=20&id=" + wmScorePackage.getScorePackageName());
		abstractArr.setExtendField1(taxNotifyConfig.getTaskUrl() + "/#/h5/indexTask?id=" + note.getPackageId() + "&userId=" + note
				.getUserId());

		taxHelperSettlementModel.setAbstractArr(Arrays.asList(abstractArr));

		TaxHelperSettlementRequest taxHelperSettlementRequest = new TaxHelperSettlementRequest(taxHelperSettlementModel);

//		String key = (String) redisTemplate.opsForValue().get(CacheConstants.TAX_HELPER_LOGIN_KEY);
//		taxHelperSettlementRequest.setKey(key);
		TaxHelperResponse response = taxHelperService.settlement(taxHelperSettlementRequest);

		log.info("税邦云结算： {}", response);

		// 提交结算成功
		WmTaskSettleNote updateEntity = new WmTaskSettleNote();
		updateEntity.setId(settleNote.getId());
		if(response.success()){
			log.info("税邦云结算提交成功： {}", settleNote.getSettleNo());
			//streamId 获取不到
			if(StringUtils.isEmpty(response.getMessage())){
				log.info("税邦云结算提交成功 streamId 获取不到： {}", settleNote.getSettleNo());
			}
			updateEntity.setUpdateTime(LocalDateTime.now());
			updateEntity.setSettleNoteStatus(3);

			updateEntity.setStreamId(response.getMessage());
			// 新增字段streamId
			this.baseMapper.updateById(updateEntity);
			return R.ok();
		}else {
			log.info("税邦云结算提交失败： {}",  settleNote.getSettleNo());
			updateEntity.setUpdateTime(LocalDateTime.now());
			updateEntity.setSettleNoteStatus(2);
			this.baseMapper.updateById(updateEntity);
			return R.failed("结算失败"+response.getMessage());
//			return R.failed("结算失败");
		}

	}

	/**
	 * @param note
	 * @return
	 */
	@Override
	public R subSettleInfo(WmTaskSettleNote note) {

		WmTaskSettleNote updateEntity;
		LocalDateTime localDateTime = LocalDateTime.now();
		if (null != note.getId()) {
			WmTaskSettleNote oldData = this.baseMapper.selectById(note.getId());
			if (0 != oldData.getSettleNoteStatus()) {

				return R.failed("状态异常，不能提交");
			}
			updateEntity = new WmTaskSettleNote();
			updateEntity.setId(note.getId());
			updateEntity.setCategoryName(note.getCategoryName());
			updateEntity.setSettleAmount(note.getSettleAmount());
			updateEntity.setSettleNoteStatus(9);
			updateEntity.setSubTime(localDateTime);
			updateEntity.setUpdateTime(localDateTime);
			this.baseMapper.updateById(updateEntity);
			WmTaskSettleNote wmTaskSettleNote = this.baseMapper.selectById(note.getId());

			WmScorePackage wmScorePackage = wmScorePackageService.getById(wmTaskSettleNote.getPackageId());
			wmScorePackage.setSettlementDate(LocalDateTime.now());
			wmScorePackageMapper.updateById(wmScorePackage);
			return R.ok();
		}else {
			WmTaskSettleNote entity = new WmTaskSettleNote();
			entity.setCategoryName(note.getCategoryName());
			entity.setSettleAmount(note.getSettleAmount());
			entity.setDiscount(new BigDecimal(1));
			entity.setPackageId(note.getPackageId());
			entity.setTaskId(note.getTaskId());
			entity.setUserId(note.getUserId());
			String settleNo = UUID.randomUUID().toString().replace("-", "");
			entity.setSettleNo(settleNo);
			entity.setSettleNoteStatus(9);

			entity.setCreateTime(localDateTime);
			entity.setSubTime(localDateTime);
			entity.setUpdateTime(localDateTime);

			this.baseMapper.insert(entity);
		}

//		WmTaskSettleNote query = new WmTaskSettleNote();
//		if (StringUtils.isNotEmpty(note.getPackageId())) {
//			query.setPackageId(note.getPackageId());
//		} else {
//			return R.failed("批量提交失败，参数异常");
//		}
//		if (StringUtils.isNotEmpty(note.getUserId())) {
//			query.setUserId(note.getUserId());
//		}
//		query.setSettleNoteStatus(0);
//
//		updateEntity = new WmTaskSettleNote();
//		updateEntity.setSettleNoteStatus(9);
//		this.baseMapper.update(updateEntity, Wrappers.query(query));

		return R.ok();
	}

	/**
	 * @param note
	 * @return
	 */
	@Override
	public R revokeSettle(WmTaskSettleNote note) {

		WmTaskSettleNote updateEntity;
		if (null != note.getId()) {
			WmTaskSettleNote oldData = this.baseMapper.selectById(note.getId());
			if (9 != oldData.getSettleNoteStatus()) {

				return R.failed("状态异常，不能提交");
			}
			updateEntity = new WmTaskSettleNote();
			updateEntity.setId(note.getId());
			updateEntity.setCategoryName(note.getCategoryName());
			updateEntity.setSettleAmount(note.getSettleAmount());
			updateEntity.setSettleNoteStatus(0);
			this.baseMapper.updateById(updateEntity);
			return R.ok();
		}

		WmTaskSettleNote query = new WmTaskSettleNote();
		if (StringUtils.isNotEmpty(note.getPackageId())) {
			query.setPackageId(note.getPackageId());
		} else {
			return R.failed("批量回退失败，参数异常");
		}
		if (StringUtils.isNotEmpty(note.getUserId())) {
			query.setUserId(note.getUserId());
		}
		query.setSettleNoteStatus(9);
		updateEntity = new WmTaskSettleNote();
		updateEntity.setSettleNoteStatus(0);
		this.baseMapper.update(updateEntity, Wrappers.query(query));

		return R.ok();
	}

	@Override
	public R saveSettleInfo(WmTaskSettleNote note) {

		LocalDateTime localDateTime = LocalDateTime.now();
		if (null == note.getId()) {

			WmTaskSettleNote entity = new WmTaskSettleNote();
			entity.setCategoryName(note.getCategoryName());
			entity.setSettleAmount(note.getSettleAmount());
			entity.setDiscount(new BigDecimal(1));
			entity.setPackageId(note.getPackageId());
			entity.setTaskId(note.getTaskId());
			entity.setUserId(note.getUserId());
			String settleNo = UUID.randomUUID().toString().replace("-", "");
			entity.setSettleNo(settleNo);
			entity.setSettleNoteStatus(0);
			entity.setCreateTime(localDateTime);
			entity.setUpdateTime(localDateTime);
			this.baseMapper.insert(entity);
		} else {
			WmTaskSettleNote oldData = this.baseMapper.selectById(note.getId());

			if (0 != oldData.getSettleNoteStatus()) {

				return R.failed("状态异常，不能修改");
			}
			WmTaskSettleNote updateEntity = new WmTaskSettleNote();
			updateEntity.setId(note.getId());
			updateEntity.setCategoryName(note.getCategoryName());
			updateEntity.setSettleAmount(note.getSettleAmount());
			updateEntity.setUpdateTime(localDateTime);
			this.baseMapper.updateById(updateEntity);
		}

		return R.ok();
	}

	@Override
	public IPage<WmTaskSettleNoteOutput> getWmTaskSettleInfoPage(Page page, WmTaskSettleNote wmTaskSettleNote) {
		return wmTaskSettleNoteMapper.getWmTaskSettleInfoPage(page, wmTaskSettleNote);
	}

	@Override
	public IPage<WmTaskSettleNoteOutput> getWmTaskForSettlePage(Page page, WmTaskSettleNote wmTaskSettleNote) {
		return wmTaskSettleNoteMapper.getWmTaskForSettlePage(page, wmTaskSettleNote);
	}

	@Override
	public R getSettleInfo(WmTaskSettleNote note) {
		SysUser user = sysUserService.getById(note.getUserId());
		if (null != note.getId()) {

			note = this.baseMapper.selectById(note.getId());
			note.setUserName(user.getRealname());
			return R.ok(note);
		}
		WmTaskSettleNote query = new WmTaskSettleNote();
		query.setPackageId(note.getPackageId());
		query.setTaskId(note.getTaskId());
		query.setUserId(note.getUserId());

		List<WmTaskSettleNote> noteList = this.baseMapper.selectList(Wrappers.query(query));
		if (CollectionUtils.isNotEmpty(noteList)) {
			if (noteList.size() > 1) {
				return R.failed("结算数据异常，请联系管理员处理");
			}
			query = noteList.get(0);

		}else {
			WmScorePackage wmScorePackage = wmScorePackageMapper.selectById(note.getPackageId());
			BigDecimal amount = new BigDecimal(wmScorePackage.getScore())
					.divide(new BigDecimal(wmScorePackage.getTaskNum()),2, BigDecimal.ROUND_HALF_UP);
			query.setSettleAmount(amount);
		}
		query.setUserName(user.getRealname());

		return R.ok(query);

//		WmTaskSettleNote entity = new WmTaskSettleNote();
//		entity.setDiscount(new BigDecimal(1));
//		entity.setPackageId(note.getPackageId());
//		entity.setTaskId(note.getTaskId());
//		entity.setUserId(note.getUserId());
//		String settleNo = UUID.randomUUID().toString().replace("-", "");
//		entity.setSettleNo(settleNo);
//		entity.setSettleNoteStatus(0);

//		this.baseMapper.insert(entity);


//		entity.setUserName(user.getRealname());

//		return R.ok(entity);
	}


	/**
	 * 税邦云结算 回调
	 * @param streamId
	 * @return
	 */
	@Override
	public R settleNotify(String streamId) {
//		if(StringUtils.isEmpty(streamId)){
//			log.info("streamId获取失败");
//			return R.failed("回调成功，streamId获取失败");
//		}

		WmTaskSettleNote query = new WmTaskSettleNote();
		query.setStreamId(streamId);
		List<WmTaskSettleNote> noteList = this.baseMapper.selectList(Wrappers.query(query));

		if(CollectionUtils.isNotEmpty(noteList)){
			log.info("回调成功，流水号{}",streamId);
			WmTaskSettleNote updateEntity = new WmTaskSettleNote();
			updateEntity.setId(noteList.get(0).getId());
			updateEntity.setSettleNoteStatus(1);
			updateEntity.setNotifyTime(LocalDateTime.now());
			this.baseMapper.updateById(updateEntity);

		}else {
			log.info("回调成功，流水号异常： {}",streamId);
		}

		return R.ok();
	}
}
