package com.yida.data.attendance.controller;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yida.data.attendance.dto.DevicePage;
import com.yida.data.attendance.dto.IssuedFaceDTO;
import com.yida.data.attendance.dto.RemoveFaceDTO;
import com.yida.data.attendance.service.EduAttendanceDeviceService;
import com.yida.data.attendance.vo.DeviceNumberVO;
import com.yida.data.attendance.vo.DeviceVO;
import com.yida.data.attendance.vo.OnlineCountVO;
import com.yida.data.common.core.annotation.ControllerLog;
import com.yida.data.common.core.common.ModuleName;
import com.yida.data.common.core.common.ResultBean;
import com.yida.data.common.core.entity.attendance.EduAttendanceDevice;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.enums.OperationLogTypeEnum;
import com.yida.data.common.core.utils.FebsUtil;
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.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
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;

@Api(tags = "考勤-设备", value = "考勤")
@RestController
@RequestMapping("/device")
@RequiredArgsConstructor
public class AttendanceDeviceController {

    private final EduAttendanceDeviceService eduAttendanceDeviceService;
    private final RemoteDeptService remoteDeptService;


    @ApiOperation("考勤设备列表分页查询")
    @GetMapping("/listDevicePage")
    @PreAuthorize("hasAuthority('attendance:device:view')")
    public ResultBean<DevicePage<DeviceVO>> listDevicePage(@ApiParam("学校名称") String schoolName,
        @ApiParam("设备编号或名称") String number,
        @ApiParam("进出类型，0-进门，1-出门") Integer scope,
        @ApiParam("区域类型，0-校门，1-宿舍") Integer type,
        @ApiParam("设备状态，0-在线，1-离线") Integer state,
        @ApiParam("当前页码") @RequestParam(defaultValue = "1") Integer pageNum,
        @ApiParam("页面大小") @RequestParam(defaultValue = "10") Integer pageSize
    ) {
        return ResultBean.buildSuccess(eduAttendanceDeviceService.listDevicePage(new DevicePage(pageNum,
            pageSize), schoolName, number, scope, type, state, FebsUtil.getCurrentUser()));
    }

    /**
     * 考勤设备数量统计
     *
     * @return com.yida.data.common.core.common.ResultBean<com.yida.data.attendance.vo.DeviceNumberVO>
     * @author ZYJ
     * @date 2021/10/8 16:57
     */
    @ApiOperation("考勤设备数量统计")
    @GetMapping("/findDeviceNumber")
    public ResultBean<DeviceNumberVO> findDeviceNumber() throws NoSuchMethodException {
        return eduAttendanceDeviceService.findDeviceNumber();
    }

    @ApiOperation("新增、修改设备")
    @PostMapping("/saveDevice")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "新增、修改考勤设备", type = OperationLogTypeEnum.SAVE)
    @PreAuthorize("hasAuthority('attendance:device:edit')")
    public ResultBean saveDevice(@RequestBody EduAttendanceDevice device) {
        return ResultBean.buildSuccess(eduAttendanceDeviceService.saveDevice(device));
    }

    @ApiOperation("删除考勤设备")
    @PostMapping("/delDevice")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "删除考勤设备", type = OperationLogTypeEnum.DELETE)
    @PreAuthorize("hasAuthority('attendance:device:delete')")
    public ResultBean delDevice(@RequestBody List<Long> ids) {
        eduAttendanceDeviceService.delDevice(ids);
        // 更新缓存
        return ResultBean.buildSuccess();
    }

    @ApiOperation("根据学校和区域查询设备列表")
    @GetMapping("/listDeviceBySchool")
    public ResultBean<List<EduAttendanceDevice>> listDeviceBySchool(
        @ApiParam("学校id") Long schoolId,
        @ApiParam("区域类型,0-进门，1-出门") @RequestParam(required = false) Integer scope,
        @ApiParam("类型,0-校门，1-宿舍") @RequestParam(required = false) Integer type) {
        LambdaQueryWrapper<EduAttendanceDevice> condition = Wrappers.lambdaQuery(new EduAttendanceDevice())
            .eq(EduAttendanceDevice::getSchoolId, schoolId);
        if (scope != null) {
            condition.eq(EduAttendanceDevice::getZoneScope, scope);
        }
        if (type != null) {
            condition.eq(EduAttendanceDevice::getType, type);
        }
        return ResultBean.buildSuccess(eduAttendanceDeviceService.list(condition));
    }

    @ApiOperation("根据id查询设备列表")
    @GetMapping("/listDeviceById")
    ResultBean<List<EduAttendanceDevice>> listDeviceById(@RequestParam("ids") Long[] ids) {
        return ResultBean.buildSuccess(
            ArrayUtil.isNotEmpty(ids) ? eduAttendanceDeviceService.listByIds(Arrays.asList(ids))
                : Collections.EMPTY_LIST);
    }

    @ApiOperation("根据id开门")
    @GetMapping("/openDoor")
    public ResultBean openDoor(@ApiParam("设备id") @RequestParam String eduAttendanceDevice) {
        eduAttendanceDeviceService.openDoor(eduAttendanceDevice);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("根据id设置时间")
    @GetMapping("/setSysTime")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "根据id设置设备时间", type = OperationLogTypeEnum.UPDATE)
    public ResultBean setSysTime(@ApiParam("设备id") @RequestParam String id) {
        eduAttendanceDeviceService.setSysTime(id);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("批量设置时间")
    @PostMapping("/setAllTime")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "批量设置设备时间", type = OperationLogTypeEnum.UPDATE)
    public ResultBean setAllTime(@RequestBody List<String> list) {

        eduAttendanceDeviceService.setAllTime(list);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("批量开门")
    @PostMapping("/openAllDoor")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "批量开门设备", type = OperationLogTypeEnum.UPDATE)
    public ResultBean openAllDoor(@RequestBody List<String> list) {

        eduAttendanceDeviceService.openAllDoor(list);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("下发人脸(下发设备需为同一厂商设备)")
    @PostMapping("/issuedFace")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "下发人脸", type = OperationLogTypeEnum.SELECT)
    public ResultBean issuedFace(@RequestBody IssuedFaceDTO dto) {
        eduAttendanceDeviceService.issuedFace(dto);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("删除设备中的人脸")
    @PostMapping("/removeFace")
    @OperationLog(module = ModuleName.ATTENDANCE, methods = "删除设备中的人脸", type = OperationLogTypeEnum.DELETE)
    public ResultBean removeFace(@RequestBody RemoveFaceDTO dto) {
        eduAttendanceDeviceService.removeFace(dto);
        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(eduAttendanceDeviceService.getOnlineDistrib(schoolIds));
    }
}
