package com.tzy.controller.grade;

import com.tzy.annotation.ApiLimitRule;
import com.tzy.annotation.ApiLog;
import com.tzy.annotation.RequireRoles;
import com.tzy.app.dto.grade.GradeOrderDTO;
import com.tzy.app.dto.grade.GradeOrderParam;
import com.tzy.app.dto.user.UserConfigDTO;
import com.tzy.common.config.handle.ApiVersion;
import com.tzy.common.dto.InDto;
import com.tzy.common.dto.OutDTO;
import com.tzy.common.dto.UserInfo;
import com.tzy.common.enums.BusinessType;
import com.tzy.common.utils.UserType;
import com.tzy.common.utils.UserUtils;
import com.tzy.express.ExpressUtils;
import com.tzy.framework.web.domain.LimitRule;
import com.tzy.sportcard.api.bean.grade.GradeTypeManage;
import com.tzy.sportcard.api.domain.AppUserInfoDto;
import com.tzy.sportcard.api.service.MineApiService;
import com.tzy.sportcard.grade.dto.GradeAuthTypeDTO;
import com.tzy.sportcard.grade.dto.GradeChangeRecordDTO;
import com.tzy.sportcard.grade.dto.GradeQuery;
import com.tzy.sportcard.grade.dto.GradeSuppleDTO;
import com.tzy.sportcard.grade.service.IGradeOrderService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * 【评级相关】Controller
 *
 * @date 2023-11-30
 */
@Controller
@RequestMapping("/api/{version}/grade")
public class GradeOrderController {

	@Resource
	private IGradeOrderService gradeOrderService;
	@Resource
	private MineApiService mineApiService;

