package com.jsh.erp.controller.pda;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jsh.erp.base.AjaxResult;
import com.jsh.erp.base.BaseController;
import com.jsh.erp.base.TableDataInfo;
import com.jsh.erp.datasource.entities.DepotHead;
import com.jsh.erp.datasource.entities.Supplier;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.pda.dto.PDADepotHeadDTO;
import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingDTO;
import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
import com.jsh.erp.datasource.pda.vo.*;
import com.jsh.erp.datasource.vo.SpinnerVO;
import com.jsh.erp.datasource.vo.TaskStocktakingVO;
import com.jsh.erp.datasource.vo.TreeNode;
import com.jsh.erp.query.LambdaQueryWrapperX;
import com.jsh.erp.service.*;
import com.jsh.erp.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping(value = "/pda")
@Api(tags = {"PDA接口"})
public class PdaController extends BaseController {

    @Resource
    private DepotHeadService depotHeadService;

    @Resource
    private DepotItemService depotItemService;

    @Resource
    private SupplierService supplierService;

    @Resource
    private MaterialService materialService;

    @Resource
    private TaskStocktakingService taskStocktakingService;

    @Resource
    private TaskStocktakingItemService taskStocktakingItemService;

    @Resource
    private UserService userService;

    @Resource
    private MaterialCategoryService materialCategoryService;

    @Resource
    private MaterialExtendService materialExtendService;

    @Resource
    private ApkVersionService apkVersionService;

    @Resource
    private DepotService depotService;

    @Resource
    private MaterialBatchService materialBatchService;

    /**
     * 采购入库
     * @return
     */
    @PostMapping ("/purchaseInventory")
    @ApiOperation(value = "采购入库")
    public TableDataInfo purchaseInventory(@RequestBody PDADepotHeadDTO pdaDepotHeadDTO) {
        pdaDepotHeadDTO.setSubType("采购订单");
        startPage();
        List<PDADepotHeadVO> pdaDepotHeadVOList = depotHeadService.pdaList(pdaDepotHeadDTO);
        return getDataTable(pdaDepotHeadVOList);
    }

    @PostMapping("/saleOrder")
    @ApiOperation(value = "检货任务")
    public TableDataInfo saleOrder(@RequestBody PDADepotHeadDTO pdaDepotHeadDTO) {
        pdaDepotHeadDTO.setSubType("销售订单");
        startPage();
        List<PDADepotHeadVO> pdaDepotHeadVOList = depotHeadService.pdaList(pdaDepotHeadDTO);
        return getDataTable(pdaDepotHeadVOList);
    }

    @ApiModelProperty(value = "订单详情")
    @GetMapping("/orderInfo/{id}")
    public AjaxResult orderInfo(@PathVariable("id") Long id){
        DepotHead depotHead = depotHeadService.getOne(new LambdaQueryWrapperX<DepotHead>().eq(DepotHead::getId, id));
        if (depotHead.getOrganId() != null) {
            depotHead.setSupplierName(supplierService.getOne(new LambdaQueryWrapperX<Supplier>().eq(Supplier::getId, depotHead.getOrganId())).getSupplier());
        }
        if (depotHead.getCreator() != null) {
            depotHead.setCreateName(userService.getOne(new LambdaQueryWrapperX<User>().eq(User::getId, depotHead.getCreator())).getUsername());
        }
        if (depotHead.getOperId() != null) {
            depotHead.setOperName(userService.getOne(new LambdaQueryWrapperX<User>().eq(User::getId, depotHead.getOperId())).getUsername());
        }
        return AjaxResult.success(depotHead);
    }

    @GetMapping("/orderDetail/{id}")
    @ApiOperation("订单明细")
    public TableDataInfo orderDetail(@PathVariable("id") Long id) throws Exception {
        startPage();
        List<PDADepotItemVO> list = depotItemService.pdaList(id);
        return getDataTable(list);
    }

    @ApiOperation("订单开始处理")
    @GetMapping("/orderStartHandle/{id}")
    public AjaxResult orderStartHandle(@PathVariable("id") Long id) {
        depotHeadService.update(new UpdateWrapper<DepotHead>().set("status", "4").eq("id", id));
        return AjaxResult.success();
    }

    @ApiOperation("商品详情")
    @GetMapping("/materialDetail/{id}")
    public AjaxResult materialDetail(@PathVariable("id") Long id) throws Exception {
        return AjaxResult.success(depotItemService.pdaDetail(id));
    }

