package com.xjrsoft.module.personnel.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.QrCodeUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.config.CommonPropertiesConfig;
import com.xjrsoft.module.organization.entity.Department;
import com.xjrsoft.module.personnel.dto.AddReservationSchoolDto;
import com.xjrsoft.module.personnel.dto.ReservationSchoolPageDto;
import com.xjrsoft.module.personnel.dto.ReservationSchoolVisitorPageDto;
import com.xjrsoft.module.personnel.dto.UpdateReservationSchoolDto;
import com.xjrsoft.module.personnel.entity.ReservationSchool;
import com.xjrsoft.module.personnel.entity.ReservationSchoolPeople;
import com.xjrsoft.module.personnel.service.IReservationSchoolService;
import com.xjrsoft.module.personnel.vo.ReservationSchoolPageVo;
import com.xjrsoft.module.personnel.vo.ReservationSchoolPeopleVo;
import com.xjrsoft.module.personnel.vo.ReservationSchoolVisitorPageVo;
import com.xjrsoft.module.personnel.vo.ReservationSchoolVo;
import com.xjrsoft.module.system.entity.DictionaryDetail;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
import com.xjrsoft.module.workflow.entity.XjrWorkflowOperateRecord;
import com.xjrsoft.module.workflow.service.IXjrWorkflowOperateRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
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 javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @title: 预约进校
* @Author dzx
* @Date: 2024-05-11
* @Version 1.0
*/
@RestController
@RequestMapping("/personnel" + "/reservationSchool")
@Api(value = "/personnel"  + "/reservationSchool",tags = "预约进校代码")
@AllArgsConstructor
public class ReservationSchoolController {


    private final IReservationSchoolService reservationSchoolService;
    private final CommonPropertiesConfig commonPropertiesConfig;
    private final IXjrWorkflowOperateRecordService operateRecordService;

