package io.hmit.modules.appointment.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import io.hmit.annotation.Login;
import io.hmit.annotation.LoginUser;
import io.hmit.common.constant.Constant;
import io.hmit.common.page.PageData;
import io.hmit.common.utils.ConvertUtils;
import io.hmit.common.utils.DateUtils;
import io.hmit.common.utils.HttpRequestUtil;
import io.hmit.common.utils.MD5;
import io.hmit.common.utils.Result;
import io.hmit.common.utils.sm.SMUtil;
import io.hmit.common.validator.AssertUtils;
import io.hmit.common.validator.ValidatorUtils;
import io.hmit.common.validator.group.AddGroup;
import io.hmit.common.validator.group.DefaultGroup;
import io.hmit.common.validator.group.UpdateGroup;
import io.hmit.entity.UserEntity;
import io.hmit.modules.appointment.dto.*;
import io.hmit.modules.appointment.entity.AppointmentOrderEntity;
import io.hmit.modules.appointment.service.AppointmentOrderService;
import io.hmit.modules.appointment.service.AppointmentOrderServiceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 预约订单表
 *
 * @author zsh 408538940@qq.com
 * @since 1.0.0 2021-02-13
 */
@RestController
@RequestMapping("app/appointmentorder")
@Api(tags="预约订单表")
public class AppointmentOrderController {
    @Autowired
    private AppointmentOrderService appointmentOrderService;

    @Autowired
    private AppointmentOrderServiceService appointmentOrderServiceService;

    @Login
    @GetMapping("page")
    @ApiOperation("分页")
    @ApiImplicitParams({
        @ApiImplicitParam(name = Constant.PAGE, value = "当前页码，从1开始", paramType = "query", required = true, dataType="int") ,
        @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") ,
        @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") ,
        @ApiImplicitParam(name = Constant.ORDER, value = "排序方式，可选值(asc、desc)", paramType = "query", dataType="String")
    })
    public Result<PageData<AppointmentOrderDTO>> page(@ApiIgnore @RequestParam Map<String, Object> params,
                                                      @ApiIgnore @LoginUser UserEntity userEntity){
        // 对数据进行加密
        params.put("appointmentIdCard", SMUtil.SM4Encrypt(userEntity.getIdCardNo()));
        params.put("appointmentPhone",  SMUtil.SM4Encrypt(userEntity.getMobile()));
        PageData<AppointmentOrderDTO> page = appointmentOrderService.page(params);
         page.getList().forEach(l->{
             //获取当前时间段事项预约总人数
            Integer rCount = appointmentOrderService.reservationAccount(l.getServiceId(),l.getAppointmentTime());
            l.setRCount(rCount);
             //判断已取号或者消除过号
             if(null!=l.getStatus() && Constant.ReservationStatus.GET_NUM.getValue()<=l.getStatus()){
                YynumberDTO yynumberDTO = appointmentOrderService.findByYuNumber(l.getAppointmentNum());
                l.setYynumberDTO(yynumberDTO);
             }
         });

        return new Result<PageData<AppointmentOrderDTO>>().ok(page);
    }

    @Login
    @GetMapping("getDetail")
    @ApiOperation("信息,预约详情接口")
    public Result<AppointmentOrderDTO> get(@RequestParam("id") Long id){
        AppointmentOrderDTO data = appointmentOrderService.get(id);
        if(null!=data.getStatus() && Constant.ReservationStatus.GET_NUM.getValue()<=data.getStatus() ) {
            data.setYynumberDTO(appointmentOrderService.findByYuNumber(data.getAppointmentNum()));
        }
        // 返回信息解密
        data.setAppointmentPhone(SMUtil.SM4Decrypt(data.getAppointmentPhone()));
        data.setAppointmentIdCard(SMUtil.SM4Decrypt(data.getAppointmentIdCard()));
        return new Result<AppointmentOrderDTO>().ok(data);
    }

