package com.wms.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms.annotation.MyLog;
import com.wms.constants.enums.ResponseCode;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.GoodsDto;
import com.wms.entity.app.dto.PageDto;
import com.wms.entity.app.request.GoodsQuery;
import com.wms.entity.app.vo.GoodsVo;
import com.wms.entity.table.Goods;
import com.wms.service.GoodsService;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.wms.utils.StringUtils.convertJsonString;

/**
 * WMS物料控制类
 *
 * @author 梁州
 * &#064;date  2023/3/9
 */
@Controller
@CrossOrigin
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/wms/goods")
public class GoodsController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 物料服务
     */
    private final GoodsService goodsService;
    /**
     * 请求头部信息
     */
    private final HttpServletRequest servletRequest;

    /**
     * 查找所有物料
     */
    @PostMapping("/getGoodsInfoByPage")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getGoodsInfoByPage(@RequestBody GoodsQuery goodsQuery) {
        logger.info("接收到查询物料数据请求：{}，请求ip：{}", convertJsonString(goodsQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            Page<Goods> page = goodsQuery.toMpPage();
            Page<Goods> goodsPage = goodsService.page(page, new LambdaQueryWrapper<Goods>()
                    .like(StringUtils.isNotEmpty(goodsQuery.getGoodsId()), Goods::getGoodsId, goodsQuery.getGoodsId())
                    .like(StringUtils.isNotEmpty(goodsQuery.getGoodsName()), Goods::getGoodsName, goodsQuery.getGoodsName()));

            PageDto<GoodsVo> pageDto = PageDto.of(goodsPage, goods -> BeanUtil.copyProperties(goods, GoodsVo.class));
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询成功");
            response.setReturnData(pageDto);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询物料信息发生异常");
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询物料发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 更新物料信息
     *
     * @param goodsQuery 物料信息
     * @return 结果
     */
    @PostMapping("/updateGoodsInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新物料信息", logMethod = "updateGoodsInfo")
    public String updateGoodsInfo(@RequestBody GoodsQuery goodsQuery) {
        logger.info("接收到更新物料信息请求：{}，请求ip：{}", convertJsonString(goodsQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(goodsQuery.getGoodsId())) {// 物料编码为空，不执行
                logger.error("请求更新的物料编号为空");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求更新的物料编号为空");
                return convertJsonString(rsp);
            }
            if (goodsService.update(BeanUtil.copyProperties(goodsQuery, Goods.class),
                    new LambdaUpdateWrapper<Goods>().eq(Goods::getGoodsId, goodsQuery.getGoodsId()))) {
                // 返回成功
                logger.info("更新物料信息成功");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("更新物料信息成功");
            } else {
                logger.error("更新物料信息失败");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("更新物料信息失败");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("更新物料信息发生异常：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("更新物料信息发生异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 查询物料信息
     *
     * @param goodsQuery 参数
     * @return 结果
     */
    @PostMapping("/getGoodsInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getGoodsInfo(@RequestBody GoodsQuery goodsQuery) {
        logger.info("接收到查询物料信息请求：{}，请求ip地址：{}", convertJsonString(goodsQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity rsp = new ResponseEntity();
        try {
            LambdaQueryWrapper<Goods> goodsLambdaQueryWrapper = new LambdaQueryWrapper<Goods>()
                    .eq(StringUtils.isNotEmpty(goodsQuery.getGoodsId()), Goods::getGoodsId, goodsQuery.getGoodsId())
                    .eq(StringUtils.isNotEmpty(goodsQuery.getGoodsName()), Goods::getGoodsName, goodsQuery.getGoodsName());

            List<GoodsVo> goodsList = BeanUtil.copyToList(goodsService.list(goodsLambdaQueryWrapper), GoodsVo.class);
            // 返回成功
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询物料信息成功");
            rsp.setReturnData(goodsList);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 返回其他异常
            logger.error("查询物料信息发生错误：{}", e.getMessage());
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("查询物料发生异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 自动补全物料编码信息---根据物料编号查询物料信息
     *
     * @param goodsQuery 参数
     * @return 结果
     */
    @PostMapping("/getGoodsInfoByGoodsId")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getGoodsInfoByGoodsId(@RequestBody GoodsQuery goodsQuery) {
        ResponseEntity rsp = new ResponseEntity();
        try {
            LambdaQueryWrapper<Goods> goodsLambdaQueryWrapper = new LambdaQueryWrapper<Goods>()
                    .select(Goods::getGoodsId, Goods::getGoodsName)
                    .like(StringUtils.isNotEmpty(goodsQuery.getGoodsId()), Goods::getGoodsId, goodsQuery.getGoodsId());
            List<GoodsVo> goodsList = BeanUtil.copyToList(goodsService.list(goodsLambdaQueryWrapper), GoodsVo.class);
            // 返回成功
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询物料信息成功");
            rsp.setReturnData(goodsList);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 返回其他异常
            logger.error("查询物料信息发生错误：{}", e.getMessage());
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("查询物料发生异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 删除当前物料信息
     *
     * @param goodsQuery 待删除的物料
     * @return 结果
     */
    @PostMapping("/deleteGoodsInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "删除物料信息", logMethod = "deleteGoodsInfo")
    public String deleteVehicle(@RequestBody GoodsQuery goodsQuery) {
        logger.info("接收到删除物料信息请求：{}，请求ip地址：{}", convertJsonString(goodsQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(goodsQuery.getGoodsId())) {// 物料编码为空，不做处理
                logger.error("请求删除的物料编码为空");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求删除的物料编码为空");
                return convertJsonString(rsp);
            }
            if (goodsService.remove(new LambdaQueryWrapper<Goods>().eq(Goods::getGoodsId, goodsQuery.getGoodsId()))) {
                logger.info("删除物料信息成功");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("删除物料信息成功");
            } else {
                // 返回其他异常
                logger.error("删除物料信息失败");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("删除物料信息失败");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("删除物料信息发生异常：{}", e.getMessage());
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("删除物料信息发生异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 生成测试物料数据
     *
     * @param goodsQuery 物料
     * @return 结果
     */
    @PostMapping("/genGoods")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "生成物料表", logMethod = "genGoods")
    public String genGoods(@RequestBody GoodsQuery goodsQuery) {
        // 9*64*22
        logger.info("生成测试物料：{}，请求ip地址：{}", convertJsonString(goodsQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            List<Goods> goodsList = new ArrayList<>();
            for (int i = 1; i <= 250; i++) {
                Goods goods = new Goods();
                goods.setGoodsId("ASRS" + StringUtils.padLeft(String.valueOf(i), 6, "0"));
                goods.setGoodsName("测试物料" + StringUtils.padLeft(String.valueOf(i), 6, "0"));
                goods.setGoodsType("直接物料");
                goods.setGoodsUnit("PC");
                goods.setProviderType("CLC");
                goods.setWeight(BigDecimal.ONE);
                goods.setWeightUnit("KG");
                goods.setQuantityPerBox(BigDecimal.valueOf(20));
                goods.setUnpackingType("套袋子");
                goods.setVehicleType("FC01");
                goods.setVehicleTypeDescription("822整体1个");
                goods.setGoodsInVehicleType("CLC一箱一料");
                goods.setFeedingType("PULL");
                goods.setLastUpdateTime(LocalDateTime.now());
                goods.setLastUpdateUser("WMS");
                goodsList.add(goods);
            }
            goodsService.saveOrUpdateBatch(goodsList);

            logger.info("生成测试物料成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("生成测试物料成功。");
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("生成测试物料异常：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("生成测试物料异常");
            return convertJsonString(rsp);
        }
    }
}
