package com.cf.imes.module.executor.controller.admin.manage.plate;

import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate.PlateImportExcelVO;
import com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate.PlatePageReqVO;
import com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate.PlateRespVO;
import com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate.PlateSaveReqVO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateGoodDO;
import com.cf.imes.module.executor.service.manage.plate.PlateExcelListener;
import com.cf.imes.module.executor.service.manage.plate.PlateManageService;
import com.cf.imes.module.executor.util.file.ExcelReadUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
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.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 org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;

import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.IMPORT;

@Tag(name = "管理后台 - 板材库管理")
@RestController
@RequestMapping("/manage/plate")
@Validated
public class PlateManageController {

    @Resource
    private PlateManageService plateService;

    final String IMPORT_TEMPLATE = "板材导入模板.xlsx";

    @PostMapping("/create")
    @Operation(summary = "创建板材信息")
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:create','base:plate:create')")
    public CommonResult<Long> createPlate(@Valid @RequestBody PlateSaveReqVO createReqVO) {
        return success(plateService.createPlate(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新板材信息")
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:update','base:plate:update')")
    public CommonResult<Boolean> updatePlate(@Valid @RequestBody PlateSaveReqVO updateReqVO) {
        plateService.updatePlate(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除板材信息")
    @Parameters({
            @Parameter(name = "id", description = "编号", required = true, example = "1024"),
            @Parameter(name = "organId", description = "板材所属组织ID", example = "1024")
    })
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:delete','base:plate:delete')")
    public CommonResult<Boolean> deletePlate(@RequestParam("id") Long id,
                                             @RequestParam(value = "organId",required = false, defaultValue = "0") Long organId) {
        plateService.deletePlate(id,organId);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得板材信息")
    @Parameters({
            @Parameter(name = "id", description = "编号", required = true, example = "1024"),
            @Parameter(name = "organId", description = "板材所属组织ID", required = true, example = "1024")
    })
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:update','base:plate:update')")
    public CommonResult<PlateRespVO> getPlate(@RequestParam("id") Long id,
                                              @RequestParam("organId") Long organId) {
        PlateGoodDO plate = plateService.getPlate(id, organId);
        return success(BeanUtils.toBean(plate, PlateRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得板材信息分页")
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:query','base:plate:query')")
    public CommonResult<PageResult<PlateRespVO>> getPlatePage(@Valid PlatePageReqVO pageReqVO) {
        PageResult<PlateGoodDO> pageResult = plateService.getPlatePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PlateRespVO.class));
    }

    @GetMapping("/webcad/page")
    @Operation(summary = "webcad获得板材信息分页")
    public CommonResult<PageResult<PlateRespVO>> webCadGetPlatePage(@Valid PlatePageReqVO pageReqVO) {
        PageResult<PlateGoodDO> pageResult = plateService.webCadGetPlatePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PlateRespVO.class));
    }

    @GetMapping("/export")
    @Operation(summary = "导出板材信息")
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:export','base:plate:export')")
    @OperateLog(type = EXPORT)
    public void exportPlateExcel(@Valid PlatePageReqVO pageReqVO,
                                 HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<PlateGoodDO> list = plateService.getPlatePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "板材信息表.xls", "数据", PlateRespVO.class,
                BeanUtils.toBean(list, PlateRespVO.class));
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入用户模板")
    @PreAuthorize("@ss.hasAnyPermissions('system:plate:export-template','base:plate:export-template')")
    public void importTemplate(HttpServletResponse response) throws IOException {
        plateService.exportTemplate(response, "excel_plate_add.xlsx");
    }

    @PostMapping("/import")
    @Operation(summary = "导入板材")
    @Parameters({
            @Parameter(name = "file", description = "Excel 文件", required = true),
            @Parameter(name = "updateSupport", description = "是否支持更新，默认为 false", example = "true"),
            @Parameter(name = "organId", description = "板材所属组织ID")
    })
    @OperateLog(type = IMPORT)
    @PreAuthorize("@ss.hasAnyPermissions('manage:plate:import','base:plate:import')")
    public void importExcel(@RequestParam("file") MultipartFile file,
                                                       @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport,
                                                       @RequestParam(value = "organId") Long organId,
                                                       HttpServletResponse response) throws Exception {
        ExcelReadUtil excelReadUtil = new ExcelReadUtil();
        PlateExcelListener listener = new PlateExcelListener(updateSupport, plateService, organId);
        List<PlateImportExcelVO> list = excelReadUtil.read(file, PlateImportExcelVO.class, listener);

//        判断文件是否导入成功
        if (!excelReadUtil.getFlag())
            ExcelUtils.write(response, IMPORT_TEMPLATE, "板材列表", PlateImportExcelVO.class, list);
        else {
            if (list.isEmpty()){
                PlateImportExcelVO plateImportExcelVO = PlateImportExcelVO.builder().result("导入失败，请保证导入文件中包含板材数据").build();
                list.add(plateImportExcelVO);
                ExcelUtils.write(response, IMPORT_TEMPLATE, "板材列表", PlateImportExcelVO.class, list);
            }else {
                plateService.importPlateList(list, updateSupport, organId);// 成功，批量导入
            }
        }
    }


    @GetMapping("/webcad/all")
    @Operation(summary = "获取全部板材信息")
    public CommonResult<List<PlateRespVO>> webCadGetPlateAll() {
        List<PlateGoodDO> list = plateService.getPlateAll();
        return success(BeanUtils.toBean(list, PlateRespVO.class));
    }

}