    @ApiOperation("商品库存详情")
    @GetMapping("/materialDepotDetail/{type}/{materialId}")
    public TableDataInfo materialDepotDetail(@PathVariable("type") String type, @PathVariable("materialId") Long materialId) {
        startPage();
        if ("in".equals(type)) {
            type = "入库";
        } else {
            type = "出库";
        }
        List<PDADepotItemVO> list = depotItemService.materialDepotDetail(type, materialId);
        return getDataTable(list);
    }

    @ApiOperation("盘点任务列表")
    @PostMapping("/taskStocktakingList")
    public TableDataInfo taskStocktakingList(@RequestBody PDATaskStocktakingDTO pdaTaskStocktakingDTO) {
        startPage();
        List<PDATaskStocktakingVO> list = taskStocktakingService.pdaList(pdaTaskStocktakingDTO.getNumber(), pdaTaskStocktakingDTO.getStatus(), pdaTaskStocktakingDTO.getDepotId());
        return getDataTable(list);
    }

    @ApiOperation(value = "盘点任务详情-商品列表")
    @PostMapping("/taskStocktakingItemList")
    public TableDataInfo taskStocktakingItemList(@RequestBody PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO){
        startPage();
        List<PDATaskStocktakingItemVO> list = taskStocktakingService.pdaItemList(pdaTaskStocktakingItemDTO);
        return getDataTable(list);
    }

    @ApiOperation("盘点任务详情")
    @GetMapping("/taskStocktakingDetail/{taskId}")
    public AjaxResult taskStocktakingDetail(@PathVariable("taskId") Long taskId) throws Exception{
        TaskStocktakingVO taskStocktakingVO = taskStocktakingService.pdaDetail(taskId);
        return AjaxResult.success(taskStocktakingVO);
    }

    /**
     * 获取商品类别树数据
     * @Param:
     * @return
     */
    @ApiOperation(value = "获取商品类别树数据")
    @GetMapping(value = "/getMaterialCategoryTree")
    public JSONArray getMaterialCategoryTree(@RequestParam("id") Long id) throws Exception{
        JSONArray arr=new JSONArray();
        List<TreeNode> materialCategoryTree = materialCategoryService.getMaterialCategoryTree(id);
        if(materialCategoryTree!=null&&materialCategoryTree.size()>0){
            for(TreeNode node:materialCategoryTree){
                String str= JSON.toJSONString(node);
                JSONObject obj=JSON.parseObject(str);
                arr.add(obj) ;
            }
        }
        return arr;
    }

