package com.yida.data.system.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.CurrentUser;
import com.yida.data.common.core.entity.FebsResponse;
import com.yida.data.common.core.entity.QueryRequest;
import com.yida.data.common.core.entity.constant.StringConstant;
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.dto.*;
import com.yida.data.system.mapper.EduAreaMapper;
import com.yida.data.system.service.IDeptService;
import com.yida.data.system.service.IUserService;
import com.yida.data.system.vo.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author MrBird
 */
@Slf4j
@Validated
@RestController
@RequestMapping("dept")
@RequiredArgsConstructor
public class DeptController {

    private final IDeptService deptService;

    private final IUserService userService;

    @Resource
    private EduAreaMapper eduAreaMapper;

    /**
     * 查询父级部门
     */
    @ApiOperation("查询父级部门")
    @GetMapping("/getParent")
    public ResultBean<Dept> getParent(@ApiParam("部门id") Long deptId) {
        return ResultBean.buildSuccess(deptService.getById(deptService.getById(deptId).getParentId()));
    }

    @ApiOperation("向上查询父级部门")
    @GetMapping("/findParentUp")
    public ResultBean<AllDeptInfoVO> findParentUp(@ApiParam("部门id") Long deptId,
        @ApiParam("最上级部门类型,0表示学校，1表示班级，2表示年级，3表示学段，4表示校区，5公司，6" +
            "学校部门") Integer type) {
        return ResultBean.buildSuccess(deptService.findParentUp(deptId, type));
    }

    @GetMapping("/findListByParent")
    @ApiOperation("查询所有子节点")
    public ResultBean<List<Dept>> findListByParent(Long deptId) {
        return ResultBean.buildSuccess(deptService.findListByParent(Arrays.asList(deptId), 0));
    }

    @ApiOperation("查询直接子节点")
    @GetMapping("/findChildByParent")
    public ResultBean findChildByParent(@ApiParam("父节点id，不能为空") @RequestParam Long deptId,
        @ApiParam("子节点类型,0表示学校，5公司，6部门，7教育局,默认所有直接子节点") Integer type) {
        return ResultBean.buildSuccess(deptService.findChildByParent(deptId, type));
    }

    @ApiOperation("向下查询到要查询的部门类别的子部门(可查询非直接子部门)")
    @GetMapping("/findChildByParentAndType")
    public ResultBean<List<Dept>> findChildByParentAndType(@ApiParam("父节点id，不能为空") Long parentId,
        @ApiParam("子节点类型,0表示学校，5公司，6部门，7教育局,默认所有直接子节点") Integer type) {
        return ResultBean.buildSuccess(deptService.findChildByParentAndType(Arrays.asList(parentId), type));
    }

    @ApiOperation("根据部门id查询所属学校")
    @GetMapping("findSchoolByDept")
    public ResultBean<Dept> findSchoolByDept(Long deptId) {
        return ResultBean.buildSuccess(deptService.findSchooleByDept(deptId));
    }

    @GetMapping
    public FebsResponse deptList(QueryRequest request, Dept dept) {
        Map<String, Object> depts = this.deptService.findDepts(request, dept);
        return new FebsResponse().data(depts);
    }

    @PostMapping
    @PreAuthorize("hasAuthority('dept:add')")
    @OperationLog(module = ModuleName.DEPT, methods = "新增部门", type = OperationLogTypeEnum.INSERT)
    public void addDept(@Valid Dept dept) {
        this.deptService.createDept(dept);
    }

    @DeleteMapping("/{deptIds}")
    @PreAuthorize("hasAuthority('dept:delete')")
    @OperationLog(module = ModuleName.DEPT, methods = "删除部门", type = OperationLogTypeEnum.DELETE)
    public void deleteDepts(@NotBlank(message = "{required}") @PathVariable String deptIds) {
        String[] ids = deptIds.split(StringConstant.COMMA);
        this.deptService.deleteDepts(ids);
    }

    @PutMapping
    @PreAuthorize("hasAuthority('dept:update')")
    @OperationLog(module = ModuleName.DEPT, methods = "修改部门", type = OperationLogTypeEnum.UPDATE)
    public void updateDept(@Valid Dept dept) {
        this.deptService.updateDept(dept);
    }

