package com.xxfc.platform.vehicle.rest;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.google.common.collect.Maps;
import com.xxfc.platform.vehicle.biz.VehicleBiz;
import com.xxfc.platform.vehicle.biz.VehicleBookRecordBiz;
import com.xxfc.platform.vehicle.biz.VehiclePlatCataBiz;
import com.xxfc.platform.vehicle.biz.VehicleWarningMsgBiz;
import com.xxfc.platform.vehicle.common.BaseController;
import com.xxfc.platform.vehicle.common.CustomIllegalParamException;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.BookType;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleBookInfo;
import com.xxfc.platform.vehicle.entity.VehicleBookRecord;
import com.xxfc.platform.vehicle.pojo.*;
import com.xxfc.platform.vehicle.pojo.dto.VehiclePlanDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import static com.xxfc.platform.vehicle.constant.VehicleConstant.USER_APP;
import static com.xxfc.platform.vehicle.constant.VehicleConstant.USER_APP_NAME;

@RestController
@RequestMapping("/vehicleInfo")
@Slf4j
@IgnoreClientToken
@Api(value="车辆管理controller",tags={"车辆管理接口"})
public class VehicleController extends BaseController<VehicleBiz> {

    @Autowired
    private VehicleBookRecordBiz vehicleBookRecordBiz;

    @Autowired
    VehicleBiz vehicleBiz;

    @Autowired
    UserFeign userFeign;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Autowired
    private VehiclePlatCataBiz vehiclePlatCataBiz;

    @Autowired
    private VehicleWarningMsgBiz vehicleWarningMsgBiz;


    private static Integer MAX_DRIVING_LICENSE_SIZE = 10 * 1024 * 1024;//10M