    @ApiOperation("开始任务")
    @GetMapping("/startTask/{id}")
    public AjaxResult startTask(@PathVariable("id") Long id){
        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>()
                .set("task_status", 2)
                .eq("id", id));
        return AjaxResult.success();
    }

    @ApiOperation("任务完成")
    @GetMapping("/taskComplete/{id}")
    public AjaxResult taskComplete(@PathVariable("id") Long id) throws Exception {
        User currentUser = userService.getCurrentUser();
        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 3)
                .set("oper_time", new Date())
                .set("oper_by", currentUser.getId())
                .eq("id", id));
        return AjaxResult.success();
    }

    @ApiOperation("盘点")
    @PostMapping("/stocktaking")
    public AjaxResult stocktaking(@RequestBody TaskStocktakingItem taskStocktakingItem) throws Exception{
        User currentUser = userService.getCurrentUser();
        MaterialBatch materialBatch = materialBatchService.getById(taskStocktakingItem.getMaterialItemId());
        if (materialBatch == null) {
            return AjaxResult.error("商品信息不存在");
        }
        UpdateWrapper<TaskStocktakingItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", taskStocktakingItem.getId())
                .set("creator", currentUser.getId())
                .set("oper_time", new Date());
        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getNewInventory())) {
            updateWrapper.set("new_inventory", taskStocktakingItem.getNewInventory());
            BigDecimal subtract = taskStocktakingItem.getNewInventory().subtract(materialBatch.getInventory());
            updateWrapper.set("difference_count", subtract);
            //差异数量，设置盘点状态为1.未盘，2.盘盈，3.盘亏 4.无差异
            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                updateWrapper.set("status", 2);
            } else if (subtract.compareTo(BigDecimal.ZERO) < 0) {
                updateWrapper.set("status", 3);
            } else {
                updateWrapper.set("status", 4);
            }
        }
        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getNewPosition())) {
            updateWrapper.set("new_position", taskStocktakingItem.getNewPosition());
        }
        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getDifferenceCount())) {
            updateWrapper.set("difference_count", taskStocktakingItem.getDifferenceCount());
        }
        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getDifferenceReason())){
            updateWrapper.set("difference_reason", taskStocktakingItem.getDifferenceReason());
        }
        taskStocktakingItemService.update(updateWrapper);
        return AjaxResult.success();
    }

    @ApiOperation("负责人下拉列表")
    @GetMapping("/creatorSpinnerList/{taskId}")
    public AjaxResult creatorSpinnerList(@PathVariable("taskId") Long taskId) {
        List<SpinnerVO> spinnerVOList = taskStocktakingItemService.creatorSpinnerList(taskId);
        return AjaxResult.success(spinnerVOList);
    }

    /**
     * PDA订单提交
     */
    @PostMapping ("/orderSubmit")
    @ApiOperation(value = "订单提交")
    public AjaxResult orderSubmit(@RequestBody PDADepotHeadDTO pdaDepotHeadDTO) {
        try {
            depotHeadService.pdaOrderSubmit(pdaDepotHeadDTO);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    @PostMapping("/inventoryInquiry")
    @ApiOperation("存货查询-商品存货查询")
    public TableDataInfo inventoryInquiry(@RequestBody PDAInventoryDTO pdaInventoryDTO){
        if (StringUtil.isNotEmpty(pdaInventoryDTO.getPosition())){
            pdaInventoryDTO.setMaterialIds(materialService.selectMaterialIdByPosition(pdaInventoryDTO.getPosition()));
        }
        //查询类型id的子类型
        pdaInventoryDTO.setCategoryIds(materialService.selectCategoryIds(pdaInventoryDTO.getCategoryId()));
        startPage();
        List<PDADepotItemVO> list = materialService.inventoryInquiry(pdaInventoryDTO);
        return getDataTable(list);
    }

    @ApiOperation("存货查询-库位树查询")
    @GetMapping("/inventoryPositionTree")
    public AjaxResult inventoryPositionTree(@RequestParam("depotId") Long depotId) throws Exception {
        return AjaxResult.success(materialService.selectPosition(depotId));
    }

    @ApiOperation("存货查询-类型树查询")
    @GetMapping("/inventoryTypeTree")
    public AjaxResult inventoryTypeTree() throws Exception {
        return AjaxResult.success(materialCategoryService.getMaterialCategoryTree(null));
    }

    @ApiOperation("仓库下拉框")
    @GetMapping("/depotSpinnerList")
    public AjaxResult depotSpinnerList() {
        return AjaxResult.success(depotService.depotSpinnerList());
    }

    @ApiOperation("下载安装包")
    @PostMapping("/downloadApk")
    public ResponseEntity downloadApk(@RequestBody ApkVersion apkVersion, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 将文件路径转换为 Path 对象
        Path path = Paths.get(apkVersion.getUrl()).toAbsolutePath().normalize();
        File file = path.toFile();
        String fileUrl = apkVersion.getUrl();
        long size = Files.size(path);
        response.setHeader("Content-Length",size+"");
        // 检查文件是否存在
        if (!file.exists() || !file.isFile()) {
            return null;
        }
        InputStream inputStream = null;
        OutputStream outputStream = null;
        inputStream = new BufferedInputStream(new FileInputStream(fileUrl));
        outputStream = response.getOutputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, len);
        }
        response.flushBuffer();
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentLength(size);
        return new ResponseEntity<>(null, headers, HttpStatus.OK);
    }

    @ApiOperation("查询版本信息")
    @GetMapping("/selectVersion")
    public AjaxResult selectVersion() {
        ApkVersion apkVersion = apkVersionService.getOne(new LambdaQueryWrapperX<ApkVersion>().orderByDesc(ApkVersion::getId).last("limit 1"));
        return AjaxResult.success(apkVersion);
    }


    @ApiOperation("查询商品打印信息")
    @GetMapping("/printMaterial")
    public AjaxResult printMaterial(@RequestParam("id") Long id) {
        PDAPrintVo pdaPrintVo = depotItemService.pdaPrintMaterial(id);
        return AjaxResult.success(pdaPrintVo);
    }

}
