package com.jumeirah.api.app.controller;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jumeirah.api.app.entity.param.StrokeAddBackAndForthParam;
import com.jumeirah.api.app.entity.param.StrokeAddFreightParam;
import com.jumeirah.api.app.entity.param.StrokeAddMedicalTreatmentParam;
import com.jumeirah.api.app.entity.param.StrokeAddOneWayParam;
import com.jumeirah.api.app.entity.param.StrokeDiscountParam;
import com.jumeirah.common.constant.Constant;
import com.jumeirah.common.entity.Stroke;
import com.jumeirah.common.enums.StatePaymentStatusEnum;
import com.jumeirah.common.enums.StrokeTypeEnum;
import com.jumeirah.common.param.StrokePageParam;
import com.jumeirah.common.param.app.StrokePaymentInfoParam;
import com.jumeirah.common.service.StrokeDiscountService;
import com.jumeirah.common.service.StrokeService;
import com.jumeirah.common.vo.StrokeDetailVo;
import com.jumeirah.common.vo.StrokeDiscountQueryVo;
import com.jumeirah.common.vo.StrokeQueryVo;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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 java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.Instant;

/**
 * 行程表 控制器
 *
 * @author wei
 * @since 2020-09-29
 */
@Slf4j
@RestController
@RequestMapping("/app/stroke")
@Api(value = "行程API", tags = {"行程"})
public class StrokeController extends BaseController {

    @Autowired
    private StrokeService strokeService;
    @Autowired
    private StrokeDiscountService strokeDiscountService;
    /**
     * 填写付款信息
     */
    @PostMapping("/add/paymentInfo")
    @OperationLog(name = "填写付款信息", type = OperationLogType.ADD)
    @ApiOperation(value = "填写付款信息", response = ApiResult.class)
    public ApiResult<Boolean> addPaymentInfo(@Validated @RequestBody StrokePaymentInfoParam strokePaymentInfoParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        Stroke stroke = new Stroke();
        BeanUtils.copyProperties(strokePaymentInfoParam, stroke);
        stroke.setPaymentStatus(StatePaymentStatusEnum.PAYING.getCode());
        stroke.setUserRechargeTime(Timestamp.from(Instant.now()));
        boolean flag = strokeService.update(stroke, new UpdateWrapper<Stroke>().lambda()
                .eq(Stroke::getUserId, jwtToken.getUserId())
                .eq(Stroke::getId, strokePaymentInfoParam.getId())
        );
        return ApiResult.result(flag);
    }


    /**
     * 添加单程行程表
     */
    @PostMapping("/add/oneWay")
    @OperationLog(name = "添加单程行程表", type = OperationLogType.ADD)
    @ApiOperation(value = "添加单程行程表", response = ApiResult.class)
    public ApiResult<Boolean> addOneWayStroke(@Validated @RequestBody StrokeAddOneWayParam strokeAddOneWayParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        Stroke stroke = new Stroke();
        BeanUtils.copyProperties(strokeAddOneWayParam, stroke);
        stroke.setType(StrokeTypeEnum.ONE_WAY.getCode())
                .setMoney(new BigDecimal("0"))
                .setMcId(Constant.MC_ID)
                .setUserId(jwtToken.getUserId());
        boolean flag = strokeService.saveStroke(stroke);
        return ApiResult.result(flag);
    }

    /**
     * 添加往返行程表
     */
    @PostMapping("/add/backAndForth")
    @OperationLog(name = "添加往返行程表", type = OperationLogType.ADD)
    @ApiOperation(value = "添加往返行程表", response = ApiResult.class)
    public ApiResult<Boolean> addBackAndForthStroke(@Validated @RequestBody StrokeAddBackAndForthParam strokeAddBackAndForthParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        Stroke stroke = new Stroke();
        BeanUtils.copyProperties(strokeAddBackAndForthParam, stroke);
        stroke.setType(StrokeTypeEnum.ROUND_TRIP.getCode())
                .setMoney(new BigDecimal("0"))
                .setMcId(Constant.MC_ID)
                .setUserId(jwtToken.getUserId());
        boolean flag = strokeService.saveStroke(stroke);
        return ApiResult.result(flag);
    }

    /**
     * 添加货运行程表
     */
    @PostMapping("/add/freight")
    @OperationLog(name = "添加货运行程表", type = OperationLogType.ADD)
    @ApiOperation(value = "添加货运行程表", response = ApiResult.class)
    public ApiResult<Boolean> addFreightStroke(@Validated @RequestBody StrokeAddFreightParam strokeAddFreightParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        Stroke stroke = new Stroke();
        BeanUtils.copyProperties(strokeAddFreightParam, stroke);
        stroke.setType(StrokeTypeEnum.CARGO_FLIGHT.getCode())
                .setMoney(new BigDecimal("0"))
                .setMcId(Constant.MC_ID)
                .setUserId(jwtToken.getUserId());
        boolean flag = strokeService.saveStroke(stroke);
        return ApiResult.result(flag);
    }

