package com.jsowell.api.uniapp;

import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.jsowell.common.annotation.Anonymous;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.response.RestApiResponse;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.dto.ApplyOrderInvoiceDTO;
import com.jsowell.pile.dto.GenerateOrderDTO;
import com.jsowell.pile.dto.QueryInvoiceRecordDTO;
import com.jsowell.pile.dto.QueryOrderDTO;
import com.jsowell.pile.dto.SettleOrderDTO;
import com.jsowell.pile.dto.StopChargingDTO;
import com.jsowell.pile.dto.UniAppQueryOrderDTO;
import com.jsowell.pile.vo.base.StationInfoVO;
import com.jsowell.pile.vo.uniapp.OrderVO;
import com.jsowell.pile.vo.uniapp.UniAppOrderVO;
import com.jsowell.service.OrderService;
import com.jsowell.wxpay.dto.WechatSendMsgDTO;
import com.jsowell.wxpay.service.WxAppletRemoteService;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 订单相关接口
 * 提供给小程序
 */
@Anonymous
@RestController
@RequestMapping("/uniapp/order")
public class OrderController extends BaseController {

	@Autowired
	private OrderService orderService;

	@Autowired
	private WxAppletRemoteService wxAppletRemoteService;

	/**
	 * 生成订单
	 * http://localhost:8080/uniapp/order/generateOrder
	 */
	@PostMapping("/generateOrder")
	public RestApiResponse<?> generateOrder(HttpServletRequest request, @RequestBody GenerateOrderDTO dto) {
		logger.info("生成订单 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response;
		try {
			if ((StringUtils.isBlank(dto.getPileSn()) || StringUtils.isBlank(dto.getConnectorCode())) && StringUtils.isBlank(dto.getPileConnectorCode())) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isEmpty(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR);
			}
			dto.setMemberId(memberId);
			// 生成订单
			dto.setStartMode(Constants.ONE); // 启动方式 1-app启动
			String orderCode = orderService.generateOrder(dto);
			response = new RestApiResponse<>(ImmutableMap.of("orderCode", orderCode));
		} catch (BusinessException e) {
			logger.warn("生成订单 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("生成订单 error", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_GENERATE_ORDER_ERROR);
		}
		logger.info("生成订单 result:{}", JSONObject.toJSONString(response));
		return response;
	}

	/**
	 * 停止充电
	 * http://localhost:8080/uniapp/order/stopCharging
	 */
	@PostMapping ("/stopCharging")
	public RestApiResponse<?> stopCharging(HttpServletRequest request, @RequestBody StopChargingDTO dto) {
		logger.info("停止充电 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isEmpty(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR);
			}
			dto.setMemberId(memberId);
			orderService.stopCharging(dto);
			response = new RestApiResponse<>();
		} catch (BusinessException e) {
			logger.warn("停止充电 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("停止充电 error", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_STOP_CHARGING_ERROR);
		}
		return response;
	}

	/**
	 * 结算订单
	 * http://localhost:8080/uniapp/order/settleOrder
	 * @param dto 结算订单DTO
	 * @return
	 */
	@PostMapping("/settleOrderForWeb")
	public RestApiResponse<?> settleOrder(HttpServletRequest request, @RequestBody SettleOrderDTO dto) {
		logger.info("结算订单 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response;
		try {
			orderService.settleOrderForWeb(dto);
			response = new RestApiResponse<>();
		} catch (Exception e) {
			logger.error("结算订单错误", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_SETTLE_ORDER_ERROR);
		}
		return response;
	}

	/**
	 * 查询订单信息
	 * http://localhost:8080/uniapp/order/getOrderList
	 * @return
	 */
	@PostMapping("/getOrderList")
	public RestApiResponse<?> getOrderInfo(HttpServletRequest request, @RequestBody UniAppQueryOrderDTO dto) {
		logger.info("查询订单信息 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response = null;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			// 通过memberId查询某状态订单列表
			PageResponse pageInfoList = orderService.getListByMemberIdAndOrderStatus(memberId, dto);
			response = new RestApiResponse<>(pageInfoList);
		} catch (BusinessException e) {
			logger.warn("查询订单信息 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		}  catch (Exception e) {
			logger.error("查询订单信息 error", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_GET_ORDER_INFO_BY_MEMBER_ID_ERROR);
		}
		logger.info("查询订单信息, result:{}", JSONObject.toJSONString(response));
		return response;
	}

	/**
	 * 小程序获取订单详情
	 * http://localhost:8080/uniapp/order/getOrderDetail
	 * @param request
	 * @param dto
	 * @return
	 */
	@PostMapping("/getOrderDetail")
	public RestApiResponse<?> getOrderDetail(HttpServletRequest request, @RequestBody UniAppQueryOrderDTO dto) {
		logger.info("小程序获取订单详情 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response = null;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			UniAppOrderVO uniAppOrderDetail = orderService.getUniAppOrderDetail(dto.getOrderCode());
			response = new RestApiResponse<>(uniAppOrderDetail);
		} catch (BusinessException e) {
			logger.warn("小程序获取订单详情 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("小程序获取订单详情 error", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_GET_ORDER_DETAIL_ERROR);
		}
		logger.info("小程序获取订单详情, result:{}", JSONObject.toJSONString(response));
		return response;
	}

	/**
	 * 根据订单号查询充电桩启动状态
	 * http://localhost:8080/uniapp/order/selectPileStarterStatus
	 */
	@PostMapping("/selectPileStarterStatus")
	public RestApiResponse<?> selectPileStarterStatus(HttpServletRequest request, @RequestBody UniAppQueryOrderDTO dto) {
		logger.info("根据订单号查询充电桩启动状态 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response = null;
		try {
			// String memberId = getMemberIdByAuthorization(request);
			String status = orderService.selectPileStarterStatus(dto.getOrderCode());
			response = new RestApiResponse<>(ImmutableMap.of("status", status));
		} catch (Exception e) {
			logger.error("根据订单号查询充电桩启动状态 error", e);
			response = new RestApiResponse<>(ReturnCodeEnum.CODE_GET_ORDER_DETAIL_ERROR);
		}
		logger.info("根据订单号查询充电桩启动状态 result:{}", JSONObject.toJSONString(response));
		return response;
	}

	/**
	 * 微信小程序发送启动充电推送消息
	 * http://localhost:8080/uniapp/order/uniAppStartChargingSendMsg
	 * @param dto
	 * @return
	 */
	@PostMapping("/uniAppStartChargingSendMsg")
	public RestApiResponse<?> uniAppStartChargingSendMsg(@RequestBody WechatSendMsgDTO dto) {
		logger.info("微信小程序发送启动充电推送消息 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response = null;
		try {
			Map<String, String> resultMap = wxAppletRemoteService.startChargingSendMsg(dto);
			response = new RestApiResponse<>(resultMap);
		} catch (Exception e){
			logger.error("微信小程序发送启动充电推送消息 error", e);
			response = new RestApiResponse<>("00300001", "微信小程序发送启动充电推送消息异常");
		}
		logger.info("微信小程序发送启动充电推送消息 result:{}", response);
		return response;
	}

	/**
	 * 关闭支付未启动的订单
	 * http://localhost:8080/uniapp/order/closeStartFailedOrder
	 */
	@PostMapping("/closeStartFailedOrder")
	public RestApiResponse<?> closeStartFailedOrder(@RequestBody QueryOrderDTO dto) {
		logger.info("关闭支付未启动的订单 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response = null;
		try {
			orderService.closeStartFailedOrder(dto);
			response = new RestApiResponse<>();
		} catch (Exception e){
			logger.error("关闭支付未启动的订单 error", e);
			response = new RestApiResponse<>("00300002", "关闭支付未启动的订单异常");
		}
		logger.info("关闭支付未启动的订单 result:{}", response);
		return response;
	}

	/**
	 * 查询未开发票订单
	 * 时间限制15天内
	 * http://localhost:8080/uniapp/order/queryUninvoicedOrderList
	 */
	@PostMapping("/queryUninvoicedOrderList")
	public RestApiResponse<?> queryUninvoicedOrderList(HttpServletRequest request, @RequestBody QueryOrderDTO dto) {
		logger.info("查询未开发票订单 param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			dto.setMemberId(memberId);
			List<OrderVO> list = orderService.queryUninvoicedOrderList(dto);
			response = new RestApiResponse<>(ImmutableMap.of("list", list));
		} catch (BusinessException e) {
			logger.error("查询未开发票订单 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e){
			logger.error("查询未开发票订单 error", e);
			response = new RestApiResponse<>("00300003", "查询未开发票订单异常");
		}
		return response;
	}

	/**
	 * 查询未开发票的站点list
	 * http://localhost:8080/uniapp/order/queryUninvoicedStationList
	 * @param request
	 * @param dto
	 * @return
	 */
	@PostMapping("/queryUninvoicedStationList")
	public RestApiResponse<?> queryUninvoicedStationList(HttpServletRequest request, @RequestBody QueryOrderDTO dto) {
		logger.info("查询未开发票的站点list param:{}", JSONObject.toJSONString(dto));
		RestApiResponse<?> response;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			dto.setMemberId(memberId);
			List<StationInfoVO> list = orderService.queryUninvoicedStationList(dto);
			response = new RestApiResponse<>(ImmutableMap.of("list", list));
		} catch (BusinessException e) {
			logger.error("查询未开发票的站点list warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e){
			logger.error("查询未开发票的站点list error", e);
			response = new RestApiResponse<>("00300004", "查询未开发票的站点list异常");
		}
		return response;
	}

	/**
	 * 申请开票接口
	 * http://localhost:8080/uniapp/order/applyOrderInvoice
	 */
	@PostMapping("/applyOrderInvoice")
	public RestApiResponse<?> applyOrderInvoice(HttpServletRequest request, @RequestBody ApplyOrderInvoiceDTO dto) {
		RestApiResponse<?> response;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			dto.setMemberId(memberId);
			orderService.applyOrderInvoice(dto);
			response = new RestApiResponse<>();
		} catch (BusinessException e) {
			logger.error("查询未开发票订单 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e){
			logger.error("查询未开发票订单 error", e);
			response = new RestApiResponse<>("00300003", "查询未开发票订单异常");
		}
		return response;
	}

	/**
	 * 查询会员申请开票记录
	 * http://localhost:8080/uniapp/order/queryInvoiceRecord
	 * @param request
	 * @return
	 */
	@PostMapping("/queryInvoiceRecord")
	public RestApiResponse<?> queryInvoiceRecord(HttpServletRequest request, @RequestBody QueryInvoiceRecordDTO dto) {
		RestApiResponse<?> response;
		try {
			String memberId = getMemberIdByAuthorization(request);
			if (StringUtils.isBlank(memberId)) {
				throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
			}
			dto.setMemberId(memberId);
			PageResponse pageResponse = orderService.queryInvoiceRecord(dto);
			response = new RestApiResponse<>(pageResponse);
		} catch (BusinessException e) {
			logger.error("查询会员申请开票记录 warn", e);
			response = new RestApiResponse<>(e.getCode(), e.getMessage());
		} catch (Exception e){
			logger.error("查询会员申请开票记录 error", e);
			response = new RestApiResponse<>("00300003", "查询会员申请开票记录异常");
		}
		return response;
	}
}