    public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public RestResponse<Vehicle> get(@PathVariable String id) {
        return RestResponse.data(baseBiz.get(id));
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public RestResponse add(@RequestBody List<AddOrUpdateVehicleVo> addOrUpdateVehicleVoList) throws Exception {
        return baseBiz.add(addOrUpdateVehicleVoList);
    }

    @RequestMapping(value = "", method = RequestMethod.PUT)
    public RestResponse update(@RequestBody List<AddOrUpdateVehicleVo> addOrUpdateVehicleVoList) throws Exception {
        return baseBiz.update(addOrUpdateVehicleVoList);
    }

    @RequestMapping(value = "", method = RequestMethod.DELETE)
    public RestResponse discard(@RequestBody List<String> idList) throws Exception {
        return baseBiz.discard(idList);
    }

    @RequestMapping(value = "/findById", method = RequestMethod.GET)
    public RestResponse<Vehicle> findById(String id) {
       Vehicle vehicle =  baseBiz.get(id);
        return RestResponse.data(vehicle);
    }

    @RequestMapping(value = "/getByIds", method = RequestMethod.GET)
    public RestResponse< List<Vehicle>> getByIds(@RequestParam("ids") List<String> ids){
        if(ids == null) {
            return RestResponse.codeAndMessage(500, "参数为空！");
        }
        List<Vehicle> vehicles = new ArrayList<>();
        for(String id : ids) {
            log.info("查询车辆信息Id：{}",id);
            Vehicle vehicle =  baseBiz.get(id);
            vehicles.add(vehicle);
        }
      return RestResponse.suc(vehicles);
    }

    @RequestMapping(value = "/page", method = RequestMethod.GET)
    public RestResponse<PageDataVO<ResultVehicleVo>> getByPage(@RequestParam String vehiclePageQueryVoJson) throws Exception {
        VehiclePageQueryVo vehiclePageQueryVo = null;
        try {
            vehiclePageQueryVo = JSON.parseObject(vehiclePageQueryVoJson, VehiclePageQueryVo.class);

            UserDTO userDTO = userFeign.userinfoByToken(userAuthConfig.getToken(request)).getData();
            if (userDTO != null) {
                if (userDTO.getDataAll() == 2) {
                    List<Integer> companyList = vehicleBiz.dataCompany(userDTO.getDataZone(), userDTO.getDataCompany());
                    return RestResponse.data(baseBiz.getByPageNotAllData(vehiclePageQueryVo, companyList));
                }
            }

            return RestResponse.data(baseBiz.getByPage(vehiclePageQueryVo));
        } catch (JSONException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        } catch (CustomIllegalParamException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }
    }

    @RequestMapping(value = "/small/page", method = RequestMethod.GET)
    @IgnoreUserToken
    public RestResponse<PageDataVO<ResultVehicleVo>> getByPageBySmall(@RequestParam String vehiclePageQueryVoJson,@RequestParam Integer uid) throws Exception {
        VehiclePageQueryVo vehiclePageQueryVo = null;
        try {
            vehiclePageQueryVo = JSON.parseObject(vehiclePageQueryVoJson, VehiclePageQueryVo.class);
            UserDTO userDTO = userFeign.userinfoByUid(uid).getData();
            if (userDTO != null) {
                if (userDTO.getDataAll() == 2) {
                    List<Integer> companyList = vehicleBiz.dataCompany(userDTO.getDataZone(), userDTO.getDataCompany());
                    return RestResponse.data(baseBiz.getByPageNotAllData(vehiclePageQueryVo, companyList));
                }
            }

            return RestResponse.data(baseBiz.getByPage(vehiclePageQueryVo));
        } catch (JSONException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        } catch (CustomIllegalParamException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }
    }

    @RequestMapping(value = "/upload/drivingLicense", method = RequestMethod.POST)
    @ApiOperation(value = "上传驾驶员驾驶证")
    public RestResponse uploadDrivingLicense(@RequestParam("file") MultipartFile file)
            throws Exception {
        String contentType = file.getContentType();   //图片文件类型
//        String fileName = file.getOriginalFilename();  //图片名字
        if (!contentType.equals("image/jpeg") && !contentType.equals("image/gif")) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }
        if (file.getSize() > MAX_DRIVING_LICENSE_SIZE) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }
        return baseBiz.uploadDrivingLicense(file);
    }


    @IgnoreUserToken
    @RequestMapping(value = "/download/drivingLicense", method = RequestMethod.GET) //匹配的是href中的download请求
    @ApiOperation(value = "下载驾驶证")
    public ResponseEntity<byte[]> downloadDrivingLicense(@RequestParam("realFileRelPath") String realFileRelPath) throws Exception {
        return baseBiz.downloadDrivingLicense(realFileRelPath);
    }

    @RequestMapping(value = "/bookedInfo/{vehicleId}/{yearMonth}", method = RequestMethod.GET)
    @ApiOperation(value = "获取车辆预定信息")
    public RestResponse<VehicleBookInfo> getBookedInfo(@PathVariable String vehicleId, @PathVariable String yearMonth) {
        return RestResponse.data(baseBiz.getByVehicleIdAndYearMonth(vehicleId, yearMonth));
    }

    @RequestMapping(value = "/bookedInfo/{vehicleId}", method = RequestMethod.GET)
    @ApiOperation(value = "根据车辆Id获取所有的预定信息")
    public RestResponse<List<VehicleBookInfo>> getBookedInfo(@PathVariable String vehicleId) {
        return RestResponse.data(baseBiz.getByVehicleIdAndYearMonth(vehicleId));
    }

    /**
     * 申请预定车辆 不需要审核
     *
     * @param bookVehicleVo
     * @return
     */
    @RequestMapping(value = "/book/4employee", method = RequestMethod.POST)
    @ApiOperation(value = "申请预定车辆信息")
    public RestResponse<Integer> applyVehicle(@RequestBody  BookVehicleVO bookVehicleVo) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        baseBiz.applyVehicle(operatorId, bookVehicleVo, userName);
        return RestResponse.suc();
    }

    /**
     * 申请预定车辆 需要审核
     *
     * @param bookVehicleVo
     * @return
     */
    @RequestMapping(value = "/apply/book/vehicle", method = RequestMethod.POST)
    @ApiOperation(value = "申请预定车辆信息")
    public RestResponse<Integer> applyForVehicle(@RequestBody  BookVehicleVO bookVehicleVo) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        baseBiz.applyForVehicle(operatorId, bookVehicleVo, userName);
        return RestResponse.suc();
    }

    /**
     * 批准预定车辆预定
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/book/4employee/prove/{bookRecordId}", method = RequestMethod.PUT)
    @ApiOperation(value = "预定车辆审核通过")
    public RestResponse<Integer> proveVehicleBooking(@PathVariable Long bookRecordId) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        return baseBiz.reviewVehicleBooking(operatorId, bookRecordId, VehicleBookRecordStatus.APPROVE.getCode(), userName);
    }

    /**
     * 拒绝预定车辆申请
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/book/4employee/reject/{bookRecordId}", method = RequestMethod.PUT)
    @ApiOperation(value = "拒绝预定车辆")
    public RestResponse<Integer> rejectVehicleBooking(@PathVariable Long bookRecordId) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        return baseBiz.reviewVehicleBooking(operatorId, bookRecordId, VehicleBookRecordStatus.REJECTED.getCode(), userName);
    }

    /**
     * 租车拒绝预定车辆申请
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/rent/book/reject/{bookRecordId}", method = RequestMethod.PUT)
    @ApiOperation(value = "租车拒绝预定车辆")
    @IgnoreUserToken
    public RestResponse<Integer> rentRejectVehicleBooking(@PathVariable Long bookRecordId) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = USER_APP_NAME;
        return baseBiz.reviewVehicleBooking(operatorId, bookRecordId, VehicleBookRecordStatus.REJECTED.getCode(), userName);
    }


//    /**
//     * 车辆归还
//     * @param bookRecordId
//     * @return
//     */
//    @RequestMapping(value ="/book/4employee/return/{bookRecordId}",method = RequestMethod.PUT)
//    public RestResponse<Integer> returnVehicle(@PathVariable String bookRecordId){
//        //此处待加入获取当前操作用户id信息以及相关权限验证
//        Integer operator = -1;//测试用
//        return baseBiz.returnVehicle(operator, bookRecordId);
//
//    }


    /**
     * 取消车辆预订
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/unbook/4employee/{bookRecordId}", method = RequestMethod.DELETE)
    @ApiOperation(value = "取消预定车辆")
    public RestResponse<Integer> unbookVehicle(@PathVariable Long bookRecordId) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        return baseBiz.unbookVehicle4Employee(operatorId, bookRecordId, userName);
    }

    @RequestMapping(value = "/bookedRecord/{bookEndDate}/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "获取预定记录")
    public RestResponse<QueryVehicleBookRecordVo> getBookedRecord(@PathVariable String bookEndDate, @PathVariable Long id) throws Exception {
        try {
            return RestResponse.codeAndData(RestResponse.SUC_CODE, vehicleBookRecordBiz.getById(id, DateTime.parse(bookEndDate, DEFAULT_FORMATTER)));
        } catch (JSONException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        } catch (CustomIllegalParamException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }

    }


    @RequestMapping(value = "/bookedRecord", method = RequestMethod.GET)
    @ApiOperation(value = "获取多个预定记录")
    public RestResponse<PageDataVO<QueryVehicleBookRecordVo>> getBookedRecord(@RequestParam String vehicleBookRecordQueryVoJson) throws Exception {

        VehicleBookRecordQueryVo vehicleBookRecordQueryVo = null;
        try {
            vehicleBookRecordQueryVo = JSON.parseObject(vehicleBookRecordQueryVoJson, VehicleBookRecordQueryVo.class);
            UserDTO userDTO = userFeign.userinfoByToken(userAuthConfig.getToken(request)).getData();
            List<Integer> companyList =new ArrayList<>();
            if (userDTO != null) {
                if (userDTO.getDataAll() == 2) {
                    companyList = vehicleBiz.dataCompany(userDTO.getDataZone(), userDTO.getDataCompany());
                }
            }
            return RestResponse.data(vehicleBookRecordBiz.page(vehicleBookRecordQueryVo, companyList));
        } catch (JSONException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        } catch (CustomIllegalParamException ex) {
            return RestResponse.code(ResCode.INVALID_REST_REQ_PARAM.getCode());
        }

    }

    /**
     * 提车
     *
     * @param liftVehicleVo
     * @return
     */
    @RequestMapping(value = "/book/4employee/lift", method = RequestMethod.PUT)
    @ApiOperation(value = "提车")
    public RestResponse<Integer> liftVehicle(@RequestBody LiftVehicleVo liftVehicleVo) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName ();
        return vehicleBookRecordBiz.lift(operatorId, userName, liftVehicleVo);
    }

    /**
     * 还车
     *
     * @param retVehicleVo
     * @return
     */
    @RequestMapping(value = "/book/4employee/ret", method = RequestMethod.PUT)
    @ApiOperation(value = "还车")
    public RestResponse<Integer> retVehicle(@RequestBody RetVehicleVo retVehicleVo) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        return vehicleBookRecordBiz.retVehicle(operatorId, userName, retVehicleVo);
    }

    /**
     * 可用车辆查询
     *
     * @param dto
     * @return
     */
    @ApiOperation("可用车辆查询")
    @RequestMapping(value = "/rent/usable-vehicle", method = RequestMethod.GET)
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<UsableVehicleModelVO>> rentUsableVehicle(UsableVeicleDTO dto) throws Exception {
        //根据时间 获得 可用车辆
        //结合车型
        if (StringUtils.isNotBlank(dto.getCatasStr())) {
            dto.setCatas(vehiclePlatCataBiz.groupCatasByParent(dto.getCatasStr()));
        }
        //设置显示是否有车
        dto.setYearNo4Where(Boolean.TRUE);
        return ObjectRestResponse.succ(vehicleBiz.searchUsableModel(dto));
    }

    @ApiOperation("根据权限获取所有车辆")
    @GetMapping(value = "/info/getVehicle")
    public ObjectRestResponse<PageDataVO<VehicleAndModelInfoVo>> getVehicle(VehiclePlanDto vehiclePlanDto) {
        return vehicleBiz.getVehicle(vehiclePlanDto);
    }



    /**
     * 热门车型
     *
     * @param dto
     * @return
     */
    @ApiOperation("热门车型")
    @RequestMapping(value = "/rent/hot-vehicle", method = RequestMethod.GET)
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<UsableVehicleModelVO>> hotVehicle(HotVeicleDTO dto) throws Exception {
        return ObjectRestResponse.succ(vehicleBiz.hotModel(dto));
    }

    /**
     * 租车触发的申请预定车辆
     *
     * @param dto
     * @return
     */
    @ApiOperation("租车触发的申请预定车辆")
    @RequestMapping(value = "/rent/book/vehicle", method = RequestMethod.POST)
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<VehicleBookRecord> rentApplyVehicle(@RequestBody RentVehicleBookDTO dto) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = dto.getUserName();
        //BaseContextHandler.getName();
        dto.setLimit(1);
        dto.setPage(1);
        //查询可车辆信息
        PageDataVO<Vehicle> pageDataVO = vehicleBiz.searchUsableVehicle(dto);
        if (pageDataVO.getData().size() <= 0) {
            throw new BaseException(ResultCode.NOTEXIST_CODE, new HashSet<String>(){{
                add("可用车辆不存在");
            }});
        }
        dto.setBookStartDate(dto.getBookStartDate()+ " 00:00:00");
        dto.setBookEndDate(dto.getBookEndDate()+ " 23:59:59");
        BookVehicleVO bookVehicleVo = BeanUtil.toBean(dto, BookVehicleVO.class);
        bookVehicleVo.setBookType(BookType.USER_RENT.getCode());
        bookVehicleVo.setVehicleId(pageDataVO.getData().get(0).getId());
        VehicleBookRecord vehicleBookRecord = baseBiz.applyVehicle4Employee(operatorId, bookVehicleVo, userName);
        return ObjectRestResponse.succ(vehicleBookRecord);
    }


    @RequestMapping(value = "/app/unauth/getVehiclePlanList", method = RequestMethod.GET)
    @ApiOperation(value = "获取排车信息")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<Map<String, Object>> getVehiclePlanList(VehiclePlanDto vehiclePlanDto) {
        //获取列表
        PageDataVO<VehicleAndModelInfoVo> pageDataVO = baseBiz.getAllVehicle(vehiclePlanDto);
        //获取警告信息
        List<VehicleWarningMsgQueryVo> vehicleWarningMsgs = vehicleWarningMsgBiz.getAllByParam(vehiclePlanDto);
        //获取统计信息
        List<VehicleCountVo> vehicleCountVos = baseBiz.countVehicleByParam(vehiclePlanDto);
        //获取列表
         Map<String, Object> map = Maps.newHashMap();
         map.put("vehicleWarningMsgs",vehicleWarningMsgs);
         map.put("vehicleAndModelInfoVo",pageDataVO);
        map.put("vehicleCountVos",vehicleCountVos);
        return ObjectRestResponse.succ(map);
    }

    @GetMapping(value = "/app/unauth/getBookRecord")
    @ApiOperation(value = "获取预定记录")
    public RestResponse<PageDataVO> getRecord(VehicleBookRecordQueryVo vehicleBookRecordQueryVo) {
        return vehicleBookRecordBiz.getBookRecord(vehicleBookRecordQueryVo);
    }

    @GetMapping(value = "/app/unauth/getBookRecordInfo")
    @ApiOperation(value = "获取预定记录信息")
    public RestResponse<PageDataVO> getBookRecordInfo(VehicleBookRecordQueryVo vehicleBookRecordQueryVo) {
        return vehicleBookRecordBiz.getBookRecordInfo(vehicleBookRecordQueryVo);
    }


    @RequestMapping(value = "/app/unauth/getVehicleWarningMsg", method = RequestMethod.GET)
    @ApiOperation(value = "获取排车车辆警告信息")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<Map<String, Object>> getVehicleWarningMsg(VehiclePlanDto vehiclePlanDto) {
        //获取警告信息
        List<VehicleWarningMsgQueryVo> vehicleWarningMsgs = vehicleWarningMsgBiz.getAllByParam(vehiclePlanDto);
        //获取列表
        Map<String, Object> map = Maps.newHashMap();
        map.put("vehicleWarningMsgs",vehicleWarningMsgs);
        return ObjectRestResponse.succ(map);
    }

    @RequestMapping(value = "/app/unauth/getVehicleTotalMsg", method = RequestMethod.GET)
    @ApiOperation(value = "获取排车车辆统计信息")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<Map<String, Object>> getVehicleTotalMsg(VehiclePlanDto vehiclePlanDto) {
        //获取统计信息
        List<VehicleCountVo> vehicleCountVos = baseBiz.countVehicleByParam(vehiclePlanDto);
        //获取列表
        Map<String, Object> map = Maps.newHashMap();
        map.put("vehicleCountVos",vehicleCountVos);
        return ObjectRestResponse.succ(map);
    }

    /**
     * 保存
     *
     * @param vehicle
     * @return
     */
    @PostMapping("/add/seva")
    public ObjectRestResponse seva(Vehicle vehicle) {
        return baseBiz.save(vehicle);
    }

    /**
     * 查找
     * @param vehicleVo
     * @param page
     * @param limit
     * @return
     */
    @PostMapping("/add/findListByVehicle/{page}/{limit}")
    public ObjectRestResponse findListByVehicle(
            @RequestBody VehicleVo vehicleVo
            , @PathVariable("page") Integer page
            , @PathVariable("limit") Integer limit) {
        return  baseBiz.findListByVehicle(vehicleVo,page,limit);
    }

    /**
     * 查询一条
     * @param id
     * @return
     */
   @GetMapping("/add/getOneById/{id}")
    public ObjectRestResponse getOneById(@PathVariable("id")Integer id){
     return   baseBiz.getOneById(id);
   }

    /**
     * 删除车辆信息
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/del/{id}", method = RequestMethod.DELETE)
    public RestResponse retVehicle(@PathVariable String id) throws Exception {

        return baseBiz.delVehicleById(id);
    }

}