    @GetMapping(value = "/page")
    @ApiOperation(value="预约进校列表(分页)")
    @SaCheckPermission("reservationschool:detail")
    public RT<PageOutput<ReservationSchoolPageVo>> page(@Valid ReservationSchoolPageDto dto){

        LambdaQueryWrapper<ReservationSchool> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                    .orderByDesc(ReservationSchool::getId)
                .eq(ReservationSchool::getCreateUserId,StpUtil.getLoginIdAsLong())
                .select(ReservationSchool.class,x -> VoToColumnUtil.fieldsToColumns(ReservationSchoolPageVo.class).contains(x.getProperty()));

        if(ObjectUtil.isNotNull(dto.getType())) {
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (dto.getType() == 1) {
                queryWrapper.le(ReservationSchool::getStartTime, sdf.format(date))
                        .ge(ReservationSchool::getEndTime, sdf.format(date));
            }
            if (dto.getType() == 2) {
                queryWrapper.and(ext->ext.ge(ReservationSchool::getStartTime, sdf.format(date)).or(eee->eee.le(ReservationSchool::getEndTime, sdf.format(date))));
            }
        }

        IPage<ReservationSchool> page = reservationSchoolService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<ReservationSchoolPageVo> pageOutput = ConventPage.getPageOutput(page, ReservationSchoolPageVo.class);
        for (ReservationSchoolPageVo record : pageOutput.getList()) {
            if(record.getStatus() != null && record.getStatus() == 2){
                MPJLambdaWrapper<XjrWorkflowOperateRecord> queryWrapper2 = new MPJLambdaWrapper<>();
                queryWrapper2
                        .select(XjrWorkflowOperateRecord::getId)
                        .select(XjrWorkflowOperateRecord.class, x -> VoToColumnUtil.fieldsToColumns(XjrWorkflowOperateRecord.class).contains(x.getProperty()))
                        .leftJoin(WorkflowFormRelation.class, WorkflowFormRelation::getProcessId, XjrWorkflowOperateRecord::getProcessId)
                        .eq(WorkflowFormRelation::getFormKeyValue, record.getId())
                        .disableSubLogicDel();
                List<XjrWorkflowOperateRecord> list = operateRecordService.selectJoinList(XjrWorkflowOperateRecord.class, queryWrapper2 );
                for (XjrWorkflowOperateRecord xjrWorkflowOperateRecord : list) {
                    if(xjrWorkflowOperateRecord.getOperateInfo().contains("驳回") && xjrWorkflowOperateRecord.getOperateInfo() != null){
                        String[] split = xjrWorkflowOperateRecord.getOperateInfo().split("，");
                        if(split.length > 0){
                            String msg = split[split.length - 1].replace(" 审批内容：", "");
                            record.setMessage(msg);
                        }
                    }
                }
            }
        }

        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/my-visitor-page")
    @ApiOperation(value="我的访客(分页)")
    @SaCheckPermission("reservationschool:detail")
    public RT<PageOutput<ReservationSchoolVisitorPageVo>> myVisitorPage(@Valid ReservationSchoolVisitorPageDto dto){
        IPage<ReservationSchoolVisitorPageVo> page = reservationSchoolService.selectJoinListPage(ConventPage.getPage(dto),
                ReservationSchoolVisitorPageVo.class
                , MPJWrappers.<ReservationSchool>lambdaJoin()
                        .orderByDesc(ReservationSchoolPeople::getId)
                        .disableSubLogicDel()
                                .select("(SELECT COUNT(*) FROM reservation_school_people WHERE reservation_schoo_id = t.id) as people_count")
                         .eq(ReservationSchool::getRespondentUserId,StpUtil.getLoginIdAsLong())
                        .le(ObjectUtil.isNotNull(dto.getVisitTime()),ReservationSchool::getStartTime,dto.getVisitTime())
                        .ge(ObjectUtil.isNotNull(dto.getVisitTime()),ReservationSchool::getEndTime,dto.getVisitTime())
                        .like(ObjectUtil.isNotNull(dto.getName()),ReservationSchoolPeople::getName,dto.getName())
                        .select(ReservationSchoolPeople::getId)
                        .select(ReservationSchool.class,x -> VoToColumnUtil.fieldsToColumns(ReservationSchoolVisitorPageVo.class).contains(x.getProperty()))
                        .leftJoin(ReservationSchoolPeople.class,ReservationSchoolPeople::getReservationSchooId,ReservationSchool::getId)
                        .select(ReservationSchoolPeople.class,x -> VoToColumnUtil.fieldsToColumns(ReservationSchoolVisitorPageVo.class).contains(x.getProperty()))
        );
        PageOutput<ReservationSchoolVisitorPageVo> pageOutput = ConventPage.getPageOutput(page, ReservationSchoolVisitorPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/visitor-page")
    @ApiOperation(value="访客记录(分页)")
    @SaCheckPermission("reservationschool:detail")
    public RT<PageOutput<ReservationSchoolVisitorPageVo>> visitorPage(@Valid ReservationSchoolVisitorPageDto dto){
        IPage<ReservationSchoolVisitorPageVo> page = reservationSchoolService.selectJoinListPage(ConventPage.getPage(dto),
                ReservationSchoolVisitorPageVo.class
                , MPJWrappers.<ReservationSchool>lambdaJoin()
                        .orderByDesc(ReservationSchoolPeople::getId)
                        .disableSubLogicDel()
                        .select("(SELECT COUNT(*) FROM reservation_school_people WHERE reservation_schoo_id = t.id) as people_count")
                        .le(ObjectUtil.isNotNull(dto.getVisitTime()),ReservationSchool::getStartTime,dto.getVisitTime())
                        .ge(ObjectUtil.isNotNull(dto.getVisitTime()),ReservationSchool::getEndTime,dto.getVisitTime())
                        .like(!StrUtil.isEmpty(dto.getName()),ReservationSchoolPeople::getName,dto.getName())
                        .like(ObjectUtil.isNotNull(dto.getIdentityCard()),ReservationSchoolPeople::getIdentityCard,dto.getIdentityCard())
                        .eq(ObjectUtil.isNotEmpty(dto.getDeptId())&&dto.getDeptId()!=0,ReservationSchool::getDeptId,dto.getDeptId())
                        .select(ReservationSchoolPeople::getId)
                        .selectAs(ReservationSchoolPeople::getReservationSchooId,ReservationSchoolVisitorPageVo::getPId)
                        .select(ReservationSchool.class,x -> VoToColumnUtil.fieldsToColumns(ReservationSchoolVisitorPageVo.class).contains(x.getProperty()))
                        .leftJoin(ReservationSchoolPeople.class,ReservationSchoolPeople::getReservationSchooId,ReservationSchool::getId)
                        .leftJoin(Department.class,Department::getId,ReservationSchool::getDeptId,ext->ext.selectAs(Department::getName,ReservationSchoolVisitorPageVo::getDeptCn))
                        .leftJoin(XjrUser.class,XjrUser::getId,ReservationSchool::getRespondentUserId,ext->ext.selectAs(XjrUser::getName,ReservationSchoolVisitorPageVo::getRespondentUserCn))
                        .leftJoin(DictionaryDetail.class,DictionaryDetail::getCode, ReservationSchoolPeople::getGender, ext->ext.selectAs(DictionaryDetail::getName, ReservationSchoolVisitorPageVo::getGender))
                        .select(ReservationSchoolPeople.class,x -> VoToColumnUtil.fieldsToColumns(ReservationSchoolVisitorPageVo.class).contains(x.getProperty()))
        );
        PageOutput<ReservationSchoolVisitorPageVo> pageOutput = ConventPage.getPageOutput(page, ReservationSchoolVisitorPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value="根据id查询预约进校信息")
    @SaCheckPermission("reservationschool:detail")
    public RT<ReservationSchoolVo> info(@RequestParam Long id){
        ReservationSchool reservationSchool = reservationSchoolService.getByIdDeep(id);
        if (reservationSchool == null) {
           return RT.error("找不到此数据！");
        }
        return RT.ok(BeanUtil.toBean(reservationSchool, ReservationSchoolVo.class));
    }


    @PostMapping
    @ApiOperation(value = "新增预约进校")
    @SaCheckPermission("reservationschool:add")
    public RT<Boolean> add(@Valid @RequestBody AddReservationSchoolDto dto){
        ReservationSchool reservationSchool = BeanUtil.toBean(dto, ReservationSchool.class);
        boolean isSuccess = reservationSchoolService.add(reservationSchool);
    return RT.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改预约进校")
    @SaCheckPermission("reservationschool:edit")
    public RT<Boolean> update(@Valid @RequestBody UpdateReservationSchoolDto dto){

        ReservationSchool reservationSchool = BeanUtil.toBean(dto, ReservationSchool.class);
        return RT.ok(reservationSchoolService.update(reservationSchool));

    }

    @DeleteMapping
    @ApiOperation(value = "删除预约进校")
    @SaCheckPermission("reservationschool:delete")
    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
        return RT.ok(reservationSchoolService.delete(ids));

    }

    @GetMapping(value = "/info-qrcode")
    @ApiOperation(value="预约进校-生成二维码")
    @SaCheckPermission("reservationschool:detail")
    public RT<List<ReservationSchoolPeopleVo>> qrcode(@RequestParam Long id) throws Exception {
        ReservationSchool reservationSchool = reservationSchoolService.getByIdDeep(id);
        List<ReservationSchoolPeople> peopleList = reservationSchool.getReservationSchoolPeopleList();
        List<ReservationSchoolPeopleVo> result = new ArrayList<>();
        JsonParser parser = new JsonParser();
        int width = 200;
        int height = 200;
        int margin = 1;
        for (ReservationSchoolPeople people : peopleList) {
            ReservationSchoolPeopleVo peopleVo = BeanUtil.toBean(people, ReservationSchoolPeopleVo.class);

            JsonObject jsonObject = parser.parse(people.getRegistrationResult()).getAsJsonObject();
            if("0".equals(jsonObject.get("code").getAsString()) && "success".equals(jsonObject.get("msg").getAsString())){
                JsonObject data = jsonObject.get("data").getAsJsonObject();
                String url = data.get("QRCode").getAsString();
                String base64 = QrCodeUtil.createBase64(url, width, height, margin);
                peopleVo.setQRCode(base64);
            }

            result.add(peopleVo);
        }
        return RT.ok(result);
    }

}