    @PostMapping("excel")
    @PreAuthorize("hasAuthority('dept:export')")
    public void export(Dept dept, QueryRequest request, HttpServletResponse response) {
        List<Dept> depts = this.deptService.findDepts(dept, request);
        //ExcelKit.$Export(Dept.class, response).downXlsx(depts, false);
    }

    @GetMapping("/getInfoById")
    @OperationLog(module = ModuleName.SYSTEM, methods = "根据id查询部门")
    public ResultBean<Dept> getInfoById(Long deptId) {
        return ResultBean.buildSuccess(deptService.getById(deptId));
    }

    @ApiOperation("根据区域查询学校列表")
    @GetMapping("/getSchoolByArea")
    public ResultBean<List<Dept>> getSchoolByArea(@ApiParam("区域id") @RequestParam(required = false) Long areaId,
        @ApiParam("搜索关键词 学校名") @RequestParam(required = false) String schoolName) throws NoSuchMethodException {
        return ResultBean.buildSuccess(deptService.getSchoolByArea(areaId, schoolName));
    }

    @ApiOperation("分页查询学校列表")
    @GetMapping("/getPageSchoolByArea")
    public ResultBean<IPage<Dept>> getPageSchoolByArea(@ApiParam("类型") @RequestParam(required = false) Long areaId,
        @ApiParam("搜索关键词 学校名") @RequestParam(required = false) String schoolName,
        @ApiParam("当前页码") @RequestParam(defaultValue = "1") Integer pageNum,
        @ApiParam("页面大小") @RequestParam(defaultValue = "10") Integer pageSize) {
        Page<Dept> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(pageNum);
        return ResultBean.buildSuccess(deptService.getPageSchoolByArea(areaId, schoolName, page));
    }

    @ApiOperation("部门树")
    @GetMapping("/getDeptTree")
    public ResultBean<List> getDeptTree(@ApiParam("根节点Id") Long deptId,
        @ApiParam("0-包含学校的企业部门（后勤部等）与学校部门（校区学段等），1-仅学校部门，2-仅企业部门，默认0") @RequestParam(defaultValue =
            "0") Integer type) {
        if (deptId == null) {
            deptId = FebsUtil.getCurrentUser().getDeptId();
        }
        return ResultBean.buildSuccess(deptService.getDeptTree(deptId, type));
    }

    @GetMapping("/getSchoolAreaInfo")
    @OperationLog(module = ModuleName.SYSTEM, methods = "获取学校和区域信息")
    public ResultBean<SchoolClassInfoVO> getSchoolAreaInfo(Long schoolId) {
        return ResultBean.buildSuccess(deptService.getSchoolAreaInfo(schoolId));
    }

    @ApiOperation("查询部门区域")
    @GetMapping("/findAreaById")
    public ResultBean<AreaVO> findAreaById(@RequestParam Long id) {
        Long byId = deptService.getById(id).getAreaId();
        return ResultBean.buildSuccess(eduAreaMapper.findAreaById(byId));
    }

