package com.yida.data.device.studentCard.controller;

import cc.mrbird.febs.common.redis.service.RedisService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yida.data.common.core.common.ModuleName;
import com.yida.data.common.core.common.ResultBean;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.card.EduStudentCard;
import com.yida.data.common.core.entity.card.EduStudentCardDisturbTime;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.enums.DeptTypeEnum;
import com.yida.data.common.core.entity.system.enums.OperationLogTypeEnum;
import com.yida.data.common.core.utils.Asserts;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.common.core.utils.FileUtil;
import com.yida.data.common.core.vo.ImportPercentVO;
import com.yida.data.device.dto.studentCard.CardPageDTO;
import com.yida.data.device.dto.studentCard.CardWithAddressDTO;
import com.yida.data.device.dto.studentCard.DisturbStatusDTO;
import com.yida.data.device.studentCard.service.EduStudentCardDisturbTimeService;
import com.yida.data.device.studentCard.service.EduStudentCardService;
import com.yida.data.device.vo.OnlineCountVO;
import com.yida.data.device.vo.studentCard.CardInfoVO;
import com.yida.data.device.vo.studentCard.CardPageVO;
import com.yida.data.device.vo.studentCard.CardWithAddressVO;
import com.yida.data.device.vo.studentCard.ListStudentCardVO;
import com.yida.data.device.vo.studentCard.LocationVO;
import com.yida.data.device.vo.studentCard.TrackVO;
import com.yida.data.log.annotation.OperationLog;
import com.yida.data.system.feign.RemoteDeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;


/**
 * 电子学生证-设备管理 Controller
 *
 * @author ccl
 * @date 2021-08-04 14:44:39
 */
@Api(tags = "学生证-学生证")
@Slf4j
@Validated
@RestController
@RequestMapping("/studentCard/card")
@RequiredArgsConstructor
public class EduStudentCardController {

    private final EduStudentCardService eduStudentCardService;
    private final EduStudentCardDisturbTimeService eduStudentCardDisturbTimeService;
    private final RedisService redisService;
    private final RemoteDeptService remoteDeptService;