    /**
     * 添加医疗行程表
     */
    @PostMapping("/add/medicalTreatment")
    @OperationLog(name = "添加医疗行程表", type = OperationLogType.ADD)
    @ApiOperation(value = "添加医疗行程表", response = ApiResult.class)
    public ApiResult<Boolean> addMedicalTreatmentStroke(
            @Validated @RequestBody StrokeAddMedicalTreatmentParam strokeAddMedicalTreatmentParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        Stroke stroke = new Stroke();
        BeanUtils.copyProperties(strokeAddMedicalTreatmentParam, stroke);
        stroke.setType(StrokeTypeEnum.MEDICAL_FLIGHT.getCode())
                .setMoney(new BigDecimal("0"))
                .setMcId(Constant.MC_ID)
                .setUserId(jwtToken.getUserId());
        boolean flag = strokeService.saveStroke(stroke);
        return ApiResult.result(flag);
    }

    /**
     * 添加优惠调机行程
     */
    @PostMapping("/add/discount")
    @OperationLog(name = "添加优惠调机行程", type = OperationLogType.ADD)
    @ApiOperation(value = "添加优惠调机行程", response = ApiResult.class)
    public ApiResult<Boolean> addOneWayStroke(@Validated @RequestBody StrokeDiscountParam strokeDiscountParam) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        StrokeDiscountQueryVo strokeDiscountQueryVo = strokeDiscountService.getStrokeDiscountById(strokeDiscountParam.getSdId());
        Stroke stroke = new Stroke();
        stroke.setType(strokeDiscountQueryVo.getType())
                .setCityOutsetId(strokeDiscountQueryVo.getCityOutsetId())
                .setCityArriveId(strokeDiscountQueryVo.getCityArriveId())
                .setPeopleNum(strokeDiscountParam.getPeopleNum())
                .setPlainTypeId(strokeDiscountQueryVo.getPlainTypeId())
                .setOutsetTime(strokeDiscountParam.getOutsetTime())
                .setMoney(strokeDiscountQueryVo.getMoney())
                .setMcId(strokeDiscountQueryVo.getMcId())
                .setIsDiscount(true)
                .setUserId(jwtToken.getUserId());
        boolean flag = strokeService.saveStroke(stroke);
        return ApiResult.result(flag);
    }


//    /**
//     * 修改行程表
//     */
//    @PostMapping("/update")
//    @OperationLog(name = "修改行程表", type = OperationLogType.UPDATE)
//    @ApiOperation(value = "修改行程表", response = ApiResult.class)
//    public ApiResult<Boolean> updateStroke(@Validated(Update.class) @RequestBody Stroke stroke) throws Exception {
//        boolean flag = strokeService.updateStroke(stroke);
//        return ApiResult.result(flag);
//    }

    /**
     * 删除行程表
     */
    @PostMapping("/delete/{id}")
    @OperationLog(name = "删除行程表", type = OperationLogType.DELETE)
    @ApiOperation(value = "删除行程表", response = ApiResult.class)
    public ApiResult<Boolean> deleteStroke(@PathVariable("id") Long id) throws Exception {
        boolean flag = strokeService.deleteStroke(id);
        return ApiResult.result(flag);
    }

    /**
     * 取消行程
     */
    @PostMapping("/cancel/{id}")
    @OperationLog(name = "取消行程", type = OperationLogType.UPDATE)
    @ApiOperation(value = "取消行程", response = ApiResult.class)
    public ApiResult<Boolean> cancel(@PathVariable("id") Long id) throws Exception {
        boolean flag = strokeService.cancelStroke(id);
        return ApiResult.result(flag);
    }

    /**
     * 获取行程表详情
     */
    @GetMapping("/info/{id}")
    @OperationLog(name = "行程表详情", type = OperationLogType.INFO)
    @ApiOperation(value = "行程表详情", response = StrokeDetailVo.class)
    public ApiResult<StrokeDetailVo> getStroke(@PathVariable("id") Long id) throws Exception {
        StrokeDetailVo strokeQueryVo = strokeService.getStrokeById(id);
        return ApiResult.ok(strokeQueryVo);
    }

//    /**
//     * 行程表分页列表
//     */
//    @PostMapping("/getPageList")
//    @OperationLog(name = "行程表分页列表", type = OperationLogType.PAGE)
//    @ApiOperation(value = "行程表分页列表", response = StrokeQueryVo.class)
//    public ApiResult<Paging<StrokeQueryVo>> getStrokePageList(@Validated @RequestBody StrokePageParam strokePageParam) throws Exception {
//        Paging<StrokeQueryVo> paging = strokeService.getStrokePageList(strokePageParam);
//        return ApiResult.ok(paging);
//    }

    /**
     * 行程表分页列表
     */
    @PostMapping("/getMyStrokePageList")
    @OperationLog(name = "行程分页列表", type = OperationLogType.PAGE)
    @ApiOperation(value = "行程分页列表")
    public ApiResult<Paging<StrokeQueryVo>> getMyStrokePageList(@Validated @RequestBody StrokePageParam strokePageParam) throws Exception {
        Paging<StrokeQueryVo> paging = strokeService.getStrokePageList(strokePageParam);
        return ApiResult.ok(paging);
    }

}