    /**
     * 查询代理商管理的学校列表数据
     *
     * @param agentSchoolSelectPageDTO 查询代理商管理的学校列表数据请求类
     * @return com.yida.data.common.core.common.ResultBean<com.baomidou.mybatisplus.core.metadata.IPage <
        * com.yida.data.system.vo.AgentSchoolVO>>
     * @author ZYJ
     * @date 2021/9/27 17:03
     */
    @GetMapping(value = "/listAgentSchoolPage")
    @ApiOperation(value = "查询代理商管理的学校列表数据", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultBean<IPage<AgentSchoolSelectPageVO>> listAgentSchoolPage(
        @Valid AgentSchoolSelectPageDTO agentSchoolSelectPageDTO) {
        return this.deptService.listAgentSchoolPage(agentSchoolSelectPageDTO);
    }

    /**
     * 代理商保存学校数据
     *
     * @param agentSchoolSaveDTO 代理商保存学校请求类
     * @return com.yida.data.common.core.common.ResultBean<java.lang.String>
     * @author ZYJ
     * @date 2021/9/27 17:59
     */
//    @PreAuthorize("hasRole('role:agent:admin')")
    @PostMapping(value = "/saveAgentSchool", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "代理商保存学校数据", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResultBean<String> saveAgentSchool(
        @Valid @RequestBody AgentSchoolSaveDTO agentSchoolSaveDTO) {
        return this.deptService.saveAgentSchool(agentSchoolSaveDTO);
    }

    /**
     * 查询学校信息
     *
     * @param schoolId 学校id
     * @return com.yida.data.common.core.common.ResultBean<com.yida.data.system.vo.AgentSchoolDetailVO>
     * @author ZYJ
     * @date 2021/9/27 20:54
     */
//    @PreAuthorize("hasRole('role:agent:admin')")
    @PostMapping(value = "/getAgentSchoolInfo")
    @ApiOperation(value = "查询学校信息", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultBean<AgentSchoolDetailVO> getAgentSchoolInfo(
        @ApiParam(value = "学校id", required = true) @RequestParam Long schoolId) {
        return this.deptService.getAgentSchoolInfo(schoolId);
    }

    /**
     * 启用或停用学校
     *
     * @param schoolId     学校id
     * @param enableStatus 需要设置的启用或停用状态. 启用: 1, 停用: 0
     * @return com.yida.data.common.core.common.ResultBean<java.lang.String>
     * @author ZYJ
     * @date 2021/9/28 9:43
     */
//    @PreAuthorize("hasRole('role:agent:admin')")
    @PostMapping(value = "/updateEnableStatus")
    @ApiOperation(value = "启用或停用学校", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @OperationLog(module = ModuleName.DEPT, methods = "启用或停用学校", type = OperationLogTypeEnum.UPDATE)
    public ResultBean<String> updateEnableStatus(
        @ApiParam(value = "学校id", required = true) @RequestParam Long schoolId,
        @ApiParam(value = "需要设置的启用或停用状态. 启用: 1, 停用: 0", required = true) @RequestParam Integer enableStatus) {
        return this.deptService.updateEnableStatus(schoolId, enableStatus);
    }

    // TODO 2021/9/28 注销学校功能待确认

    /**
     * 代理商查询学校管理员账号列表数据
     *
     * @param schoolAdminAccountSelectPageDTO 代理商查询学校管理员账号列表数据请求类
     * @return com.yida.data.common.core.common.ResultBean<com.baomidou.mybatisplus.core.metadata.IPage <
        * com.yida.data.system.vo.SchoolAdminAccountSelectPageVO>>
     * @author ZYJ
     * @date 2021/9/29 17:34
     */
    @PostMapping(value = "/listSchoolAdminAccountPage")
    @ApiOperation(value = "查询学校管理员账号列表数据", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultBean<IPage<SchoolAdminAccountSelectPageVO>> listSchoolAdminAccountPage(
        @Valid SchoolAdminAccountSelectPageDTO schoolAdminAccountSelectPageDTO) {
        return ResultBean.buildSuccess(this.userService.listSchoolAdminAccountPage(schoolAdminAccountSelectPageDTO));
    }

    /**
     * 保存学校负责人账号
     *
     * @param schoolAdminAccountSaveDTO 保存学校负责人账号请求类
     * @return com.yida.data.common.core.common.ResultBean<java.lang.String>
     * @author ZYJ
     * @date 2021/9/28 11:02
     */
//    @PreAuthorize("hasRole('role:agent:admin')")
    @PostMapping(value = "/saveSchoolAdminAccount", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "保存学校负责人账号", consumes = MediaType.APPLICATION_JSON_VALUE)
    @OperationLog(module = ModuleName.DEPT, methods = "保存学校负责人账号", type = OperationLogTypeEnum.UPDATE)
    public ResultBean<String> saveSchoolAdminAccount(
        @Valid @RequestBody SchoolAdminAccountSaveDTO schoolAdminAccountSaveDTO) {
        return this.userService.saveSchoolAdminAccount(schoolAdminAccountSaveDTO);
    }
}
