package com.wms.controller;

import cn.hutool.core.bean.BeanUtil;
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.PageDto;
import com.wms.entity.app.dto.StandDto;
import com.wms.entity.app.request.StandQuery;
import com.wms.entity.app.vo.StandVo;
import com.wms.entity.app.wcs.DdjStatusChangeRequest;
import com.wms.entity.table.Stand;
import com.wms.service.StandService;
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.util.ArrayList;
import java.util.List;

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

/**
 * 站台控制类
 */
@Controller
@CrossOrigin
@RequestMapping(value = "/wms/stand")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StandController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 站台服务
     */
    private final StandService standService;
    /**
     * 请求头部信息
     */
    private final HttpServletRequest servletRequest;

    /**
     * 查找所有站台信息
     */
    @PostMapping("/getStandsByPage")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getStandsByPage(@RequestBody StandQuery standQuery){
        logger.info("接收到查询站台信息请求：{}，请求ip：{}", convertJsonString(standQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            Page<Stand> page = standQuery.toMpPage();
            LambdaQueryWrapper<Stand> lambdaQueryWrapper = new LambdaQueryWrapper<Stand>()
                    .like(StringUtils.isNotEmpty(standQuery.getStandId()), Stand::getStandId, standQuery.getStandId())
                    .eq(standQuery.getStandStatus() != null, Stand::getStandStatus, standQuery.getStandStatus())
                    .eq(standQuery.getIsLock() != null, Stand::getIsLock, standQuery.getIsLock())
                    .eq(standQuery.getStandType() != null, Stand::getStandType, standQuery.getStandType());
            Page<Stand> standPage = standService.page(page, lambdaQueryWrapper);

            PageDto<StandVo> pageDto = PageDto.of(standPage, stand -> BeanUtil.copyProperties(stand, StandVo.class));
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询站台成功");
            response.setReturnData(pageDto);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询站台发生异常：{}", convertJsonString(e));
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询站台发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 更新站台信息
     *
     * @param request 站台信息
     * @return 结果
     */
    @PostMapping("/updateStandInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新站台信息", logMethod = "updateStandInfo")
    public String updateGoodsInfo(@RequestBody StandQuery request) {
        logger.info("接收到更新站台信息请求：{}，请求ip：{}", convertJsonString(request), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(request.getStandId())) {// 站台id为空，不允许更新
                logger.error("缺少站台号。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少站台号。");
                return convertJsonString(rsp);
            }
            // 更新信息
            LambdaUpdateWrapper<Stand> lambdaUpdateWrapper = new LambdaUpdateWrapper<Stand>()
                    .set(request.getIsLock() != null, Stand::getIsLock, request.getIsLock())
                    .set(request.getStandStatus() != null, Stand::getStandStatus, request.getStandStatus())
                    .set(request.getLastUseTime() != null, Stand::getLastUseTime, request.getLastUseTime())
                    .set(request.getPickVehicleCount() != null, Stand::getPickVehicleCount, request.getPickVehicleCount())
                    .eq(Stand::getStandId, request.getStandId());
            if (standService.update(lambdaUpdateWrapper)) {
                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 request 请求信息
     * @return 结果
     */
    @PostMapping("/ddjStatusChange")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String ddjStatusChange(@RequestBody List<DdjStatusChangeRequest> request) {
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (request == null || request.isEmpty()) {
                // 返回其他异常
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求信息不完整。");
                return convertJsonString(rsp);
            }
            List<Stand> modifiedStands = new ArrayList<>();
            for (DdjStatusChangeRequest tempDDJ : request) {
                // 查询对应的堆垛机
                Stand stand = standService.getOne(new LambdaQueryWrapper<Stand>().eq(Stand::getEquipmentId, tempDDJ.getEquipment())
                        .eq(Stand::getStandType, 3)
                        .last("limit 1"));
                if (stand == null) {
                    continue;
                }
                if (stand.getIsLock() == 0 && tempDDJ.getError() != 0) {
                    stand.setIsLock(1);
                    modifiedStands.add(stand);
                }
                if (stand.getIsLock() == 1 && tempDDJ.getError() == 0) {
                    stand.setIsLock(0);
                    modifiedStands.add(stand);
                }
            }
            if (!modifiedStands.isEmpty()) {
                if (standService.updateBatchById(modifiedStands)) {
                    logger.info("更新堆垛机状态成功: {}", convertJsonString(request));
                    rsp.setCode(ResponseCode.OK.getCode());
                    rsp.setMessage("更新堆垛机状态成功。");
                } else {
                    logger.error("更新堆垛机状态失败: {}", convertJsonString(request));
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("更新堆垛机状态失败。");
                }
            } else {
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("没有堆垛机变更状态。");
            }

            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("堆垛机状态变更发生异常");
            return convertJsonString(rsp);
        }
    }
}
