package com.xjrsoft.module.activity.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.module.activity.dto.ActivityEnrollExportDto;
import com.xjrsoft.module.activity.dto.ActivityInfoPageDto;
import com.xjrsoft.module.activity.dto.ActivityInfoTodayDto;
import com.xjrsoft.module.activity.dto.AddActivityEnrollRangeDto;
import com.xjrsoft.module.activity.dto.AddActivityInfoDto;
import com.xjrsoft.module.activity.dto.ChangeStatusDto;
import com.xjrsoft.module.activity.dto.UpdateActivityInfoDto;
import com.xjrsoft.module.activity.entity.ActivityEnroll;
import com.xjrsoft.module.activity.entity.ActivityInfo;
import com.xjrsoft.module.activity.service.IActivityEnrollRangeService;
import com.xjrsoft.module.activity.service.IActivityEnrollService;
import com.xjrsoft.module.activity.service.IActivityInfoService;
import com.xjrsoft.module.activity.vo.ActivityEnrollPageVo;
import com.xjrsoft.module.activity.vo.ActivityEnrollRangeVo;
import com.xjrsoft.module.activity.vo.ActivityInfoPageVo;
import com.xjrsoft.module.activity.vo.ActivityInfoVo;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.service.IBaseClassService;
import com.xjrsoft.module.concat.service.IXjrUserService;
import com.xjrsoft.module.organization.entity.Department;
import com.xjrsoft.module.organization.service.IDepartmentService;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.system.service.IFileService;
import com.xjrsoft.module.teacher.entity.XjrUser;
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.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @title: 活动信息
* @Author dzx
* @Date: 2024-07-19
* @Version 1.0
*/
@RestController
@RequestMapping("/activity" + "/activityInfo")
@Api(value = "/activity"  + "/activityInfo",tags = "活动信息代码")
@AllArgsConstructor
public class ActivityInfoController {


    private final IActivityInfoService activityInfoService;
    private final IBaseClassService classService;
    private final IDepartmentService departmentService;
    private final IXjrUserService xjrUserService;
    private final IFileService fileService;
    private final IActivityEnrollService enrollService;
    private final IActivityEnrollRangeService rangeService;

