package cn.superdesk.uniorder.controller.invoice.supplier.state;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.constants.ResponseMsgConstants;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierPayOffAccountStatusEnum;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderForm;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderItem;
import cn.superdesk.uniorder.dubbo.consumer.invoice.supplier.InvoiceApplySupplierDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.invoice.supplier.InvoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 简易状态机 星型结构
 * @Author: linjinyu
 * @CreateDate: 10/12/20 4:28 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 10/12/20 4:28 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "InvoiceApplySupplier - PayoffAccountStatus", tags = {"InvoiceApplySupplier - PayoffAccountStatus"})
@Slf4j
@RestController
@RequestMapping("/invoice/apply/supplier/score/state/payoffAccountStatus")
public class InvoiceApplySupplierScoreFieldPayoffAccountStatusController extends BaseController {

	@Autowired
	private InvoiceApplySupplierDubboConsumerService                         invoiceApplySupplierDubboConsumerService;
	@Autowired
	private InvoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService;

	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 操作 侨城汇-运营 开票申请后初始状态 待付款 状态改变为 待付款_0")
	@RequestMapping(value = "/opInit/{id}", method = RequestMethod.POST)
	@ResponseBody
	public R<?> opInit(@PathVariable("id") Long id) {

		R<?> result = new R<>();

		try {
			InvoiceApplySupplier entity = invoiceApplySupplierDubboConsumerService.findById(id);
			invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opInit(getToken(), entity);
			result.setSuccess(true);

		} catch (Exception e) {

			result.setSuccess(false);
			result.setMessage(ResponseMsgConstants.ERROR_UNKNOW);
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}
		return result;
	}

	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 操作 侨城汇-运营 op发起付款 向上级请款 审批流程 例如 走OA审批流 状态改变为 付款中_10")
	@RequestMapping(value = "/opRegulatoryPipeline/{id}", method = RequestMethod.POST)
	@ResponseBody
	public R<?> opRegulatoryPipeline(@PathVariable("id") Long id) {

		R<?> result = new R<>();

		try {
			InvoiceApplySupplier entity = invoiceApplySupplierDubboConsumerService.findById(id);
			invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opRegulatoryPipeline(getToken(), entity);
			result.setSuccess(true);

		} catch (Exception e) {

			result.setSuccess(false);
			result.setMessage(ResponseMsgConstants.ERROR_UNKNOW);
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}

	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 对账单维度 - 操作 侨城汇-运营 op发起付款 向上级请款 审批流程 例如 走OA审批流 状态改变为 付款中_10")
	@RequestMapping(value = "/opRegulatoryPipeline/dim/accountingOrder", method = RequestMethod.POST)
	@ResponseBody
	public R<String> opRegulatoryPipelineDimAccountingOrder(@RequestBody InvoiceApplySupplierOpCommonDimAccountingOrderForm form) { // 以对账单维度自动补全 - 20220111

		// TODO 简单验证

		if (CollUtil.isEmpty(form.getInvoiceApplySupplierList())) {
			return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
		}

		try {

			/****************************************** 对账单编号 start ******************************************/

			if (StrUtil.isBlank(form.getAccountingOrderSn())) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/****************************************** 开票申请 - 数据库 start ******************************************/

			List<InvoiceApplySupplier> entitysExistDb = invoiceApplySupplierDubboConsumerService.findByAccountingOrderSn(form.getAccountingOrderSn());

			if (CollUtil.isEmpty(entitysExistDb)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/******************************************  start ******************************************/

			List<Long> invoiceApplyIds = form.getInvoiceApplySupplierList()
					.stream()
					.map(InvoiceApplySupplierOpCommonDimAccountingOrderItem::getInvoiceApplyId)
					.collect(Collectors.toList());

			List<InvoiceApplySupplier> entitysQueryBySubmit = invoiceApplySupplierDubboConsumerService.findByIds(invoiceApplyIds);

			if (CollUtil.isEmpty(invoiceApplyIds)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (CollUtil.isEmpty(entitysQueryBySubmit)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (entitysExistDb.size() != entitysQueryBySubmit.size()) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/******************************************  start ******************************************/

			List<Integer> payoffAccountStatus = entitysExistDb
					.stream()
					.filter(AnLamdaUtils.distinctByKey(o -> o.getPayoffAccountStatus()))
					.map(InvoiceApplySupplier::getPayoffAccountStatus)
					.collect(Collectors.toList());

			if (CollUtil.isEmpty(payoffAccountStatus)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (payoffAccountStatus.size() > 1) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			InvoiceApplySupplierPayOffAccountStatusEnum invoiceApplySupplierPayOffAccountStatusEnum = InvoiceApplySupplierPayOffAccountStatusEnum.get(payoffAccountStatus.get(0));

			if (invoiceApplySupplierPayOffAccountStatusEnum != InvoiceApplySupplierPayOffAccountStatusEnum.待付款) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据 [申请状态] 异常, 要求付款状态为 [待付款]");
			}

			int ret = invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opRegulatoryPipeline(getToken(), entitysQueryBySubmit, form);

			if (ret > 0) {
				return ResponseResultOuterUtils.createSuccesResult("操作成功");
			} else {
				return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
			}

		} catch (Exception e) {
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
			return ResponseResultOuterUtils.createErrorResult("500", "操作失败，请联系管理员！");
		}

	}

	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 操作 侨城汇-运营 收到发票后 跟进付款 部分付款 - 预留 - 目前没有这逻辑,也不允许 状态改变为 部分付款_1")
	@RequestMapping(value = "/opPart/{id}", method = RequestMethod.POST)
	@ResponseBody
	public R<?> opPart(@PathVariable("id") Long id) {

		R<?> result = new R<>();

		try {
			InvoiceApplySupplier entity = invoiceApplySupplierDubboConsumerService.findById(id);
			invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opPart(getToken(), entity);
			result.setSuccess(true);

		} catch (Exception e) {

			result.setSuccess(false);
			result.setMessage(ResponseMsgConstants.ERROR_UNKNOW);
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}
		return result;
	}

	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 操作 侨城汇-运营 op确认付款 收到发票后 线下 或 走OA 请到付且付款后 已付款 状态改变为 已付款_2")
	@RequestMapping(value = "/opComplete/{id}", method = RequestMethod.POST)
	@ResponseBody
	public R<?> opComplete(@PathVariable("id") Long id) {

		R<?> result = new R<>();

		try {
			InvoiceApplySupplier entity = invoiceApplySupplierDubboConsumerService.findById(id);
			invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opComplete(getToken(), entity);
			result.setSuccess(true);

		} catch (Exception e) {

			result.setSuccess(false);
			result.setMessage(ResponseMsgConstants.ERROR_UNKNOW);
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * /invoice/apply/supplier/score/state/payoffAccountStatus/opComplete/dim/accountingOrder
	 * @param form
	 * @return
	 */
	@ApiOperation(value = "InvoiceApplySupplier - PayoffAccountStatus - 对账单维度 - 操作 侨城汇-运营 op确认付款 收到发票后 线下 或 走OA 请到付且付款后 已付款 状态改变为 已付款_2")
	@RequestMapping(value = "/opComplete/dim/accountingOrder", method = RequestMethod.POST)
	@ResponseBody
	public R<String> opCompleteDimAccountingOrder(@RequestBody InvoiceApplySupplierOpCommonDimAccountingOrderForm form) { // 以对账单维度自动补全 - 20220111


		// TODO 简单验证

		if (CollUtil.isEmpty(form.getInvoiceApplySupplierList())) {
			return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
		}

		try {

			/****************************************** 对账单编号 start ******************************************/

			if (StrUtil.isBlank(form.getAccountingOrderSn())) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/****************************************** 开票申请 - 数据库 start ******************************************/

			List<InvoiceApplySupplier> entitysExistDb = invoiceApplySupplierDubboConsumerService.findByAccountingOrderSn(form.getAccountingOrderSn());

			if (CollUtil.isEmpty(entitysExistDb)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/******************************************  start ******************************************/

			List<Long> invoiceApplyIds = form.getInvoiceApplySupplierList()
					.stream()
					.map(InvoiceApplySupplierOpCommonDimAccountingOrderItem::getInvoiceApplyId)
					.collect(Collectors.toList());

			List<InvoiceApplySupplier> entitysQueryBySubmit = invoiceApplySupplierDubboConsumerService.findByIds(invoiceApplyIds);

			if (CollUtil.isEmpty(invoiceApplyIds)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (CollUtil.isEmpty(entitysQueryBySubmit)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (entitysExistDb.size() != entitysQueryBySubmit.size()) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			/******************************************  start ******************************************/

			List<Integer> payoffAccountStatus = entitysQueryBySubmit
					.stream()
					.filter(AnLamdaUtils.distinctByKey(o -> o.getPayoffAccountStatus()))
					.map(InvoiceApplySupplier::getPayoffAccountStatus)
					.collect(Collectors.toList());

			if (CollUtil.isEmpty(payoffAccountStatus)) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}
			if (payoffAccountStatus.size() > 1) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据异常");
			}

			InvoiceApplySupplierPayOffAccountStatusEnum invoiceApplySupplierPayOffAccountStatusEnum = InvoiceApplySupplierPayOffAccountStatusEnum.get(payoffAccountStatus.get(0));

			if (invoiceApplySupplierPayOffAccountStatusEnum != InvoiceApplySupplierPayOffAccountStatusEnum.付款中) {
				return ResponseResultOuterUtils.createErrorResult("500", "提交的数据 [申请状态] 异常, 要求付款状态为 [付款中]");
			}

			int ret = invoiceApplySupplierFieldPayoffAccountStatusDubboConsumerService.opComplete(getToken(), entitysQueryBySubmit, form);

			if (ret > 0) {
				return ResponseResultOuterUtils.createSuccesResult("操作成功");
			} else {
				return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
			}

		} catch (Exception e) {
			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
			return ResponseResultOuterUtils.createErrorResult("500", "操作失败，请联系管理员！");
		}

	}


}