    @GetMapping("orderInfo")
    @ApiOperation("根据手机号或身份证号获取信息(给杭州接口）")
    public Result<List<ReservationOrderInfoDTO>> queryInfo(String identity){
//        PageData<AppointmentOrderDTO> pageData = appointmentOrderService.getAppointmentInfoPage(params, identity);
        List<ReservationOrderInfoDTO> data = appointmentOrderService.getAppointmentInfoPage(identity);

        if(data == null ){
            return new Result<List<ReservationOrderInfoDTO>>().error(1,"没有查询到此用户的预约信息");
        }
        if(data.size()==0){
            return new Result<List<ReservationOrderInfoDTO>>().error(2,"当前时段没有此用户的预约信息");
        }
        return new Result<List<ReservationOrderInfoDTO>>().ok(data);
    }

    @Login
    @PostMapping
    @ApiOperation("预约保存")
    public Result<ReservationSuccessDTO> save(@RequestBody ReservationDTO dto,
                                              @ApiIgnore @LoginUser UserEntity userEntity){
        //校验数据
        ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);

        AppointmentOrderDTO appointmentOrderDTO =  new AppointmentOrderDTO().assembleAppointmentOrderDTO(dto,userEntity);
        appointmentOrderDTO.setAppointmentPhone(SMUtil.SM4Encrypt(appointmentOrderDTO.getAppointmentPhone()));
        appointmentOrderDTO.setAppointmentIdCard(SMUtil.SM4Encrypt(appointmentOrderDTO.getAppointmentIdCard()));
        appointmentOrderService.save(appointmentOrderDTO);

        ReservationSuccessDTO successData = ConvertUtils.sourceToTarget(appointmentOrderDTO,ReservationSuccessDTO.class);

        AppointmentOrderServiceDTO orderServiceDTO =  new AppointmentOrderServiceDTO().assembleAppointmentOrderServiceDTO(appointmentOrderDTO,userEntity);

        appointmentOrderServiceService.save(orderServiceDTO);