    @GetMapping(value = "/page")
    @ApiOperation(value="活动信息列表(分页)")
    @SaCheckPermission("activityinfo:detail")
    public RT<PageOutput<ActivityInfoPageVo>> page(@Valid ActivityInfoPageDto dto){

        Page<ActivityInfoPageVo> page = activityInfoService.getPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
        PageOutput<ActivityInfoPageVo> pageOutput = ConventPage.getPageOutput(page, ActivityInfoPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/today-schedule")
    @ApiOperation(value="今日安排(分页)")
    @SaCheckPermission("activityinfo:detail")
    public RT<PageOutput<ActivityInfoPageVo>> todaySchedule(@Valid ActivityInfoTodayDto dto){
        List<String> roleList = StpUtil.getRoleList();
        if(dto.getLoginUserId() == null){
            dto.setLoginUserId(StpUtil.getLoginIdAsLong());
        }
        if(roleList.contains("STUDENT")){
            dto.setRoleType(3);
        }else if(roleList.contains("TEACHER")){
            dto.setRoleType(2);
        }
        return RT.ok();
    }

    @GetMapping(value = "/info")
    @ApiOperation(value="根据id查询活动信息信息")
    @SaCheckPermission("activityinfo:detail")
    public RT<ActivityInfoVo> info(@RequestParam Long id, Integer category){
        ActivityInfoVo infoVo = null;
        if(category == null || (category == 1 || category == 2)){
            ActivityInfo activityInfo = activityInfoService.getByIdDeep(id);
            if (activityInfo == null) {
                return RT.error("找不到此数据！");
            }
            infoVo = BeanUtil.toBean(activityInfo, ActivityInfoVo.class);
            if(infoVo.getOrgId() != null){
                Department department = departmentService.getById(infoVo.getOrgId());
                if(department != null){
                    infoVo.setOrgName(department.getName());
                }
            }
            if(infoVo.getEnterpriseId() != null){
                String tableName = "company_coop";
                Entity where = Entity.create(tableName);
                where.set("id", infoVo.getEnterpriseId());
                Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);

                if(objectMap != null && objectMap.containsKey("company_name")){
                    infoVo.setEnterpriseName(objectMap.get("company_name").toString());
                }
            }

            List<ActivityEnrollRangeVo> userRelationList = new ArrayList<>();
            if(activityInfo.getEnrollRange() != null && !activityInfo.getEnrollRange().isEmpty()){
                JSONArray asJsonArray = JSONUtil.parseArray(activityInfo.getEnrollRange());
                for (Object jsonElement : asJsonArray) {
                    ActivityEnrollRangeVo relationDto = JSONUtil.toBean(JSONUtil.parseObj(jsonElement), ActivityEnrollRangeVo.class);
                    if(relationDto.getUserId() != null){
                        XjrUser xjrUser = xjrUserService.getById(relationDto.getUserId());
                        if(xjrUser != null){
                            relationDto.setName(xjrUser.getName());
                        }
                    }else if(relationDto.getDeptId() != null){
                        Department department = departmentService.getById(relationDto.getDeptId());
                        if(department != null){
                            relationDto.setName(department.getName());
                        }

                    }else if(relationDto.getClassId() != null){
                        BaseClass aClass = classService.getById(relationDto.getClassId());
                        if(aClass != null){
                            relationDto.setName(aClass.getName());
                        }
                    }
                    userRelationList.add(relationDto);
                }
            }
            infoVo.setActivityEnrollRangeList(userRelationList);

            ActivityEnrollExportDto dto = new ActivityEnrollExportDto();
            dto.setActivityInfoId(id);
            List<ActivityEnrollPageVo> enrollList = enrollService.getList(dto);
            infoVo.setEnrollCount(enrollList.size());

            Set<ActivityEnrollPageVo> teacherSet = enrollList.stream().filter(x -> x.getTeacherId() != null).collect(Collectors.toSet());
            infoVo.setTeacherCount(teacherSet.size());

            Set<ActivityEnrollPageVo> studentSet = enrollList.stream().filter(x -> x.getStudentId() != null).collect(Collectors.toSet());
            infoVo.setStudentCount(studentSet.size());

            Set<ActivityEnrollPageVo> suretSet = enrollList.stream().filter(x -> (x.getStatus() == 2)).collect(Collectors.toSet());
            infoVo.setSureCount(suretSet.size());

            Set<ActivityEnrollPageVo> notSuretSet = enrollList.stream().filter(x -> (x.getStatus() == 1 || x.getStatus() == 0)).collect(Collectors.toSet());
            infoVo.setNotSureCount(notSuretSet.size());
        }else if(category == 3){
            String tableName = "club_activities";
            Entity where = Entity.create(tableName);
            where.set("id", id);
            Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);
            infoVo = new ActivityInfoVo();
            if(objectMap == null){
                return RT.ok(infoVo);
            }

            infoVo.setName(objectMap.get("club_activities_name").toString());
            infoVo.setContent(objectMap.get("club_activities_content").toString());
            infoVo.setStartDate((Date)objectMap.get("start_time"));
            infoVo.setEndDate((Date)objectMap.get("end_time"));
            infoVo.setPlace(objectMap.get("activity_location").toString());
        }else if(category == 4){
            String tableName = "moral_event";
            Entity where = Entity.create(tableName);
            where.set("id", id);
            Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);
            infoVo = new ActivityInfoVo();
            if(objectMap == null){
                return RT.ok(infoVo);
            }
            infoVo.setName(objectMap.get("moral_event_name").toString());
            infoVo.setContent(objectMap.get("event_content").toString());
            infoVo.setStartDate((Date)objectMap.get("event_start_time"));
            infoVo.setEndDate((Date)objectMap.get("event_end_time"));
            infoVo.setPlace(objectMap.get("event_address").toString());
            infoVo.setOrgName(objectMap.get("host_unit").toString());
            infoVo.setDutyPerson(objectMap.get("event_leader").toString());
        }else if(category == 5){
            String tableName = "wf_teacher_training";
            Entity where = Entity.create(tableName);
            where.set("id", id);
            Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);
            infoVo = new ActivityInfoVo();
            if(objectMap == null){
                return RT.ok(infoVo);
            }
            infoVo.setName(objectMap.get("training_name").toString());
            infoVo.setContent(objectMap.get("training_topic").toString());
            infoVo.setStartDate(Date.from(((LocalDateTime)objectMap.get("start_time")).atZone(ZoneId.systemDefault()).toInstant()));
            infoVo.setEndDate(Date.from(((LocalDateTime)objectMap.get("end_time")).atZone(ZoneId.systemDefault()).toInstant()));
            infoVo.setPlace(objectMap.get("training_address").toString());
            infoVo.setDutyPerson(objectMap.get("person_in_charge").toString());
        }else if(category == 6){
            String tableName = "party_build_event";
            Entity where = Entity.create(tableName);
            where.set("id", id);
            Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);
            infoVo = new ActivityInfoVo();
            if(objectMap == null){
                return RT.ok(infoVo);
            }
            infoVo.setName(objectMap.get("event_type").toString());
            infoVo.setContent(objectMap.get("event_content").toString());
            infoVo.setStartDate((Date)objectMap.get("event_start_time"));
            infoVo.setEndDate((Date)objectMap.get("event_end_time"));
            infoVo.setPlace(objectMap.get("event_address").toString());
        }

        return RT.ok(infoVo);
    }

    @PostMapping(value = "/change-status")
    @ApiOperation(value="修改状态")
    @SaCheckPermission("officebuild:detail")
    public RT<Boolean> changeStatus(@Valid @RequestBody ChangeStatusDto dto) throws Exception {
        ActivityInfo activityInfo = activityInfoService.getById(dto.getId());
        if(activityInfo == null){
            throw new MyException("未能找到活动信息");
        }
        activityInfo.setStatus(dto.getStatus());
        activityInfoService.updateById(activityInfo);
        return RT.ok(true);
    }


    @PostMapping
    @ApiOperation(value = "新增活动信息")
    @SaCheckPermission("activityinfo:add")
    public RT<Boolean> add(@Valid @RequestBody AddActivityInfoDto dto){

        boolean isSuccess = activityInfoService.add(dto);
        return RT.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改活动信息")
    @SaCheckPermission("activityinfo:edit")
    public RT<Boolean> update(@Valid @RequestBody UpdateActivityInfoDto dto){
        return RT.ok(activityInfoService.update(dto));

    }

    @DeleteMapping
    @ApiOperation(value = "删除活动信息")
    @SaCheckPermission("activityinfo:delete")
    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
        return RT.ok(activityInfoService.delete(ids));
    }


    @GetMapping(value = "/effective-list")
    @ApiOperation(value="移动端活动信息列表(分页)")
    @SaCheckPermission("activityinfo:detail")
    public RT<PageOutput<ActivityInfoPageVo>> mobilePage(@Valid ActivityInfoPageDto dto){
        AddActivityEnrollRangeDto rangeDto = new AddActivityEnrollRangeDto();
        if(dto.getLoginUserId() == null){
            dto.setLoginUserId(StpUtil.getLoginIdAsLong());
        }

        rangeDto.setUserId(dto.getLoginUserId());
        List<Long> activityInfoIds = rangeService.getActivityInfoIds(rangeDto);
        dto.setActivityInfoIds(activityInfoIds);
        dto.setIsEffective(1);
        Page<ActivityInfoPageVo> page = activityInfoService.getPage(new Page<>(dto.getLimit(), dto.getSize()), dto);

        List<ActivityEnroll> enrollList = enrollService.list(
                new QueryWrapper<ActivityEnroll>().lambda()
                        .eq(ActivityEnroll::getUserId, StpUtil.getLoginIdAsLong())
        );
        Set<Long> collect = enrollList.stream().map(ActivityEnroll::getActivityInfoId).collect(Collectors.toSet());

        for (ActivityInfoPageVo record : page.getRecords()) {
            record.setIsEnroll(0);
            if(collect.contains(Long.parseLong(record.getId()))){
                record.setIsEnroll(1);
            }
            if(record.getCoverFileId() != null){
                File file = fileService.getOne(new QueryWrapper<File>().lambda().eq(File::getFolderId, record.getCoverFileId()));
                if(file != null){
                    record.setCoverFileUrl(file.getFileUrl());
                }
            }
        }

        PageOutput<ActivityInfoPageVo> pageOutput = ConventPage.getPageOutput(page, ActivityInfoPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/my-enroll-list")
    @ApiOperation(value="我的报名记录(分页)")
    @SaCheckPermission("activityinfo:detail")
    public RT<PageOutput<ActivityInfoPageVo>> myEnrollList(@Valid ActivityInfoPageDto dto){
        dto.setLoginUserId(StpUtil.getLoginIdAsLong());
        Page<ActivityInfoPageVo> page = activityInfoService.getMyPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
        for (ActivityInfoPageVo record : page.getRecords()) {
            if(record.getCoverFileId() != null){
                File file = fileService.getOne(new QueryWrapper<File>().lambda().eq(File::getFolderId, record.getCoverFileId()));
                if(file != null){
                    record.setCoverFileUrl(file.getFileUrl());
                }
            }
        }

        PageOutput<ActivityInfoPageVo> pageOutput = ConventPage.getPageOutput(page, ActivityInfoPageVo.class);
        return RT.ok(pageOutput);
    }
}