package com.ywt.outpatient.controllers;

import com.ywt.biz.common.constant.YwtCommonRespCode;
import com.ywt.biz.common.enums.OrderTypeEnum;
import com.ywt.biz.common.exception.YwtCommonException;
import com.ywt.biz.common.util.Checker;
import com.ywt.gapi.nat.*;
import com.ywt.outpatient.api.req.CancelNatOrderReq;
import com.ywt.outpatient.api.req.CreateNatOrderReq;
import com.ywt.outpatient.api.req.GetNatOrderDetailReq;
import com.ywt.outpatient.api.req.GetNatOrderListReq;
import com.ywt.outpatient.api.resp.*;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.core.utils.BizUtil;
import com.ywt.outpatient.core.utils.CheckUtil;
import com.ywt.outpatient.domain.models.enums.DatePeriodEnum;
import com.ywt.outpatient.domain.models.enums.NatOrderExtStatusEnum;
import com.ywt.outpatient.domain.models.enums.NatOrderStatusEnum;
import com.ywt.outpatient.service.web.UserSrv;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.stream.Collectors;

/**
 * @author Walker
 * Created on 2021/1/25
 */
@RestController("/nat")
@RequestMapping(value = {"/nat"})
public class NatController {
    private final Logger logger = LoggerFactory.getLogger(NatController.class);
    @DubboReference
    NatService natServiceBlockingStub;
    @Autowired
    UserSrv userSrv;