        return new Result().ok(successData);
    }

    @PostMapping("/updateReservationInfo")
    @ApiOperation("更新预约人取号信息(给杭州接口）")
    public Result updateReservationInfo(@RequestBody UpdateInfoDTO dto){

        AppointmentOrderEntity appointmentOrderEntity = appointmentOrderService.selectById(dto.getOrderId());

        if(appointmentOrderEntity == null){
            return new Result().error(1,"当前预约id: "+dto.getOrderId()+" 的预约信息不存在！");
        }
        appointmentOrderEntity.setAppointmentNum(dto.getAppointmentNum());
        appointmentOrderEntity.setWaitNum(dto.getWaitNum());
        appointmentOrderEntity.setServiceWindow(String.join(",", dto.getListWin()));
        appointmentOrderEntity.setTicketDate(dto.getTicketDate());
        //取号机生成取号码则设置取号预约状态为：完成
        appointmentOrderEntity.setStatus(Constant.ReservationStatus.GET_NUM.getValue());
        appointmentOrderEntity.setStatusName(Constant.ReservationStatus.GET_NUM.getMsg());

        appointmentOrderService.updateById(appointmentOrderEntity);

        return new Result();
    }

    @Login
    @GetMapping("/cancel")
    @ApiOperation("预约取消")
    public Result cancelReservation(@RequestParam("id") Long id,
                                    @ApiIgnore @LoginUser UserEntity user){

        AppointmentOrderDTO data = appointmentOrderService.get(id);
        data.setStatus(Constant.ReservationStatus.CANCEL.getValue());
        data.setStatusName(Constant.ReservationStatus.CANCEL.getMsg());
        data.setUpdateDate(new Date());
        data.setUpdater(user.getId());
        appointmentOrderService.update(data);

        return new Result();
    }

    @Login
    @GetMapping("/deleteOverNum")
    @ApiOperation("消除过号")
    public Result deleteOverNum(@RequestParam("id") Long id,
                                @ApiIgnore @LoginUser UserEntity user){

        AppointmentOrderDTO data = appointmentOrderService.get(id);
        data.setStatus(Constant.ReservationStatus.ELIMINATE_INVALID_NUM.getValue());
        data.setStatusName(Constant.ReservationStatus.ELIMINATE_INVALID_NUM.getMsg());
        data.setUpdateDate(new Date());
        data.setUpdater(user.getId());
        appointmentOrderService.update(data);

        return new Result();
    }

    @GetMapping(value = "/signin")
    @ApiOperation("签到")
    public Result signin(@RequestParam("id") Long appointmentOrderId){

        //根据appointmentOrderId获取到订单实体
        AppointmentOrderDTO appointmentOrderDTO = appointmentOrderService.get(appointmentOrderId);

            String appointmentIdCard = SMUtil.SM4Decrypt(appointmentOrderDTO.getAppointmentIdCard());
            String appointmentPhone = SMUtil.SM4Decrypt(appointmentOrderDTO.getAppointmentPhone());
            String serviceId = appointmentOrderDTO.getServiceId().toString();
            String appointmentPerson = appointmentOrderDTO.getAppointmentPerson();
            String nowtime = String.valueOf(System.currentTimeMillis()/1000);
            String sign = "hjfhsdjfueytRwYSdsa%hdf^jdshfh*KGh$e"+serviceId+nowtime;
            //判断签到时间是否在预约时间前

            //调用取号机取号接口，获取取号信息，并更新预约号。
//         http://IP:8223/smartqueue/yynumber?sQueueInfoID=24&time=1613389800&sign=ee2c3fc1bdabf439f00aa90af6a0a68f&sTel=13988888888&sName=王小二&sCardID=333111123456
            String url = "http://192.168.1.97:8223/smartqueue/yynumber?" +
                    "sQueueInfoID=" +serviceId+
                    "&time="+ nowtime +
                    "&sign="+ MD5.md5(sign)+
                    "&sTel="+ appointmentPhone+
                    "&sName="+appointmentPerson+
                    "&sCardID="+appointmentIdCard;
            String s = HttpRequestUtil.sendGetAndRetrieveContent(url);
//            String s = "{\"nStatus\":0,\"sMsg\":\"成功\",\"nWait\":9,\"sCallTime\":\"\",\"sRegTime\":\"2018-12-21 13:49:21\",\"sQueueName\":\"交通违法处理\",\"listWin\":[\"B03\",\"B04\",\"B05\",\"B06\"]}\n";

            YynumberDTO yynumberDTO = JSONObject.parseObject(s,YynumberDTO.class);
        //根据接口返回的结果更新预约单号
            if(0 == yynumberDTO.getNStatus()){
                appointmentOrderDTO.setAppointmentNum(yynumberDTO.getSPaperNumber());
                appointmentOrderDTO.setTicketDate(yynumberDTO.getSRegTime());
                appointmentOrderDTO.setWaitNum(yynumberDTO.getNWait());
                appointmentOrderDTO.setServiceWindow(String.join(",",yynumberDTO.getListWin()));
                appointmentOrderDTO.setStatus(Constant.ReservationStatus.GET_NUM.getValue());
                appointmentOrderDTO.setStatusName(Constant.ReservationStatus.GET_NUM.getMsg());
                appointmentOrderDTO.setUpdateDate(new Date());
                appointmentOrderService.update(appointmentOrderDTO);

                return new Result();
            }else{
                return new Result().error(yynumberDTO.getSMsg());
            }
    }


    @GetMapping(value = "/serviceWaitingNum/{serviceId}")
    @ApiOperation("获取当前事项的预约排队人数")
    public Result serviceWaitingNum (@PathVariable(value = "serviceId") Long serviceId){


        Integer serviceWaitingNum = appointmentOrderService.serviceWaitingNum(serviceId);

        return new Result().ok(serviceWaitingNum);


    }

    @PutMapping
    @ApiOperation("修改")
    public Result update(@RequestBody AppointmentOrderDTO dto){
        //校验数据
        ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);

        dto.setAppointmentPhone(SMUtil.SM4Encrypt(dto.getAppointmentPhone()));
        dto.setAppointmentIdCard(SMUtil.SM4Encrypt(dto.getAppointmentIdCard()));
        appointmentOrderService.update(dto);

        return new Result();
    }

    @DeleteMapping
    @ApiOperation("删除")
    public Result delete(@RequestBody Long[] ids){
        //校验数据
        AssertUtils.isArrayEmpty(ids, "id");

        appointmentOrderService.delete(ids);

        return new Result();
    }


}
