package org.dromara.main.controller;

import cn.hutool.core.util.ObjectUtil;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.main.domain.bo.MainTrainingBo;
import org.dromara.main.domain.vo.MainTrainingLearnRecordVo;
import org.dromara.main.domain.vo.MainTrainingParticipantVo;
import org.dromara.main.domain.vo.MainTrainingVo;
import org.dromara.main.service.IMainTrainingService;
import org.dromara.system.domain.vo.SysOssUploadVo;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.util.List;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/main/training")
public class MainTrainingController extends BaseController {

    private final IMainTrainingService mainTrainingService;
    private final ISysOssService ossService;

    /**
     * 查询培训列表
     */
    @GetMapping("/list")
    public TableDataInfo<MainTrainingVo> list(MainTrainingBo bo, PageQuery pageQuery) {
        return mainTrainingService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询线下培训列表
     */
    @GetMapping("/offline/list")
    public TableDataInfo<MainTrainingVo> offlineList(MainTrainingBo bo, PageQuery pageQuery) {
        return mainTrainingService.queryOfflinePageList(bo, pageQuery);
    }

    /**
     * 获取培训详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<MainTrainingVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return R.ok(mainTrainingService.queryById(id));
    }

    /**
     * 获取线下培训详细信息
     */
    @GetMapping("/offline/{id}")
    public R<MainTrainingVo> getOfflineInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        MainTrainingVo vo = mainTrainingService.queryOfflineById(id);
        return vo == null ? R.fail("线下培训不存在") : R.ok(vo);
    }

    /**
     * 查询视频培训学习记录分页
     */
    @GetMapping("/{id}/learn-records")
    public TableDataInfo<MainTrainingLearnRecordVo> learnRecords(@NotNull(message = "主键不能为空") @PathVariable Long id, PageQuery pageQuery) {
        return mainTrainingService.queryLearnRecordPage(id, pageQuery);
    }

    /**
     * 查询线下培训参与人分页
     */
    @GetMapping("/offline/{id}/participants")
    public TableDataInfo<MainTrainingParticipantVo> offlineParticipants(@NotNull(message = "主键不能为空") @PathVariable Long id, PageQuery pageQuery) {
        return mainTrainingService.queryOfflineParticipantPage(id, pageQuery);
    }

    /**
     * 导出视频培训学习记录
     */
    @Log(title = "培训管理", businessType = BusinessType.EXPORT)
    @PostMapping("/{id}/learn-records/export")
    public void exportLearnRecords(@NotNull(message = "主键不能为空") @PathVariable Long id, @RequestBody List<Long> studentIds, HttpServletResponse response) {
        List<MainTrainingLearnRecordVo> list = mainTrainingService.queryLearnRecordExportList(id, studentIds);
        ExcelUtil.exportExcel(list, "学习记录", MainTrainingLearnRecordVo.class, response);
    }

    /**
     * 导出线下培训参与人
     */
    @Log(title = "培训管理", businessType = BusinessType.EXPORT)
    @PostMapping("/offline/{id}/participants/export")
    public void exportOfflineParticipants(@NotNull(message = "主键不能为空") @PathVariable Long id, @RequestBody List<Long> studentIds, HttpServletResponse response) {
        List<MainTrainingParticipantVo> list = mainTrainingService.queryOfflineParticipantExportList(id, studentIds);
        ExcelUtil.exportExcel(list, "线下培训参与人", MainTrainingParticipantVo.class, response);
    }

    /**
     * 新增培训
     */
    @Log(title = "培训管理", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@RequestBody MainTrainingBo bo) {
        return toAjax(mainTrainingService.insertByBo(bo));
    }

    /**
     * 培训文件上传
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<SysOssUploadVo> upload(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("上传文件不能为空");
        }
        SysOssVo oss = ossService.upload(file);
        SysOssUploadVo uploadVo = new SysOssUploadVo();
        uploadVo.setUrl(oss.getUrl());
        uploadVo.setFileName(oss.getOriginalName());
        uploadVo.setOssId(oss.getOssId().toString());
        return R.ok(uploadVo);
    }

    /**
     * 修改培训
     */
    @Log(title = "培训管理", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@RequestBody MainTrainingBo bo) {
        return toAjax(mainTrainingService.updateByBo(bo));
    }

    /**
     * 删除培训
     *
     * @param ids 主键串
     */
    @Log(title = "培训管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
        return toAjax(mainTrainingService.deleteWithValidByIds(List.of(ids), true));
    }

    /**
     * 删除线下培训
     */
    @Log(title = "培训管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/offline/{id}")
    public R<Void> removeOffline(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return toAjax(mainTrainingService.deleteOfflineById(id));
    }

    /**
     * 更新培训状态（上架/下架）
     */
    @Log(title = "培训管理", businessType = BusinessType.UPDATE)
    @PutMapping("/updateStatus")
    public R<Void> updateStatus(@RequestBody MainTrainingBo bo) {
        return toAjax(mainTrainingService.updateStatus(bo.getId(), bo.getStatus()));
    }

    /**
     * 更新线下培训状态（上架/下架）
     */
    @Log(title = "培训管理", businessType = BusinessType.UPDATE)
    @PutMapping("/offline/updateStatus")
    public R<Void> updateOfflineStatus(@RequestBody MainTrainingBo bo) {
        return toAjax(mainTrainingService.updateOfflineStatus(bo.getId(), bo.getStatus()));
    }
}
