package com.jeequan.jeepay.mgr.ctrl.division;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchDivisionReceiver;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.DivisionReceiverBindReqModel;
import com.jeequan.jeepay.model.DivisionReceiverChannelBalanceCashoutReqModel;
import com.jeequan.jeepay.model.DivisionReceiverChannelBalanceQueryReqModel;
import com.jeequan.jeepay.request.DivisionReceiverBindRequest;
import com.jeequan.jeepay.request.DivisionReceiverChannelBalanceCashoutRequest;
import com.jeequan.jeepay.request.DivisionReceiverChannelBalanceQueryRequest;
import com.jeequan.jeepay.response.DivisionReceiverBindResponse;
import com.jeequan.jeepay.response.DivisionReceiverChannelBalanceCashoutResponse;
import com.jeequan.jeepay.response.DivisionReceiverChannelBalanceQueryResponse;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchDivisionReceiverService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

/**
 * 商户分账接收者账号关系维护
 *
 * @author terrfly
 *
 * @date 2021-08-23 11:50
 */
@RestController
@RequestMapping("api/divisionReceivers")
public class MchDivisionReceiverController extends CommonCtrl {

	@Autowired
	private MchDivisionReceiverService mchDivisionReceiverService;
	@Autowired
	private MchAppService mchAppService;
	@Autowired
	private SysConfigService sysConfigService;


	/**
	 * list
	 */
	@PreAuthorize("hasAnyAuthority( 'ENT_DIVISION_RECEIVER_LIST' )")
	@RequestMapping(value = "", method = RequestMethod.GET)
	public ApiRes list() {

		MchDivisionReceiver queryObject = getObject(MchDivisionReceiver.class);
		IPage<MchDivisionReceiver> records = mchDivisionReceiverService.listByPage(getIPage(true), queryObject);
		// 商户名称存入
		setMchName(records.getRecords());
		return ApiRes.page(records);
	}


	/**
	 * detail
	 */
	@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_VIEW' )")
	@RequestMapping(value = "/{recordId}", method = RequestMethod.GET)
	public ApiRes detail(@PathVariable("recordId") Long recordId) {
		MchDivisionReceiver record = mchDivisionReceiverService
				.getOne(MchDivisionReceiver.gw()
						.eq(MchDivisionReceiver::getReceiverId, recordId));
		if (record == null) {
			throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
		}
		return ApiRes.ok(record);
	}

	/**
	 * add
	 */
	@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_ADD' )")
	@RequestMapping(value = "", method = RequestMethod.POST)
	@MethodLog(remark = "新增分账接收账号")
	public ApiRes add() {

		DivisionReceiverBindReqModel model = getObject(DivisionReceiverBindReqModel.class);
		model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
		if (StringUtils.isEmpty(model.getMchNo())) {
			throw new BizException("商户号不能为空");
		}

		MchAppEntity mchAppEntity = mchAppService.getById(model.getAppId());
		if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(model.getMchNo())) {
			throw new BizException("商户应用不存在或不可用");
		}

		DivisionReceiverBindRequest request = new DivisionReceiverBindRequest();
		request.setBizModel(model);
		model.setMchNo(model.getMchNo());
		model.setAppId(mchAppEntity.getAppId());
		model.setDivisionProfit(new BigDecimal(model.getDivisionProfit()).divide(new BigDecimal(100)).toPlainString());

		JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());

		try {
			DivisionReceiverBindResponse response = jeepayClient.execute(request);
			if (response.getCode() != 0) {
				throw new BizException(response.getMsg());
			}
			return ApiRes.ok(response.get());
		} catch (JeepayException e) {
			throw new BizException(e.getMessage());
		}
	}

	/**
	 * update
	 */
	@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_EDIT' )")
	@RequestMapping(value = "/{recordId}", method = RequestMethod.PUT)
	@MethodLog(remark = "更新分账接收账号")
	public ApiRes update(@PathVariable("recordId") Long recordId) {

		// 请求参数
		MchDivisionReceiver reqReceiver = getObject(MchDivisionReceiver.class);
		reqReceiver.setReceiverId(recordId);
		mchDivisionReceiverService.updateReceiver(reqReceiver);

		return ApiRes.ok();
	}

	/**
	 * delete
	 */
	@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_DELETE')")
	@RequestMapping(value = "/{recordId}", method = RequestMethod.DELETE)
	@MethodLog(remark = "删除分账接收账号")
	public ApiRes del(@PathVariable("recordId") Long recordId) {
		MchDivisionReceiver record = mchDivisionReceiverService.getOne(MchDivisionReceiver.gw()
				.eq(MchDivisionReceiver::getReceiverGroupId, recordId));
		if (record == null) {
			throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
		}

		mchDivisionReceiverService.removeById(recordId);
		return ApiRes.ok();
	}


	/**
	 * 查询账户余额
	 */
	@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_EDIT')")
	@RequestMapping(value = "/channelBalances/{recordId}", method = RequestMethod.GET)
	public ApiRes channelBalances(@PathVariable("recordId") Long recordId) {
		MchDivisionReceiver record = mchDivisionReceiverService.getById(recordId);
		if (record == null) {
			throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
		}

		MchAppEntity mchAppEntity = mchAppService.getById(record.getAppId());
		if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(record.getMchNo())) {
			throw new BizException("商户应用不存在或不可用");
		}

		DivisionReceiverChannelBalanceQueryRequest request = new DivisionReceiverChannelBalanceQueryRequest();
		DivisionReceiverChannelBalanceQueryReqModel model = new DivisionReceiverChannelBalanceQueryReqModel();
		model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
		model.setReceiverId(recordId);
		model.setMchNo(record.getMchNo());
		model.setAppId(mchAppEntity.getAppId());
		request.setBizModel(model);

		JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());

		try {

			DivisionReceiverChannelBalanceQueryResponse response = jeepayClient.execute(request);
			if (response.getCode() != 0) {
				throw new BizException(response.getMsg());
			}
			return ApiRes.ok(response.get());
		} catch (JeepayException e) {
			throw new BizException(e.getMessage());
		}
	}


	/**
	 * 发起提现
	 */
	@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_EDIT')")
	@RequestMapping(value = "/channelCashout/{recordId}", method = RequestMethod.POST)
	@MethodLog(remark = "分账账户发起提现")
	public ApiRes channelCashout(@PathVariable("recordId") Long recordId) {

		MchDivisionReceiver record = mchDivisionReceiverService.getById(recordId);
		if (record == null) {
			throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
		}

		MchAppEntity mchAppEntity = mchAppService.getById(record.getAppId());
		if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(record.getMchNo())) {
			throw new BizException("商户应用不存在或不可用");
		}

		DivisionReceiverChannelBalanceCashoutRequest request = new DivisionReceiverChannelBalanceCashoutRequest();
		DivisionReceiverChannelBalanceCashoutReqModel model = new DivisionReceiverChannelBalanceCashoutReqModel();
		model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
		model.setReceiverId(recordId);
		model.setCashoutAmount(getRequiredAmountL("cashoutAmount"));
		model.setMchNo(record.getMchNo());
		model.setAppId(mchAppEntity.getAppId());
		request.setBizModel(model);

		JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());

		try {

			DivisionReceiverChannelBalanceCashoutResponse response = jeepayClient.execute(request);
			if (response.getCode() != 0) {
				throw new BizException(response.getMsg());
			}
			return ApiRes.ok(response.get());
		} catch (JeepayException e) {
			throw new BizException(e.getMessage());
		}
	}
}