	@ApiLog(title = "评级认证类型", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/auth/type")
	@ApiVersion(2.0)
	public OutDTO getGradeAuthType(@RequestBody InDto inDto) {
		String type = inDto.getString("type");
		List<GradeTypeManage> types = gradeOrderService.getGradeAuthType(type);
		return OutDTO.ok().put("types", types);
	}

	@ApiLog(title = "查询评级订单", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/list")
	@ApiVersion(2.0)
	public OutDTO getGradeOrderList(@RequestBody InDto inDto) {
		GradeQuery gradeQuery = inDto.buildParam(new GradeQuery());
		UserInfo userInfo = UserUtils.getSimpleUserInfo();
		Integer userId = userInfo != null && UserType.USER_ROLE_ADMIN.equals(userInfo.getRoleCode()) ? null : inDto.getUserId();
		gradeQuery.setUserId(userId).setPageNo(inDto.getPageNo()).setRows(inDto.getPageSize());
		if (StringUtils.isNumeric(gradeQuery.getKeyword())) {
			gradeQuery.setOrderNo(gradeQuery.getKeyword()).setKeyword(null);
		}
		List<GradeOrderDTO> orders = gradeOrderService.getGradeOrderList(gradeQuery);
		return OutDTO.ok().put("orders", orders);
	}

	@ApiLog(title = "提交", businessType = BusinessType.INSERT, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/submit")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 2, limitCount = 10, msg = "操作频繁,请稍后再试!")
	public OutDTO submitGradeOrder(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		GradeOrderParam gradeParam = inDto.buildParam(new GradeOrderParam());
		gradeParam.setUserId(inDto.getUserId().longValue());
		List<Long> orderIds = gradeOrderService.submitGradeOrder(gradeParam);
		return OutDTO.ok().put("orderIds", orderIds);
	}

	@ApiLog(title = "明细", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ApiOperation("评级订单明细,参数:id")
	@ResponseBody
	@PostMapping(value = "/detail")
	@ApiVersion(2.0)
	public OutDTO getGradeOrderDetail(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		Integer id = inDto.getIntegerParam("id");
		Integer payStatus = inDto.getIntegerParam("payStatus");
		UserInfo userInfo = UserUtils.getSimpleUserInfo();
		Integer userId = userInfo != null && UserType.USER_ROLE_ADMIN.equals(userInfo.getRoleCode()) ? null : inDto.getUserId();
		GradeOrderDTO gradeOrder = gradeOrderService.getGradeOrderDetail(id, userId);
		GradeAuthTypeDTO authType = gradeOrderService.selectAuthTypeById(gradeOrder.getAuthTypeId());
		gradeOrder.setAuthName(authType.getName()).setAuthParentName(authType.getParentName());
		UserConfigDTO user=mineApiService.getUserConfig(gradeOrder.getUserId().intValue());
		if(user != null){
			gradeOrder.setNickname(user.getNickname()).setAvatar(user.getAvatar());
		}else {
			gradeOrder.setNickname("已注销");
		}
		List<GradeChangeRecordDTO> recordList = gradeOrderService.getGradeChangeRecord(id, payStatus);
		gradeOrder.setRecords(recordList);
		return OutDTO.ok().put("gradeOrder", gradeOrder);
	}

	@ApiLog(title = "预支付", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("预支付,参数:id,payType")
	@ResponseBody
	@PostMapping(value = "/prepay")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO gradeOrderPrepay(@RequestBody InDto inDto) {
		AppUserInfoDto user = mineApiService.checkUserNew(inDto);
		Integer id = inDto.getIntegerParam("id");
		String payType = inDto.getString("payType");
		if (StringUtils.isEmpty(payType)) {
			return OutDTO.error500("请选择支付方式!");
		}
		return gradeOrderService.gradeOrderPrepay(id, payType, user);
	}

	@ApiLog(title = "查询已支付的明细和总金额", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("查询已支付的明细和总金额,参数id")
	@ResponseBody
	@PostMapping(value = "/payed/record")
	@ApiVersion(2.0)
	public OutDTO getGradePayedRecord(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		UserInfo userInfo = UserUtils.getSimpleUserInfo();
		Integer userId = userInfo != null && UserType.USER_ROLE_ADMIN.equals(userInfo.getRoleCode()) ? null : inDto.getUserId();
		GradeOrderDTO order = gradeOrderService.getGradeOrderDetail(id, userId);
		if (order == null) {
			return OutDTO.error500("权限不足!");
		}
		List<GradeChangeRecordDTO> recordList = gradeOrderService.getGradeChangeRecord(id, 101);
		BigDecimal totalPayAmount = BigDecimal.ZERO;
		if (!CollectionUtils.isEmpty(recordList)) {
			totalPayAmount = recordList.stream().map(GradeChangeRecordDTO::getActualPayment).reduce(BigDecimal::add).get();
		}
		return OutDTO.ok().put("totalPayAmount", totalPayAmount).put("payedRecords", recordList);
	}

	@ApiLog(title = "用户添加寄送物流信息", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("用户添加寄送物流信息")
	@ResponseBody
	@PostMapping(value = "/user/add/shipping")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO addGradeShipping(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		Integer id = inDto.getIntegerParam("id");
		String courierNum = inDto.getString("courierNum");
		String courierCompany = inDto.getString("courierCompany");
		String courierImg = inDto.getString("courierImg");
		String receiveAddress = inDto.getString("receiveAddress");
		if (StringUtils.isEmpty(courierNum) || StringUtils.isEmpty(courierCompany) || StringUtils.isEmpty(courierImg) || StringUtils.isEmpty(receiveAddress)) {
			return OutDTO.error500("物流信息缺失!");
		}
		if (!ExpressUtils.checkExpressCode(courierNum)) {
			return OutDTO.error(10059, "快递单号不符合规范[" + courierNum + "]");
		}
		gradeOrderService.addGradeShipping(inDto.getUserId(), id, courierNum, courierCompany, courierImg, receiveAddress);
		return OutDTO.ok();
	}


	@ApiLog(title = "评级服务方签收", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("收到用户寄送")
	@ResponseBody
	@PostMapping(value = "/card/receive")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO receiveUserCard(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		String courierNum = inDto.getString("courierNum");
		String courierImg = inDto.getString("courierImg");
		if (StringUtils.isEmpty(courierNum) || StringUtils.isEmpty(courierImg)) {
			return OutDTO.error500("物流信息缺失!");
		}
		gradeOrderService.receiveUserCard(inDto.getUserId(), courierNum, courierImg);
		return OutDTO.ok();
	}


	@ApiLog(title = "补充信息,仅admin权限", businessType = BusinessType.INSERT, indto = "{{inDto}}")
	@ApiOperation("补充信息,仅admin权限")
	@ResponseBody
	@PostMapping(value = "/supple/info")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO suppleGradeInfo(@RequestBody InDto inDto) {
		GradeSuppleDTO suppleInfo = inDto.buildParam(new GradeSuppleDTO());
		gradeOrderService.suppleGradeInfo(inDto.getUserId(), suppleInfo);
		return OutDTO.ok();
	}


	@ApiLog(title = "预评估", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("预评估,补差价,id,preGradeReport,payAmount")
	@ResponseBody
	@PostMapping(value = "/pre/evaluation")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO preEvaluation(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		Integer id = inDto.getIntegerParam("id");
		String preGradeReport = inDto.getString("preGradeReport");
		if (StringUtils.isEmpty(preGradeReport) || id == null) {
			return OutDTO.error500("预评参数缺失!");
		}
		gradeOrderService.preEvaluation(inDto.getUserId(), id, preGradeReport);
		return OutDTO.ok();
	}


	@ApiLog(title = "修改评级金额", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("修改评级金额,id,payAmount,describe")
	@ResponseBody
	@PostMapping(value = "/edit/grade/price")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO editGradeAmount(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String payAmount = inDto.getString("payAmount");
		String describe = inDto.getString("describe");
		if (id == null || StringUtils.isEmpty(describe) || StringUtils.isEmpty(payAmount)) {
			return OutDTO.error500("预评参数缺失!");
		}
		gradeOrderService.editGradeAmount(id, describe, new BigDecimal(payAmount));
		return OutDTO.ok();
	}


	@ApiLog(title = "补差价", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("补差价,id,payAmount,describe")
	@ResponseBody
	//@PostMapping(value = "/balance/price")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO editBalancePrice(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String payAmount = inDto.getString("payAmount");
		String describe = inDto.getString("describe");
		if (id == null || StringUtils.isEmpty(describe) || StringUtils.isEmpty(payAmount)) {
			return OutDTO.error500("预评参数缺失!");
		}
		gradeOrderService.editBalancePrice(id, describe, payAmount);
		return OutDTO.ok();
	}


	@ApiLog(title = "补差价", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("补差价,id,payAmount,describe")
	@ResponseBody
	@PostMapping(value = "/cancel/unpayed")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO cancelUnPayedRecord(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		gradeOrderService.cancelUnPayedRecord(id);
		return OutDTO.ok();
	}

	@ApiLog(title = "确认送评", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("确认送评")
	@ResponseBody
	@PostMapping(value = "/confirm/grade")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO confirmUserGrade(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		gradeOrderService.confirmUserGrade(id, inDto.getUserId());
		return OutDTO.ok();
	}

	@ApiLog(title = "上传评级报告", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("上传评级报告")
	@ResponseBody
	@PostMapping(value = "/report/add")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO addGradeReport(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String gradeReport = inDto.getString("gradeReport");
		String gradeProp = inDto.getString("gradeProp");
		if (id == null || StringUtils.isEmpty(gradeReport)) {
			return OutDTO.error500("预评参数缺失!");
		}
		gradeOrderService.addGradeReport(id, gradeReport, gradeProp);
		return OutDTO.ok();
	}


	@ApiLog(title = "确认收到评级公司回寄", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("确认收到评级公司回寄")
	@ResponseBody
	@PostMapping(value = "/confirm/back")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO confirmBack(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String courierNum = inDto.getString("courierNum");
		String courierCompany = inDto.getString("courierCompany");
		String courierImg = inDto.getString("courierImg");
		if (id == null || StringUtils.isEmpty(courierNum) || StringUtils.isEmpty(courierCompany) || StringUtils.isEmpty(courierImg)) {
			return OutDTO.error500("物流信息缺失!");
		}
		gradeOrderService.confirmBack(id, courierCompany, courierNum, courierImg);
		return OutDTO.ok();
	}


	@ApiLog(title = "填写回寄用户物流", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("填写回寄用户物流")
	@ResponseBody
	@PostMapping(value = "/send/back/user")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO sendUserBack(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String courierNum = inDto.getString("courierNum");
		String courierCompany = inDto.getString("courierCompany");
		String courierImg = inDto.getString("courierImg");
		if (id == null || StringUtils.isEmpty(courierNum) || StringUtils.isEmpty(courierCompany) || StringUtils.isEmpty(courierImg)) {
			return OutDTO.error500("物流信息缺失!");
		}
		gradeOrderService.sendUserBack(id, courierCompany, courierNum, courierImg);
		return OutDTO.ok();
	}

	@ApiLog(title = "用户签收", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("用户签收")
	@ResponseBody
	@PostMapping(value = "/user/sign/for")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO userSignFor(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		gradeOrderService.userSignFor(id, inDto.getUserId());
		return OutDTO.ok();
	}


	@ApiLog(title = "取消", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("取消")
	@ResponseBody
	@PostMapping(value = "/cancel")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO cancelOrder(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		UserInfo userInfo = UserUtils.getSimpleUserInfo();
		Integer userId = userInfo != null && UserType.USER_ROLE_ADMIN.equals(userInfo.getRoleCode()) ? null : inDto.getUserId();
		gradeOrderService.cancelOrder(userId, id);
		return OutDTO.ok();
	}

	@ApiLog(title = "用户编辑收货地址", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("用户编辑收货地址")
	@ResponseBody
	@PostMapping(value = "/edit/address")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO editAddress(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		Integer addressId = inDto.getIntegerParam("addressId");
		gradeOrderService.editAddress(inDto.getUserId(), id, addressId);
		return OutDTO.ok();
	}

	@ApiLog(title = "用户申请退款", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("用户申请退款")
	@ResponseBody
	@PostMapping(value = "/apply/refund")
	@ApiVersion(2.0)
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO applyRefund(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		gradeOrderService.applyRefund(inDto.getUserId(), id);
		return OutDTO.ok();
	}

	@ApiLog(title = "填写回寄用户物流", businessType = BusinessType.UPDATE, indto = "{{inDto}}")
	@ApiOperation("填写回寄用户物流")
	@ResponseBody
	@PostMapping(value = "/send/grade/shipping")
	@ApiVersion(2.0)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作频繁,请稍后再试!")
	public OutDTO addSendGradeShipping(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String courierNum = inDto.getString("courierNum");
		String courierCompany = inDto.getString("courierCompany");
		String courierImg = inDto.getString("courierImg");
		if (id == null || StringUtils.isEmpty(courierNum) || StringUtils.isEmpty(courierCompany)) {
			return OutDTO.error500("物流信息缺失!");
		}
		gradeOrderService.addSendGradeShipping(id, courierCompany, courierNum, courierImg);
		return OutDTO.ok();
	}


}