    @ApiOperation("分页查询电子学生证")
    @GetMapping("/listCardPage")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "分页查询电子学生证")
    public ResultBean<IPage<CardPageVO>> listCardPage(CardPageDTO dto) {
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        if (dto.getSchoolId() == null &&
            !DeptTypeEnum.COMPANY_TYPE.getValue().equals(Objects.requireNonNull(currentUser).getDeptType())) {
            dto.setSchoolId(currentUser.getDeptId());
        }
        return ResultBean.buildSuccess(eduStudentCardService.listCardPage(dto));
    }

    @ApiOperation("更新学生证")
    @PostMapping("/updateCard")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "更新学生证", type = OperationLogTypeEnum.UPDATE)
    public ResultBean updateCard(@RequestBody EduStudentCard card) {
        eduStudentCardService.updateCard(card);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("导出电子学生证数据")
    @PostMapping("/exportCard")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "导出电子学生证数据")
    public void exportCard(CardPageDTO dto, HttpServletResponse response) {
        eduStudentCardService.exportCard(dto, response);
    }

    @ApiOperation("查询电子学生证详情数据")
    @GetMapping("/getInfo")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "查询电子学生证详情数据")
    public ResultBean<CardInfoVO> getInfo(@ApiParam("设备id") Long id) {
        return ResultBean.buildSuccess(eduStudentCardService.getInfo(id));
    }

    @ApiOperation("查询电子学生证(带定位信息)")
    @GetMapping("/listCardWithAddress")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "查询电子学生证(带定位信息)")
    public ResultBean<List<CardWithAddressVO>> listCardWithAddress(@Valid CardWithAddressDTO dto) {
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        if (DeptTypeEnum.SCHOOL_TYPE.getValue().equals(Objects.requireNonNull(currentUser).getDeptType())) {
            dto.setSchoolId(currentUser.getDeptId());
        }
        return ResultBean.buildSuccess(eduStudentCardService.listCardWithAddress(dto));
    }

    @ApiOperation("刷入缓存中的位置信息")
    @PostMapping("/flushCacheLocaltion")
    public ResultBean flushCacheLocation() {
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        if (DeptTypeEnum.DEPARTMENT_TYPE.getValue().equals(currentUser.getDeptType())) {
            eduStudentCardService.flushCacheLocation(currentUser.getDeptId());
        }
        return ResultBean.buildSuccess();
    }

    @ApiOperation("导入学生信息")
    @PostMapping("/importCard")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "导入学生信息", type =
        OperationLogTypeEnum.INSERT)
    public ResultBean importCard(@RequestParam("file") MultipartFile file) {
        ImportPercentVO vo = (ImportPercentVO) redisService.hget(CachePrefixConstant.STUDENT_CARD_IMPORT,
            FebsUtil.getCurrentUser().getUserId().toString());
        Asserts.isTrue(vo == null || vo.getFinish() == 1, "有导入任务正在进行中，请稍后重试");
        eduStudentCardService.importCard(FileUtil.uploadMultipartFile(file),
            FebsUtil.getCurrentUser().getUserId().toString());
        return ResultBean.buildSuccess();
    }

    @ApiOperation("下载导入模板")
    @GetMapping("/downloadTemplate")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "导入学生信息")
    public void downloadTemplate(HttpServletResponse response) {
        eduStudentCardService.downloadTemplate(response);
    }

    @ApiOperation("查询导入学生的进度信息")
    @GetMapping("/getImportPercent")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "导入学生信息", type =
        OperationLogTypeEnum.INSERT)
    public ResultBean getImportPercent() {
        return ResultBean.buildSuccess(redisService
            .hget(CachePrefixConstant.STUDENT_CARD_IMPORT, FebsUtil.getCurrentUser().getUserId().toString()));
    }

    @ApiOperation("家长对应学生列表")
    @GetMapping("/listStudentCard")
    public ResultBean<List<ListStudentCardVO>> listStudentCard(@ApiParam("家长id") @RequestParam Long parentId) {
        return ResultBean.buildSuccess(eduStudentCardService.listStudentCard(parentId));
    }

    @ApiOperation("获取定位")
    @GetMapping("/getLocation")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "获取定位")
    public ResultBean<LocationVO> getLocation(@ApiParam("设备imei") @RequestParam String imei) {
        return ResultBean.buildSuccess(eduStudentCardService.getLocation(imei));
    }

    @ApiOperation("刷新定位")
    @GetMapping("/refreshLocation")
    public ResultBean refreshLocation(String imei) {
        eduStudentCardService.refreshLocation(imei);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("查询免打扰时间端")
    @GetMapping("/listDisturb")
    public ResultBean<List<EduStudentCardDisturbTime>> listDisturb(Long studentId) {
        return ResultBean.buildSuccess(eduStudentCardDisturbTimeService.listDisturbTime(studentId));
    }

    @ApiOperation("批量免打扰")
    @PostMapping("/setDisturbStatus")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "批量免打扰", type = OperationLogTypeEnum.UPDATE)
    public ResultBean setDisturbStatus(@RequestBody DisturbStatusDTO disturbStatusDTO) {
        eduStudentCardService.setDisturbStatus(disturbStatusDTO);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("获取轨迹")
    @GetMapping("/getTrack")
    public ResultBean<List<TrackVO>> getTrack(@ApiParam("imei") @RequestParam(required = false) String imei,
        @ApiParam("学生cardId") @RequestParam(required = false) Long cardId,
        @ApiParam("时间格式为yyyy-MM-dd HH:mm:ss") @RequestParam String startTime,
        @ApiParam("时间格式为yyyy-MM-dd HH:mm:ss") @RequestParam String endTime) {
        return ResultBean.buildSuccess(eduStudentCardService.listTrack(imei, cardId, startTime, endTime));
    }

    @ApiOperation("根据imei号或名称搜索学生")
    @GetMapping("/getStudentCardByImeiOrName")
    public ResultBean<List<CardPageVO>> listStudentCardByImeiOrName(
        @ApiParam("学生id") @RequestParam(required = false) Long schoolId,
        @ApiParam("关键字，imei号或学生名称") String keyword) {
        if (schoolId == null) {
            CurrentUser currentUser = FebsUtil.getCurrentUser();
            if (DeptTypeEnum.SCHOOL_TYPE.getValue().equals(Objects.requireNonNull(currentUser).getDeptType())) {
                schoolId = currentUser.getDeptId();
            }
        }
        return ResultBean.buildSuccess(eduStudentCardService.listStudentCardByImeiOrName(schoolId, keyword));
    }

    @ApiOperation("下发监听指令")
    @GetMapping("/issueMonitor")
    @OperationLog(module = ModuleName.ELECTRONIC_STUDENT_CARD, methods = "下发监听指令", type = OperationLogTypeEnum.SELECT)
    public ResultBean issueMonitor(@ApiParam("接收监听手机号") String mobile,
        @ApiParam("学生证imei号") String imei) {
        eduStudentCardService.issueMonitor(mobile, imei);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("查询电子学生证在线离线数量")
    @GetMapping("/getOnlineDistrib")
    public ResultBean<OnlineCountVO> getOnlineDistrib() {
        List<Long> schoolIds = remoteDeptService.getSchoolByArea(null, null).getData().stream().map(Dept::getDeptId).collect(
            Collectors.toList());
        return ResultBean.buildSuccess(eduStudentCardService.getCardDistrib(schoolIds));
    }
}