    @RequestMapping(value = {"/createOrder"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<CreateNatOrderResp> createOrder(@RequestBody CreateNatOrderReq reqData) {
        BaseResponse2<CreateNatOrderResp> baseResponse = new BaseResponse2<>();
        try {
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (hospitalId <= 0) hospitalId = BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped());
            if (hospitalId <= 0)
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, String.format("请指定医院(t:%d)", BizUtil.getCurrentTerminalWrapped()));
            int userId = userSrv.getCurrentUserIdWrapped();
            String name = Checker.getStringValue(reqData.getName());
            String idCardNo = Checker.getStringValue(reqData.getIdCardNo());
            String mobile = Checker.getStringValue(reqData.getMobile());
            String regDate = Checker.getStringValue(reqData.getRegDate());
            int regTimePeriod = Checker.getIntegerValue(reqData.getRegTimePeriod());
            String address = Checker.getStringValue(reqData.getAddress());
            int amount = Checker.getIntegerValue(reqData.getAmount());
            CreateOrderResponse response = natServiceBlockingStub.createOrder(CreateOrderRequest.newBuilder()
                    .setHospitalId(hospitalId)
                    .setUserId(userId)
                    .setName(name)
                    .setIdCardNo(idCardNo)
                    .setMobile(mobile)
                    .setRegDate(regDate)
                    .setRegTimePeriod(regTimePeriod)
                    .setAddress(address)
                    .setAmount(amount)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                CreateNatOrderResp resp = new CreateNatOrderResp();
                resp.setOrderId(response.getOrderId());
                resp.setOrderNo(response.getOrderNo());
                resp.setHasPaid(response.getHasPaid());
                resp.setNatOrderId(response.getNatOrderId());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("NatController#createOrder(reqData={} ):\n {}", reqData, e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    @RequestMapping(value = {"/orderDetail"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<GetNatOrderDetailResp> orderDetail(@RequestBody GetNatOrderDetailReq reqData) {
        BaseResponse2<GetNatOrderDetailResp> baseResponse = new BaseResponse2<>();
        try {
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            GetOrderDetailResponse response = natServiceBlockingStub.getOrderDetail(GetOrderDetailRequest.newBuilder()
                    .setNatOrderId(Checker.getIntegerValue(reqData.getNatOrderId()))
                    .setOrderNo(Checker.getStringValue(reqData.getOrderNo()))
                    .setOrderId(Checker.getIntegerValue(reqData.getOrderId()))
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                OrderDetail detail = response.getOrderDetail();
                GetNatOrderDetailResp resp = convertPojo(detail);
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("NatController#orderDetail(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private GetNatOrderDetailResp convertPojo(OrderDetail detail) {
        GetNatOrderDetailResp resp = new GetNatOrderDetailResp();
        resp.setId(detail.getId());
        resp.setOrderId(detail.getOrderId());
        resp.setOrderNo(detail.getOrderNo());
        resp.setHospitalId(detail.getHospitalId());
        resp.setCreateTime(detail.getCreateTime());
        resp.setAmount(detail.getAmount());
        resp.setUserId(detail.getUserId());
        resp.setPatientName(detail.getPatientName());
        resp.setIdCard(detail.getIdCard());
        resp.setMobile(detail.getMobile());
        resp.setRegDate(detail.getRegDate());
        resp.setRegTimePeriod(detail.getRegTimePeriod());
        resp.setAddress(detail.getAddress());
        int status = detail.getStatus();
        resp.setStatus(status);
        resp.setPaymentStatus(detail.getPaymentStatus());
        resp.setPayTime(detail.getPayTime());
        resp.setRefundTime(detail.getRefundTime());
        resp.setPaymentCode(detail.getPaymentCode());
        resp.setVaccineCode(detail.getVaccineCode());
        resp.setRemark(detail.getRemark());
        resp.setStatusStr(NatOrderStatusEnum.valueOf(status).getDisplayName());
        int extStatus = detail.getExtStatus();
        resp.setExtStatus(extStatus);
        resp.setOrderTitle("核酸检测缴费");
        resp.setOrderType(OrderTypeEnum.NAT.getValue());
        resp.setHospitalName(BizUtil.getHospitalNameByIdSimply(detail.getHospitalId()));
        resp.setDoctorName("-");
        resp.setDeptName("-");
        resp.setStrTime(String.format("%s %s", detail.getRegDate(), DatePeriodEnum.valueOf(detail.getRegTimePeriod()).getDisplayName()));
        resp.setStrAmount(String.format("￥%.2f", detail.getAmount() / 100d));
        resp.setCancel(NatOrderStatusEnum.valueOf(status) == NatOrderStatusEnum.PAID && NatOrderExtStatusEnum.valueOf(extStatus) != NatOrderExtStatusEnum.EXECUTED);
        return resp;
    }

    @RequestMapping(value = {"/orderList"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<PageListResponse<GetNatOrderDetailResp>> orderList(@RequestBody GetNatOrderListReq reqData) {
        BaseResponse2<PageListResponse<GetNatOrderDetailResp>> baseResponse = new BaseResponse2<>();
        try {
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (hospitalId <= 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped());
            }
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            GetOrderListResponse response = natServiceBlockingStub.getOrderList(GetOrderListRequest.newBuilder()
                    .setPageIndex(Checker.getIntegerValue(reqData.getPageIndex()))
                    .setPageSize(Checker.getIntegerValue(reqData.getPageSize()))
                    .setHospitalId(hospitalId)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                PageListResponse<GetNatOrderDetailResp> resp = new PageListResponse<>();
                resp.setList(response.getOrderDetailList().stream()
                        .map(this::convertPojo)
                        .collect(Collectors.toList()));
                resp.setCount(response.getCount());
                resp.setTotalPages(response.getTotalPages());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("NatController#orderList(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    @RequestMapping(value = {"/config"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<GetNatOrderConfigResp> config() {
        BaseResponse2<GetNatOrderConfigResp> baseResponse = new BaseResponse2<>();
        try {
            GetConfigResponse response = natServiceBlockingStub.getConfig(GetConfigRequest.newBuilder()
                    .setHospitalId(BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped()))
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                GetNatOrderConfigResp resp = new GetNatOrderConfigResp();
                resp.setFee(response.getFee());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (Exception e) {
            logger.error("NatController#config(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    @RequestMapping(value = {"/cancelOrder"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse cancelOrder(@RequestBody CancelNatOrderReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int natOrderId = Checker.getIntegerValue(reqData.getNatOrderId());
            CheckUtil.ensureLargerThanZero(natOrderId, "核酸检测订单 id 有误");
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            BaseInfoResponse response = natServiceBlockingStub.cancelOrder(CancelOrderRequest.newBuilder()
                    .setNatOrderId(natOrderId)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed(response.getInfo());
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("NatController#cancelOrder(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }
}
