package com.xjrsoft.module.textbook.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.TreeUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.entity.BaseGrade;
import com.xjrsoft.module.base.entity.BaseSemester;
import com.xjrsoft.module.base.service.IBaseClassService;
import com.xjrsoft.module.student.entity.BaseClassMajorSet;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.textbook.dto.*;
import com.xjrsoft.module.textbook.entity.WfTextbookSubscription;
import com.xjrsoft.module.textbook.entity.WfTextbookSubscriptionItem;
import com.xjrsoft.module.textbook.service.IWfTextbookSubscriptionService;
import com.xjrsoft.module.textbook.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
* @title: 教材教辅征订
* @Author szs
* @Date: 2024-06-04
* @Version 1.0
*/
@RestController
@RequestMapping("/textbook" + "/wfTextbookSubscription")
@Api(value = "/textbook"  + "/wfTextbookSubscription",tags = "教材教辅征订代码")
@AllArgsConstructor
public class WfTextbookSubscriptionController {


    private final IWfTextbookSubscriptionService wfTextbookSubscriptionService;

    private final IBaseClassService baseClassService;

    @GetMapping(value = "/tree")
    @ApiOperation(value = "学生年级班级树")
    @SaCheckPermission("studentmanager:detail")
    public RT<List<GradeClassTreeVo>> tree() {
        List<GradeClassTreeVo> voList = new ArrayList<>();

        voList.add(new GradeClassTreeVo() {{
            setId("666666");
            setName("班级");
        }});

        //获取班级List（包含年级信息）
        MPJLambdaWrapper<BaseClass> baseClassMPJLambdaWrapper = new MPJLambdaWrapper<>();
        baseClassMPJLambdaWrapper
                .selectAs(BaseClass::getId, GradeClassListVo::getClassId)
                .selectAs(BaseClass::getName, GradeClassListVo::getClassName)
                .selectAs(BaseClass::getGradeId, GradeClassListVo::getGradeId)
                .selectAs(BaseGrade::getName, GradeClassListVo::getGradeName)
                .leftJoin(BaseGrade.class, BaseGrade::getId, BaseClass::getGradeId)
                .eq(BaseClass::getDeleteMark, 0)
                .eq(BaseClass::getIsGraduate, 1)
        ;
        List<GradeClassListVo> gradeClassTreeVoList = baseClassService.selectJoinList(GradeClassListVo.class, baseClassMPJLambdaWrapper);

        //年级Map
        Map<String, GradeClassTreeVo> gradeMap = new HashMap<>();
        for (GradeClassListVo gradeClassListVo : gradeClassTreeVoList){
            if(gradeClassListVo.getGradeId() != null && gradeMap.get(gradeClassListVo.getGradeId()) == null){
                gradeMap.put(gradeClassListVo.getGradeId(), new GradeClassTreeVo(){{
                    setId(gradeClassListVo.getGradeId());
                    setName(gradeClassListVo.getGradeName());
                    setParentId("666666");
                }});
            }
            voList.add(new GradeClassTreeVo() {{
                setId(gradeClassListVo.getClassId());
                setName(gradeClassListVo.getClassName());
                setParentId(gradeClassListVo.getGradeId());
            }});
        }

        List<GradeClassTreeVo> gradeList = new ArrayList<>(gradeMap.values());
        voList.addAll(gradeList);

        List<GradeClassTreeVo> treeVoList = TreeUtil.build(voList);

        return RT.ok(treeVoList);
    }

