package com.yuchen.saas.park.service.controller.pldoor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.yuchen.saas.park.api.dto.park.IoTEvent;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorInoutRecode;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPoint;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.vo.door.*;
import com.yuchen.saas.park.api.vo.door.PlDoorInoutRecodeVO;
import com.yuchen.saas.park.api.vo.door.PlDoorPointInOutVO;
import com.yuchen.saas.park.api.vo.pldoor.*;
import com.yuchen.saas.park.service.service.pldoor.PlDoorInoutRecodeService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import com.yuchen.saas.park.service.util.PageConverterUtils;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 * 门禁出入记录 前端控制器
 * </p>
 *
 * @author miaoqs
 * @since 2024-04-12
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/plDoorInoutRecode")
public class PlDoorInoutRecodeController {

    private final PlDoorInoutRecodeService plDoorInoutRecodeService;

    private final PropertyHousesService propertyHousesService;

    private final PlDoorPointService plDoorPointService;

    @PostMapping("/saveOrUpdate")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "门禁出入记录 新增或修改", notes = "门禁出入记录 新增或修改")
    public R saveOrUpdate(@Valid @RequestBody PlDoorInoutRecode plDoorInoutRecode) {
        if(Func.isEmpty(plDoorInoutRecode)) {
            return R.error("门禁出入记录不能为空");
        }
        return R.data(plDoorInoutRecodeService.saveOrUpdate(plDoorInoutRecode));
    }

    @PostMapping("/saveOpenDoorUpload")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "保存门禁出入记录-刷脸/二维码", notes = "保存门禁出入记录-刷脸/二维码")
    public R saveOpenDoorUpload(@Valid @RequestBody IoTEvent ioTEvent) {
        if(Func.isEmpty(ioTEvent)) {
            return R.error("门禁出入记录不能为空");
        }
        plDoorInoutRecodeService.saveOpenDoorUpload(ioTEvent);
        return R.success();
    }

    /**
     * 获取详情
     * @param id
     * @return
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "门禁出入记录 详情", notes = "门禁出入记录详情")
    public R detail(Long id) {
        return R.data(plDoorInoutRecodeService.getById(id));
    }

    /**
     * 根据主表id删除门禁出入记录
     * @param plDoorInoutRecode
     * @return
     */
    @PostMapping("/removeId")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "根据主表id 门禁出入记录 删除", notes = "根据主表id 门禁出入记录 删除")
    public R removeId(@RequestBody PlDoorInoutRecode plDoorInoutRecode) {
        plDoorInoutRecodeService.removeById(plDoorInoutRecode.getId());
        return R.success();
    }

    /**
     * 分页 门禁出入记录
     */
    @PostMapping("/pageByparam")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "分页 门禁出入记录", notes = "分页 门禁出入记录")
    public R<NestPage<PlDoorInoutRecodeVO>> pageByparam(@RequestBody PlDoorInoutRecode plDoorInoutRecode,@RequestBody Query query) {
        IPage<PlDoorInoutRecode> pages = plDoorInoutRecodeService.page(Condition.getPage(query),
                new LambdaQueryWrapper<PlDoorInoutRecode>()
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getOpenDoorType()),PlDoorInoutRecode::getOpenDoorType,
                                plDoorInoutRecode.getOpenDoorType())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getParkId()), PlDoorInoutRecode::getParkId,
                                plDoorInoutRecode.getParkId())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getBuildingId()), PlDoorInoutRecode::getBuildingId,
                                plDoorInoutRecode.getBuildingId())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getElementId()), PlDoorInoutRecode::getElementId,
                                plDoorInoutRecode.getElementId())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getFloorId()), PlDoorInoutRecode::getFloorId,
                                plDoorInoutRecode.getFloorId())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getRoomId()), PlDoorInoutRecode::getRoomId,
                                plDoorInoutRecode.getRoomId())
                        .eq(Func.isNotEmpty(plDoorInoutRecode.getDoorPointId()), PlDoorInoutRecode::getDoorPointId,
                                plDoorInoutRecode.getDoorPointId())
                        .gt(Func.isNotEmpty(plDoorInoutRecode.getStartTime()), PlDoorInoutRecode::getInoutTime,
                                plDoorInoutRecode.getStartTime())
                        .lt(Func.isNotEmpty(plDoorInoutRecode.getEndTime()), PlDoorInoutRecode::getInoutTime,
                                plDoorInoutRecode.getEndTime())
                        .like(Func.isNotEmpty(plDoorInoutRecode.getUserName()), PlDoorInoutRecode::getUserName,
                                plDoorInoutRecode.getUserName())
                        .orderByDesc(PlDoorInoutRecode::getCreateTime));

        // 返回分页数据
        IPage<PlDoorInoutRecodeVO> plDoorInoutRecodeVOIPage = PageConverterUtils.pageVoCovert(pages, PlDoorInoutRecodeVO.class);
        if(Func.isNotEmpty(plDoorInoutRecodeVOIPage) && Func.isNotEmpty(plDoorInoutRecodeVOIPage.getRecords())){
            plDoorInoutRecodeVOIPage.getRecords().forEach(record -> {
                PropertyHouses houses = propertyHousesService.getById(record.getRoomId());
                record.setRoomName(null == houses?"":houses.getHouseName());
                PlDoorPoint point = plDoorPointService.getById(record.getDoorPointId());
                record.setDoorName(null == point?"":point.getDoorName());
            });

        }

        return  R.data(NestPage.of(plDoorInoutRecodeVOIPage));
    }

    /**
     * 获取门禁点详情数据
     * @param pointId
     * @return
     */
    @GetMapping("/getPointInfoByPointId")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "获取门禁点详情数据 UE", notes = "获取门禁点详情数据 UE")
    public R<PlDoorPointInOutVO> getPointInfoByPointId(Long pointId) {
        return R.data(plDoorInoutRecodeService.getPointInOutByPointId(pointId));
    }

    /**
     * 统计今日通行次数 根据parkId
     * @param parkId
     * @return
     */
    @GetMapping("/todayPassCount")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "统计今日通行次数 根据parkId", notes = "统计今日通行次数 根据parkId")
    public R<PlDoorPassedTodayCountVO> todayPassCount(Long parkId) {
        return R.data(plDoorInoutRecodeService.todayPassCount(parkId));
    }

    /**
     * 智慧门禁-通行时段统计 根据parkId 7天
     * @param parkId
     * @return
     */
    @GetMapping("/passedTimeFrameCount")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "智慧门禁-通行时段统计 根据parkId 7天", notes = "通行时段统计 根据parkId 7天")
    public R<List<PlDoorPassedTimeFrameCountVO>> passedTimeFrameCount(Long parkId, String userType) {
        return R.data(plDoorInoutRecodeService.passedTimeFrameCount(parkId, userType));
    }

    /**
     * 智慧门禁-按通行方式统计 根据parkId
     * @param parkId
     * @return
     */
    @GetMapping("/passedTypeCount")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "智慧门禁-按通行方式统计 根据parkId", notes = "按通行方式统计 根据parkId")
    public R<PlDoorPassedTypeCountVO> passedTypeCount(Long parkId, String userType) {
        return R.data(plDoorInoutRecodeService.passedTypeCount(parkId, userType));
    }

    /**
     * 智慧门禁-按人员类型统计 根据parkId
     * @param parkId
     * @return
     */
    @GetMapping("/userTypeCount")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "智慧门禁-按人员类型统计 根据parkId", notes = "按人员类型统计 根据parkId")
    public R<List<PlDoorPassedUserTypeVO>> userTypeCount(Long parkId) {
        return R.data(plDoorInoutRecodeService.userTypeCount(parkId));
    }

    /**
     * 智慧门禁-访客日期类型统计
     * @param parkId
     * @return
     */
    @GetMapping("/visitorDateTypeCount")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "智慧门禁-访客日期类型统计 根据parkId", notes = "访客日期类型统计 根据parkId")
    public R<PlDoorVistorDateTypeCountVO> visitorDateTypeCount(Long parkId) {
        return R.data(plDoorInoutRecodeService.visitorDateTypeCount(parkId));
    }

    /**
     * 智慧门禁-访客人数按天统计-本月
     * @param parkId
     * @return
     */
    @GetMapping("/getDaysOfCurrentMonth")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "智慧门禁-访客人数按天统计-本月-访客 根据parkId", notes = "访客人数按天统计-本月 根据parkId")
    public R<List<PlDoorPassedTimeFrameCountVO>> getDaysOfCurrentMonth(Long parkId) {
        return R.data(plDoorInoutRecodeService.getDaysOfCurrentMonth(parkId));
    }

    /**
     * 智慧门禁-访客人数按月统计-当年
     * @param parkId
     * @return
     */
    @GetMapping("/getMonthsOfCurrentYear")
    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "智慧门禁-访客人数按月统计-当年-访客 根据parkId", notes = "访客人数按月统计-当年 根据parkId")
    public R<List<PlDoorPassedTimeFrameCountVO>> getMonthsOfCurrentYear(Long parkId) {
        return R.data(plDoorInoutRecodeService.getMonthsOfCurrentYear(parkId));
    }

    /**
     * 智慧门禁-到访时段统计 根据parkId
     * @param parkId
     * @return
     */
    @GetMapping("/getHourOfDay")
    @ApiOperationSupport(order = 13)
    @ApiOperation(value = "智慧门禁-到访时段统计-访客 根据parkId", notes = "到访时段统计-访客 根据parkId")
    public R<List<PlDoorPassedTimeFrameCountVO>> getHourOfDay(Long parkId) {
        return R.data(plDoorInoutRecodeService.getHourOfDay(parkId));
    }

    /**
     * 智慧访客-统计分析/人数预约 根据parkId
     * @param parkId
     * @param type 1：人数 2：预约
     * @return
     */
    @GetMapping("/vistorCountByType")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "智慧访客-统计分析/人数预约 根据parkId", notes = "智慧访客-统计分析/人数预约 根据parkId")
    public R<PlVistorByTypeCountVO> vistorCountByType(Long parkId, String type) {
        return R.data(plDoorInoutRecodeService.vistorCountByType(parkId, type));
    }

}
