package com.cf.imes.module.executor.controller.admin.order;

import com.alibaba.fastjson.JSONObject;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.executor.controller.admin.order.vo.order.*;
import com.cf.imes.module.executor.controller.admin.order.vo.product.OrderBodyRespVO;
import com.cf.imes.module.executor.controller.admin.orderParts.vo.OrderPartsRespVO;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.util.ExcelWriterUtil;
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiDataAchieve;
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiTypeRealize;
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.ExcelReadUtil;
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.OrderPlateImportExcelVO;
import io.swagger.v3.oas.annotations.Parameters;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;

import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;

import static com.cf.imes.framework.common.pojo.CommonResult.success;

import com.cf.imes.framework.operatelog.core.annotations.OperateLog;

import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.*;

import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.service.order.OrderService;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.concurrent.ExecutionException;


@Tag(name = "管理后台 - 生产单管理")
@RestController
@RequestMapping("/executor/order")
@Validated
public class OrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private ExcelReadUtil excelReadUtil;

    @Resource
    private ApiDataAchieve apiDataAchieve;

    @Resource
    private ApiTypeRealize apiTypeRealize;


    @PostMapping("/create")
    @Operation(summary = "创建生产单")
    @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
    public CommonResult<Long> createOrder(@Valid @RequestBody OrderSaveReqVO createReqVO) {
        return success(orderService.createOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新生产单")
    @PreAuthorize("@ss.hasPermission('production:manager-list:edit')")
    public CommonResult<Boolean> updateOrder(@Valid @RequestBody OrderSaveReqVO updateReqVO) {
        orderService.updateOrder(updateReqVO);
        return success(true);
    }

    //    删除柜体
    @DeleteMapping("/delete-body")
    @Operation(summary = "删除柜体")
    @Parameters({
            @Parameter(name = "orderId", description = "生产单编号", required = true, example = "1024"),
            @Parameter(name = "bodyIds", description = "柜体编号集合", required = true, example = "1,2")
    })
    @PreAuthorize("@ss.hasPermission('production:manager-list:deleteCabinet')")
    public CommonResult<Boolean> deleteBody(@RequestParam("orderId") Long orderId, @RequestParam("bodyIds") Set<Long> bodyIds) {
        orderService.deleteBodyByOrder(orderId, bodyIds);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "作废")
    @Parameter(name = "orderId", description = "生产单id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('production:manager-list:nullify')")
    public CommonResult<Boolean> deleteOrder(@RequestParam("orderId") Long orderId) {
        orderService.deleteOrder(orderId);
        return success(true);
    }

    @PutMapping("/restore")
    @Operation(summary = "还原")
    @Parameter(name = "orderId", description = "生产单id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('production:manager-list:backOrder')")
    public CommonResult<Boolean> restoreOrder(@RequestBody JSONObject jsonObject) {
        Long orderId = jsonObject.getLong("orderId");
        orderService.restoreOrder(orderId);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得（单个）生产单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<OrderRespVO> getOrder(@RequestParam("id") Long id) {
        OrderDO order = orderService.getOrder(id);
        return success(BeanUtils.toBean(order, OrderRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得生产单分页")
    @PreAuthorize("@ss.hasPermission('productManager:List')")
    public CommonResult<PageResult<OrderRespVO>> getOrderPage(@Valid OrderPageReqVO pageReqVO) {
        PageResult<OrderDO> pageResult = orderService.getOrderPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, OrderRespVO.class));
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入生产单模板")
    @Parameter(name = "value", description = "文件类型", required = true, example = "0")
    public void importTemplate(HttpServletResponse response, @RequestParam("value") String value) {
        orderService.exportTemplate(response, value);
    }

    @GetMapping("/get-room")
    @Operation(summary = "生产单详情-房间和柜体id")
    @Parameter(name = "orderId", description = "生产单编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<List<OrderBodyRespVO>> getRoom(@RequestParam("orderId") Long orderId) {
        List<OrderBodyRespVO> orderBodyMap = orderService.getOrderBody(orderId);
        return success(orderBodyMap);
    }

    @GetMapping("/get-module")
    @Operation(summary = "生产单详情-数量信息")
    @Parameter(name = "orderId", description = "生产单编号", example = "1024")
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<Map<String,List<?>>> getModule(@RequestParam("orderId") Long orderId) {
        Map<String,List<?>> moduleDOList = orderService.getModule(orderId);
        return success(moduleDOList);
    }

    @GetMapping("/get-platesDetails")
    @Operation(summary = "生产单详情-板材详细信息")
    @Parameters({
            @Parameter(name = "orderId", description = "生产单编号", example = "1024"),
            @Parameter(name = "roomId", description = "房间编号", example = "1024"),
            @Parameter(name = "bodyId", description = "柜体编号", example = "1024"),
            @Parameter(name = "groupId", description = "加工组编号", example = "1024"),
            @Parameter(name = "groupName", description = "加工组名称", example = "弧形")
    })
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<List<OrderPlatesDetailReqVO>> platesDetails(@RequestParam("orderId") Long orderId,
                                                                    @RequestParam(value = "roomId", required = false) Long roomId,
                                                                    @RequestParam(value = "bodyId", required = false) Long bodyId,
                                                                    @RequestParam(value = "groupId", required = false) Long groupId,
                                                                    @RequestParam(value = "groupName", required = false) String groupName) {
        List<OrderPlatesDetailReqVO> moduleDOList = orderService.getPlatesDetail(orderId, roomId, bodyId,groupId,groupName);
        return success(moduleDOList);
    }

    @GetMapping("/get-partsDetails")
    @Operation(summary = "生产单详情-配件详细信息")
    @Parameters({
            @Parameter(name = "orderId", description = "生产单编号", example = "1024"),
            @Parameter(name = "roomId", description = "房间编号", example = "1024"),
            @Parameter(name = "bodyId", description = "柜体编号", example = "1024"),
            @Parameter(name = "name", description = "配件名称", example = "1024")
    })
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<List<OrderPartsRespVO>> partsDetails(@RequestParam("orderId") Long orderId,
                                                             @RequestParam(value = "roomId", required = false) Long roomId,
                                                             @RequestParam(value = "bodyId", required = false) Long bodyId,
                                                             @RequestParam(value = "name", required = false) String name) {
        List<OrderPartsRespVO> moduleDOList = orderService.getPartsDetail(orderId, roomId, bodyId, name);
        return success(moduleDOList);
    }

    //    柜体数据获取，需要加上柜体的属性
    @GetMapping("/get-body")
    @Operation(summary = "生产单柜体数据获取")
    @Parameter(name = "orderId", description = "生产单编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<List<OrderBodyRespVO>> getBody(@RequestParam("orderId") Long orderId) {
        return success(BeanUtils.toBean(orderService.getBody(orderId), OrderBodyRespVO.class));
    }

    @GetMapping("getApiData")
    @Operation(summary = "生产单api数据导入新增")
    @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
    public CommonResult<Long> test(@RequestParam(value = "orderNo", required = false, defaultValue = "20230809027818") String orderNo)
            throws InterruptedException, ExecutionException {
//        return success(orderService.importApiData(orderNo));
        Long organId = SecurityFrameworkUtils.getLoginUser().getOrganId();
        String token = apiDataAchieve.getApiToken(organId);
        JSONObject dataPlates = apiDataAchieve.getApiPlateProData(token, orderNo).get();
        JSONObject dataParts = apiDataAchieve.getApiPartsMessage(token, orderNo).get();
        JSONObject dataBody = apiDataAchieve.getApiBodyMessage(token, orderNo).get();
        JSONObject dataGoods = apiDataAchieve.getApiGoodsMessage(token, orderNo).get();
        JSONObject plate = apiDataAchieve.getApiPlateDetailMessage(token, orderNo).get();
        JSONObject dataModule = apiDataAchieve.getApiGroupMessage(token, orderNo).get();
        JSONObject block = apiDataAchieve.getApiBlocksMessage(token, orderNo).get();
        Map<String, List<?>> listMap = apiTypeRealize.apiPlateDataChange(
                dataPlates.getJSONObject("value"),//板件生产信息
                dataParts,// 配件信息
                dataBody, // 柜体信息
                dataGoods, // 商品信息
                plate, // 板件信息
                dataModule,// 加工组信息
                block,// 板材数据
                orderNo); // 原始板编号
        return success(orderService.importApiData(listMap));
    }

    @PostMapping("/importFile")
    @Operation(summary = "生产单文件导入新增")
    @Parameters({
            @Parameter(name = "file", description = "文件", required = true),
            @Parameter(name = "type", description = "文件类型", required = true)
    })
    @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
    @OperateLog(type = EXPORT)
    public void exportTest(@RequestPart("file") MultipartFile file,
                           @RequestParam(value = "type", required = false, defaultValue = "true") Integer type,
                            HttpServletResponse response) throws IOException {

        List<?> list = null;
        OrderDO orderDO = new OrderDO();
        if (type == 0) { //excel
            // 读取文件
            excelReadUtil.setErr(0);
            Map<String, Object> map = excelReadUtil.read(file);
            System.out.println(" map " + map);
            System.err.println(excelReadUtil.isErr());
            // 判断是否读取有误
            if (excelReadUtil.isErr() == -1) { // 文件为空
                ExcelWriterUtil.writeErr(response, "生产单内容为空",orderService.getSavePath()+ "\\"+ "错误文件.xlsx");
                return;
            }else if (excelReadUtil.isErr() > 0) {
                // 返回文件
                System.out.println("(Map<Object, Object>)  " + (Map<Object, Object>) map.get("order")+ " , (List<OrderPlateImportExcelVO>)" +(List<OrderPlateImportExcelVO>) map.get("plate"));
                ExcelWriterUtil.write(response, (Map<Object, Object>) map.get("order"), (List<OrderPlateImportExcelVO>) map.get("plate"),orderService.getSavePath()+ "\\"+ "生产单Excel导入错误导出模板.xlsx");
                return;
            } else {
                // 获取数据
                list = (List<?>) map.get("plate");
                orderDO = excelReadUtil.changeOrderDO((Map<Object, Object>) map.get("order")).setOrderType(0).setStatus(1);
            }
        } else if (type == 1) { // json

        }else if (type == 2) { // xml

        }
        orderService.importExcelData(orderDO,list);
    }

    @GetMapping("/get-goodsList")
    @Operation(summary = "生产单所用板材商品信息")
    @Parameter(name = "orderId", description = "生产单编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
    public CommonResult<List<GoodsDO>> getGoodsList(@RequestParam("orderId") Long orderId) {
        List<GoodsDO> goodsDOS = orderService.getGoodsList(orderId);
        return success(goodsDOS);
    }

    @GetMapping("/uploadFiles")
    @Operation(summary = "导入生产数据文件模板")
    @Parameters({
            @Parameter(name = "file", description = "文件", required = true),
            @Parameter(name = "type", description = "是否强制上传", required = false)
    })
    @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
    public CommonResult<String> uploadOrderType(@RequestPart("file") MultipartFile file,
                                             @RequestParam(value = "type", required = false, defaultValue = "false") Boolean type) {
        return success(orderService.importTemplate(file,type));
    }

    @GetMapping("/printing")
    @Operation(summary = "打印/导出 数据文件")
    @Parameter(name = "type", description = "文件类型", required = true, example = "0")
    @PreAuthorize("@ss.hasPermission('production:manager-list:export')")
    @OperateLog(type = EXPORT)
    public CommonResult<Map<String, Object>> getOrderPrintData(
            @RequestParam("orderId") Long orderId,
            @RequestParam("type") String type,
            HttpServletResponse response) {

        return success(orderService.getPrintDataMap(orderId,type,response));
    }
}