    @GetMapping(value = "/page")
    @ApiOperation(value="教材教辅征订列表(分页)")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<PageOutput<WfTextbookSubscriptionPageVo>> page(@Valid WfTextbookSubscriptionPageDto dto){
        MPJLambdaWrapper<WfTextbookSubscription> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper
                .select(WfTextbookSubscription::getId)
                .selectAs(BaseSemester::getName, WfTextbookSubscriptionPageVo::getBaseSemesterIdCn)
                .select("(select ifnull(sum(student_subscription_number),0) + ifnull(sum(teacher_subscription_number),0) from wf_textbook_subscription_item a where a.wf_textbook_subscription_id = t.id) as sum")
                .select(WfTextbookSubscription.class,x -> VoToColumnUtil.fieldsToColumns(WfTextbookSubscriptionPageVo.class).contains(x.getProperty()))
                .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookSubscription::getBaseSemesterId)
                .eq(dto.getBaseSemesterId() != null && dto.getBaseSemesterId() > 0, WfTextbookSubscription::getBaseSemesterId, dto.getBaseSemesterId())
                .eq(dto.getSubscriptionMethod() != null && dto.getSubscriptionMethod() > 0, WfTextbookSubscription::getSubscriptionMethod, dto.getSubscriptionMethod())
                .orderByDesc(WfTextbookSubscription::getCreateDate)
        ;
        IPage<WfTextbookSubscriptionPageVo> page = wfTextbookSubscriptionService.selectJoinListPage(ConventPage.getPage(dto),WfTextbookSubscriptionPageVo.class, queryWrapper);
        PageOutput<WfTextbookSubscriptionPageVo> pageOutput = ConventPage.getPageOutput(page, WfTextbookSubscriptionPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/baseclass-page")
    @ApiOperation(value="征订班级列表(分页)")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<PageOutput<BaseclassPageVo>> baseclassPage(@Valid BaseclassPageDto dto){
        if(dto.getClassIds() == null || dto.getClassIds().equals("")){
            return RT.ok(null);
        }
        String classIds = dto.getClassIds();
        String[] classIdArr = classIds.split(",");
        List<String> classIdList = Arrays.asList(classIdArr);
        MPJLambdaWrapper<BaseClass> baseClassMPJLambdaWrapper = new MPJLambdaWrapper<>();
        baseClassMPJLambdaWrapper
                .selectAs(BaseGrade::getName, BaseclassPageVo::getGradeIdCn)
                .selectAs(XjrUser::getName, BaseclassPageVo::getTeacherIdCn)
                .selectAs(BaseClassMajorSet::getTotalStudent, BaseclassPageVo::getTotalStudent)
                .select(BaseClass.class,x -> VoToColumnUtil.fieldsToColumns(BaseclassPageVo.class).contains(x.getProperty()))
                .leftJoin(BaseGrade.class, BaseGrade::getId, BaseClass::getGradeId)
                .leftJoin(XjrUser.class, XjrUser::getId, BaseClass::getTeacherId)
                .leftJoin(BaseClassMajorSet.class, BaseClassMajorSet::getClassId, BaseClass::getId)
                .in(BaseClass::getId, classIdList)
                ;
        IPage<BaseclassPageVo> baseclassPageVos = baseClassService.selectJoinListPage(ConventPage.getPage(dto), BaseclassPageVo.class, baseClassMPJLambdaWrapper);
        PageOutput<BaseclassPageVo> pageOutput = ConventPage.getPageOutput(baseclassPageVos, BaseclassPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/history-list")
    @ApiOperation(value="教材教辅征订历史列表(分页)")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<List<TextbookSubscriptionHistoryListVo>> historyList(@Valid TextbookSubscriptionHistoryListDto dto){

        MPJLambdaWrapper<WfTextbookSubscription> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper
                .selectSum(WfTextbookSubscriptionItem::getStudentSubscriptionNumber, TextbookSubscriptionHistoryListVo::getStudentSubscriptionNumber)
                .selectSum(WfTextbookSubscriptionItem::getTeacherSubscriptionNumber, TextbookSubscriptionHistoryListVo::getTeacherSubscriptionNumber)
                .selectAs(WfTextbookSubscription::getCreateDate, TextbookSubscriptionHistoryListVo::getCreateDate)
                .rightJoin(WfTextbookSubscriptionItem.class, WfTextbookSubscriptionItem::getWfTextbookSubscriptionId, WfTextbookSubscription::getId)
                .eq(WfTextbookSubscriptionItem::getTextbookId, dto.getTextbookId())
                .eq(WfTextbookSubscription::getBaseSemesterId, dto.getBaseSemesterId())
                .groupBy("t.id,t1.textbook_id")
        ;
        List<TextbookSubscriptionHistoryListVo> list = wfTextbookSubscriptionService.selectJoinList(TextbookSubscriptionHistoryListVo.class, queryWrapper);
        return RT.ok(list);
    }

    @GetMapping(value = "/instockroom-list")
    @ApiOperation(value="教材教辅征订入库列表")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<List<TextbookInstockroomListVo>> instockroomList(@Valid TextbookInstockroomListDto dto){
        List<TextbookInstockroomListVo> list =  wfTextbookSubscriptionService.instockroomList(dto);
        return RT.ok(list);
    }

    @PostMapping(value = "/instockroom")
    @ApiOperation(value="入库")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<Boolean> instockroom(@Valid @RequestBody  List<TextbookInstockroomDto> dtos){
        return RT.ok(wfTextbookSubscriptionService.instockroom(dtos));
    }

    @GetMapping(value = "/info")
    @ApiOperation(value="根据id查询教材教辅征订信息")
    @SaCheckPermission("wftextbooksubscription:detail")
    public RT<WfTextbookSubscriptionVo> info(@Valid WfTextbookSubscriptionDto dto){
        WfTextbookSubscriptionVo wfTextbookSubscriptionVo = wfTextbookSubscriptionService.getInfo(dto);
        if (wfTextbookSubscriptionVo == null) {
           return RT.error("找不到此数据！");
        }
        return RT.ok(wfTextbookSubscriptionVo);
    }


    @PostMapping
    @ApiOperation(value = "新增教材教辅征订")
    @SaCheckPermission("wftextbooksubscription:add")
    public RT<Boolean> add(@Valid @RequestBody AddWfTextbookSubscriptionDto dto){
        WfTextbookSubscription wfTextbookSubscription = BeanUtil.toBean(dto, WfTextbookSubscription.class);
        boolean isSuccess = wfTextbookSubscriptionService.add(wfTextbookSubscription);
    return RT.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改教材教辅征订")
    @SaCheckPermission("wftextbooksubscription:edit")
    public RT<Boolean> update(@Valid @RequestBody UpdateWfTextbookSubscriptionDto dto){

        WfTextbookSubscription wfTextbookSubscription = BeanUtil.toBean(dto, WfTextbookSubscription.class);
        return RT.ok(wfTextbookSubscriptionService.update(wfTextbookSubscription));

    }

    @PutMapping("/alteration")
    @ApiOperation(value = "变更")
    @SaCheckPermission("wftextbooksubscription:edit")
    public RT<Boolean> alteration(@Valid @RequestBody UpdateWfTextbookSubscriptionItemDto dto){
        return RT.ok(wfTextbookSubscriptionService.alteration(dto));
    }


    @PutMapping(value = "/change-status")
    @ApiOperation(value = "修改教材教辅征订状态")
    @SaCheckPermission("wftextbooksubscription:edit")
    public RT<Boolean> changeStatus(@Valid @RequestBody UpdateWfTextbookSubscriptionDto dto){
        return RT.ok(wfTextbookSubscriptionService.changeStatus(dto));
    }

    @DeleteMapping
    @ApiOperation(value = "删除教材教辅征订")
    @SaCheckPermission("wftextbooksubscription:delete")
    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
        return RT.ok(wfTextbookSubscriptionService.delete(ids));

    }

    @GetMapping("/subscription-export-query")
    @ApiOperation(value = "导出")
    public ResponseEntity<byte[]> exportData(@Valid WfTextbookSubscriptionPageDto dto, @RequestParam(defaultValue = "false") Boolean isTemplate) {
        List<WfTextbookSubscriptionPageVo> customerList = isTemplate != null && isTemplate ? new ArrayList<>() : ((PageOutput<WfTextbookSubscriptionPageVo>) page(dto).getData()).getList();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, WfTextbookSubscriptionPageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);

        return RT.fileStream(bot.toByteArray(), "WfTextbookSubscription" + ExcelTypeEnum.XLSX.getValue());
    }
    
    @PostMapping("/textbook-subscription-export-query")
    @ApiOperation(value = "教材征订条件导出")
    public ResponseEntity<byte[]> textbookSubscriptionExportQuery(@Valid @RequestBody TextbookSubscriptionExportQueryListDto dto) {
//    @GetMapping("/textbook-subscription-export-query")
//    @ApiOperation(value = "教材征订条件导出")
//    public ResponseEntity<byte[]> textbookSubscriptionExportQuery(@Valid TextbookSubscriptionExportQueryListDto dto) {
        List<TextbookSubscriptionExportQueryListVo> customerList = wfTextbookSubscriptionService.textbookSubscriptionExportQuery(dto);
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, TextbookSubscriptionExportQueryListVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);

        return RT.fileStream(bot.toByteArray(), "TextbookSubscription" + ExcelTypeEnum.XLSX.getValue());
    }

    @PostMapping("/instockroom-excel-import")
    @ApiOperation(value = "教材征订入库数量导入")
    public RT<String> excelImport(@RequestParam("file") MultipartFile file,  @RequestParam(value = "wfTextbookSubscriptionId") Long wfTextbookSubscriptionId) throws IOException {
        InputStream inputStream = file.getInputStream();
        return RT.ok(wfTextbookSubscriptionService.excelImport(inputStream, wfTextbookSubscriptionId));
    }
}