package com.xxfc.platform.vehicle.rest;

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.admin.feign.rest.UserRestInterface;
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.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xxfc.platform.vehicle.biz.*;
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.ResCode.ResCode;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.entity.BranchCompany;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleBookInfo;
import com.xxfc.platform.vehicle.jobhandler.VehicleJobHandler;
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.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.List;
import java.util.Map;
import java.util.stream.Collectors;

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

    @Autowired
    private VehicleBookRecordBiz vehicleBookRecordBiz;

    @Autowired
    VehicleBiz vehicleBiz;

    @Autowired
    UserFeign userFeign;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Autowired
    private VehiclePlatCataBiz vehiclePlatCataBiz;

    @Autowired
    private VehicleWarningMsgBiz vehicleWarningMsgBiz;

    @Autowired
    private VehicleJobHandler vehicleJobHandler;

    @Autowired
    private VehicleBookHourInfoBiz vehicleBookHourInfoBiz;

    @Autowired
    BranchCompanyBiz branchCompanyBiz;

    public UserFeign getUserFeign() {
        return userFeign;
    }
    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();
        bookVehicleVo.setStatus(VehicleBookRecordStatus.APPROVE.getCode());
        bookVehicleVo.setNotCheckTimeLegal(Boolean.FALSE);
        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();
        bookVehicleVo.setStatus(VehicleBookRecordStatus.APPLY.getCode());
        bookVehicleVo.setNotCheckTimeLegal(Boolean.FALSE);
        baseBiz.applyVehicle(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, "", Boolean.FALSE);
    }

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

//    /**
//     * 车辆归还
//     * @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
     * @return
     */
    @RequestMapping(value = "/unbook/4employee", method = RequestMethod.DELETE)
    @ApiOperation(value = "取消预定车辆")
    public RestResponse<Integer> unbookVehicle(@RequestBody  BookVehicleVO bookVehicleVo) throws Exception {
        Integer operatorId = Integer.parseInt(BaseContextHandler.getUserID());
        String userName = BaseContextHandler.getName();
        return baseBiz.unbookVehicle4Employee(operatorId, bookVehicleVo.getVehicleBookRecordId(), userName, bookVehicleVo.getRejectRemark(), Boolean.FALSE);
    }

    @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);
    }

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

    @RequestMapping(value = "/app/unauth/getVehiclePlanList", method = RequestMethod.GET)
    @ApiOperation(value = "获取排车信息")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<Map<String, Object>> getVehiclePlanList(VehiclePlanDto vehiclePlanDto) {
        UserDTO userDTO = getAdminUserInfo();
        if(userDTO == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.RSTOKEN_EXPIRED_CODE, "token失效");
        }
        List<Integer> companyList =  Lists.newArrayList();
        List<BranchCompany> branchCompany = branchCompanyBiz.getListByUser(userDTO);
        companyList = branchCompany.stream().map(BranchCompany::getId).collect(Collectors.toList());
        if(vehiclePlanDto.getParkBranchCompanyId() != null) {
            if(companyList.size() > 0) {
                if(companyList.contains(vehiclePlanDto.getParkBranchCompanyId())) {
                    companyList.clear();
                    companyList.add(vehiclePlanDto.getParkBranchCompanyId());
                } else {
                    return ObjectRestResponse.succ();
                }
            }
        }
        if(vehiclePlanDto.getSubordinateBranch() != null) {
            if(companyList.size() > 0) {
                if(companyList.contains(vehiclePlanDto.getSubordinateBranch())) {
                    companyList.clear();
                    companyList.add(vehiclePlanDto.getSubordinateBranch());
                } else {
                    return ObjectRestResponse.succ();
                }
            }
        }
        vehiclePlanDto.setCompanyIds(companyList);
        //获取列表
        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);
    }

    @GetMapping("/app/unauth/data/{month}")
    @IgnoreClientToken
    @IgnoreUserToken
    public  RestResponse dataCo(@PathVariable(value = "month") String month) throws Exception {
        vehicleJobHandler.execute(month);
        return RestResponse.suc();
    }

    @GetMapping("/app/unauth/checkHourInfo")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse checkHourInfo() {
        return vehicleBookRecordBiz.checkDateInvalide();
    }

    @GetMapping("/app/unauth/checkBookHourInfo")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse checkBookHourInfo() {
        return vehicleBookHourInfoBiz.checkBookHourInfo();
    }
}
