package cn.iocoder.yudao.module.system.controller.admin.worklog;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserRespVO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance.LogInstanceNextOrUpVO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance.LogInstancePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance.LogInstanceRespVO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance.LogInstanceSaveReqVO;
import cn.iocoder.yudao.module.system.convert.worklog.LogInstanceConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.service.worklog.LogInstanceService;
import cn.iocoder.yudao.module.system.service.worklog.LogReadService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "管理后台 - 日志实例")
@RestController
@RequestMapping("/system/log-instance")
@Validated
public class LogInstanceController {

    @Resource
    private LogInstanceService logInstanceService;

    @Resource
    private LogReadService logReadService;

    @Resource
    private AdminUserService adminUserService;

    @PostMapping("/create")
    @Operation(summary = "创建日志实例")
    @PreAuthorize("@ss.hasPermission('system:log-instance:create')")
    public CommonResult<Long> createLogInstance(@Valid @RequestBody LogInstanceSaveReqVO createReqVO) {
        return success(logInstanceService.createLogInstance(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新日志实例")
    @PreAuthorize("@ss.hasPermission('system:log-instance:update')")
    public CommonResult<Boolean> updateLogInstance(@Valid @RequestBody LogInstanceSaveReqVO updateReqVO) {
        logInstanceService.updateLogInstance(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除日志实例")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('system:log-instance:delete')")
    public CommonResult<Boolean> deleteLogInstance(@RequestParam("id") Long id) {
        logInstanceService.deleteLogInstance(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得日志实例")
    @Parameter(name = "id", description = "编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<LogInstanceRespVO> getLogInstance(@RequestParam("id") Long id) {

        //查看日志详情时，变更当前用户日志的阅读状态
        logReadService.updateReadStatus(id, getLoginUserId());

        //获取日志详情
        LogInstanceRespVO logInstance = logInstanceService.getLogInstance(id);

        //用户日志发起人详情
        AdminUserDO userDO = adminUserService.getUser(logInstance.getStartUserId());
        //设置日志发起人名称
        logInstance.setStartUserName(userDO.getNickname());
        //设置日志发起人头像
        logInstance.setAvatar(userDO.getAvatar());

        return success(logInstance);
    }


    @PostMapping("/getNextOrUp")
    @Operation(summary = "获取上一篇下一篇日志")
    public CommonResult<LogInstanceNextOrUpVO> getNextOrUp(@RequestBody LogInstancePageReqVO dto,
                                                           @Parameter(description = "当前id") @RequestParam("id") Long id,
                                                           @Parameter(description = "日志tab 0我收到的 1我发出的") @RequestParam("pagingType") Integer pagingType) {
        LogInstanceNextOrUpVO vo = logInstanceService.getNextOrUp(dto, id, pagingType);
        return success(vo);
    }

    @GetMapping("/page")
    @Operation(summary = "获得日志分页列表")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<IPage<LogInstanceRespVO>> getLogInstancePage(@ModelAttribute LogInstancePageReqVO pageReqVO) {

        IPage<LogInstanceRespVO> pageResult = logInstanceService.getLogInstancePage(pageReqVO, 0);
        return success(pageResult);
    }

    @GetMapping("/my-page")
    @Operation(summary = "获得我的日志分页列表")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<IPage<LogInstanceRespVO>> getMyLogInstancePage(@ModelAttribute LogInstancePageReqVO pageReqVO) {

        IPage<LogInstanceRespVO> pageResult = logInstanceService.getLogInstancePage(pageReqVO, 1);
        return success(pageResult);
    }

    @PostMapping("/get-dept")
    @Operation(summary = "获得我收到的日志页面中的部门列表")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<List<DeptRespVO>> getReadDept() {

        List<DeptRespVO> deptInfo = logInstanceService.getDeptInfo();
        return success(deptInfo);
    }

    @GetMapping("/get-upLog")
    @Operation(summary = "获取上一篇日志，用于导入上一篇日志")
    @Parameter(name = "formId", description = "日志模板编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<LogInstanceRespVO> getUpLog(@RequestParam("formId") Long formId) {

        LogInstanceRespVO logInstanceRespVO = LogInstanceConvert.INSTANCE.convert(logInstanceService.getUpLog(formId));
        logInstanceRespVO = logInstanceService.setContentFun(logInstanceRespVO);

        return success(logInstanceRespVO);
    }

    @PostMapping("/getByLogId")
    @Operation(summary = "获得可查看日志的用户详情")
    @Parameter(name = "logId", description = "日志编号", required = true, example = "10")
    @PreAuthorize("@ss.hasPermission('system:view-log:query')")
    public CommonResult<List<Map<String, Object>>> getUserByLogId(@RequestParam("logId") Long logId) {

        List<Map<String, Object>> readUserVO = new ArrayList<>();

        //获取可查看者用户列表
        Map<Integer, List<Long>> usrMap = logReadService.getUserId(logId);

        //获取未读用户详情
        List<UserRespVO> unReadUserInfo = BeanUtils.toBean(adminUserService.getUserList(usrMap.get(0)), UserRespVO.class);
        //获取已读用户详情
        List<UserRespVO> readUserInfo = BeanUtils.toBean(adminUserService.getUserList(usrMap.get(1)), UserRespVO.class);

        Map<String, Object> unReadMap = new HashMap<>();
        Map<String, Object> readMap = new HashMap<>();

        unReadMap.put("readStatus", 0);
        unReadMap.put("value", unReadUserInfo);

        readMap.put("readStatus", 1);
        readMap.put("value", readUserInfo);

        readUserVO.add(unReadMap);
        readUserVO.add(readMap);

        return success(readUserVO);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出日志实例 Excel")
    @PreAuthorize("@ss.hasPermission('system:log-instance:export')")
    @OperateLog(type = EXPORT)
    public void exportLogInstanceExcel(@Valid LogInstancePageReqVO pageReqVO,
                                       HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<LogInstanceRespVO> list = logInstanceService.getLogInstancePage(pageReqVO, null).getRecords();
        // 导出 Excel
        ExcelUtils.write(response, "日志实例的拓展.xls", "数据", LogInstanceRespVO.class,
                BeanUtils.toBean(list, LogInstanceRespVO.class));
    }
}