package com.sw.mes.yb.accessory.service.impl;


import com.alibaba.fastjson.JSON;
import com.sw.mes.base.factory.init.service.FactoryModelService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.core.api.auth.AuthFeignClient;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.dto.auth.UserDto;
import com.sw.mes.core.dto.store.StoreOperatorDetailDto;
import com.sw.mes.core.dto.store.StoreOperatorDto;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.material.entity.Unit;
import com.sw.mes.core.enums.StoreBusinessTypeEnum;
import com.sw.mes.core.enums.StoreOperatorTypeEnum;
import com.sw.mes.core.response.Result;
import com.sw.mes.yb.accessory.dao.AccessoryReturnDao;
import com.sw.mes.yb.accessory.dto.AccessoryReturnDto;
import com.sw.mes.yb.accessory.dto.EquipmentAccessoryListByPageDto;
import com.sw.mes.yb.accessory.dto.ReturnCreateDto;
import com.sw.mes.yb.accessory.entity.*;
import com.sw.mes.yb.accessory.service.*;
import com.sw.mes.yb.accessory.vo.RequestWmsVo;
import com.sw.mes.yb.accessory.vo.ReturnApplyVo;
import com.sw.mes.yb.accessory.vo.ToMaterialApplyVo;
import com.sw.mes.yb.accessory.vo.WmsResult;
import com.sw.mes.yb.production.entity.EquipmentExtendState;
import com.sw.mes.yb.production.service.EquipmentExtendStateService;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@Service
@Transactional
public class AccessoryReturnServiceImpl extends BaseServiceImpl<AccessoryReturn> implements AccessoryReturnService {
    AccessoryReturnDao dao;
	@Autowired
    public void setDao(AccessoryReturnDao dao) {
        super.setBaseDao(dao);
        this.dao=dao;
    }

    @Autowired
    private EquipmentAccessoryService equipmentAccessoryService;



	@Autowired
    //private UserService userService;
    private AuthFeignClient authFeignClient;

	@Autowired
    private AccessoryApplyService accessoryApplyService;

	@Autowired
    private RestTemplate restTemplate;

	@Autowired
    private AccessoryLogService accessoryLogService;

	@Autowired
    private AccessoryReturnService accessoryReturnService;

    @Autowired
    private EquipmentExtendStateService equipmentExtendStateService;

    @Autowired
    private AccessoryDiscardService accessoryDiscardService;

    @Autowired
    private StoreFeignClients storeFeignClients;

    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private AccessoryMaterialOutService accessoryMaterialOutService;

//    @Value("${wms.url}")
    private String wmsUrl;

    private static final String returnWms = "api/YC6MES/otherinteraction"; //TODO
    /**
     *
     * param id 热场申请id
     * param equipmentAccessoryId 对应热场监控id
     * param reason 退库原因
     * param num 退库数量
     * param equipmentAccessoryUseTime 已使用寿命
     * @description 热场寿命监控-退库按钮传equipmentAccessoryId、reason、num、equipmentAccessoryUseTime
     *              热场申请记录-退库按钮传id、equipmentAccessoryId、reason、num、equipmentAccessoryUseTime
     */
    @Override
    public void accessoryReturn(ReturnCreateDto returnCreateDto) {
        EquipmentAccessory accessory = equipmentAccessoryService.get(returnCreateDto.getEquipmentAccessoryId().longValue());
        if (accessory == null) {
            throw new RuntimeException("监控信息不存在！");
        }

        if (accessory.getNum() == 0){
            throw new RuntimeException("当前监控信息已解绑，无法退库！");
        }

        if (accessory.getApplyButton() == 1){
            throw new RuntimeException("已发起退库，请发起申请。");
        }

        Integer num = returnCreateDto.getNum();

        if (returnCreateDto.getId() != null){   //针对热场申请记录里的退库操作
            AccessoryApply accessoryApply = accessoryApplyService.get(returnCreateDto.getId().longValue());
            if (accessoryApply != null){
                num = accessoryApply.getNum();
                AccessoryMaterialOut accessoryMaterialOut = accessoryMaterialOutService.findByPickNo(accessoryApply.getPickNo());
                if (accessoryMaterialOut != null){
                    if (!accessoryMaterialOut.getUniqueCode().equals(accessory.getGoodsCode())){
                        throw new RuntimeException("当前记录已过期;原因：当前设备监控辅料不来自于该条申请！");
                    }
                }
            }
        }


        if (num != null){
            if (num < 0){
                throw new RuntimeException("数量不得小于0");
            }
            if (num > accessory.getNum()){
                throw new RuntimeException("退库数量大于库存量");
            }
        }

        //生成退库记录
        AccessoryReturn accessoryReturn = new AccessoryReturn();
        accessoryReturn.setApplyDate(new Date());
        accessoryReturn.setApplyUser(BaseContextHandler.getUsername());
        EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(accessory.getEquipment().getCode());
        if (equipmentExtendState != null){
            accessoryReturn.setUserClassNo(equipmentExtendState.getClassNo());
            accessoryReturn.setUserTeamGroup(equipmentExtendState.getTeamGroup());
        }
        accessoryReturn.setBatchNo(accessory.getBatchNo());
        accessoryReturn.setEquipment(accessory.getEquipment());
        accessoryReturn.setGoodsCode(accessory.getGoodsCode());
        accessoryReturn.setMaterial(accessory.getMaterial());
        accessoryReturn.setReason(returnCreateDto.getReason());
        accessoryReturn.setState(EnumValues.AccessoryReturnStatus.CONFIRMED.getKey());
        accessoryReturn.setEquipmentAccessory(accessory);
        EquipmentAccessoryListByPageDto detail = equipmentAccessoryService.getDetail(accessory.getId());
        accessoryReturn.setUseTime(new BigDecimal(Optional.ofNullable(detail).map(EquipmentAccessoryListByPageDto::getUseTime).map(Object::toString).orElse("0")));//detail.getUseTime().toString()
        Result<UserDto> user = authFeignClient.getUserById(BaseContextHandler.getUserID());
        if (user!=null && user.getData()!=null){
        accessoryReturn.setApplyWorkNo(user.getData().getWorkNo());}
        accessoryReturn.setOrderNum(getOrderNum(Optional.of(accessory).map(EquipmentAccessory::getEquipment).map(Equipment::getCode).orElse("")));
        if (num == null){
            accessoryReturn.setNum(accessory.getNum());
        }else {
            accessoryReturn.setNum(num);
        }
        accessoryReturn.setEngraving(accessory.getEngraving());
        accessoryReturn.setCarbonFelt(accessory.getCarbonFelt());
        accessory.setButtonStatus(0);
        accessory.setApplyButton(1);
        accessory.setBind(0);
        accessory.setNum(accessory.getNum() - accessoryReturn.getNum());
        if(accessory.getNum() - accessoryReturn.getNum() == 0){
            accessory.setDeleted(1);
        }
        equipmentAccessoryService.saveOrUpdate(accessory);
        saveOrUpdate(accessoryReturn);

        //生成报废记录
//        AccessoryDiscard accessoryDiscard = new AccessoryDiscard();
//        accessoryDiscard.setAccessory(accessory);
//        accessoryDiscard.setEquipment(accessory.getEquipment());
//        accessoryDiscard.setMaterial(accessory.getMaterial());
//        accessoryDiscard.setUseTime(new BigDecimal(Optional.ofNullable(detail).map(EquipmentAccessoryListByPageDto::getUseTime).map(Object::toString).orElse("0")));
//        accessoryDiscard.setOperateTime(accessory.getOperateDate());
//        accessoryDiscard.setAccessoryReturn(accessoryReturn);
//        accessoryDiscard.setGoodsCode(accessory.getGoodsCode());
//        accessoryDiscard.setFactory(accessory.getFactory());
//        accessoryDiscard.setReturnType(returnCreateDto.getReturnType());
//        accessoryDiscard.setResult(EnumValues.AccessoryOpinionStatus.OPINION.getKey());
//        accessoryDiscard.setCreateTime(new Date());
//        accessoryDiscard.setCreateUser(BaseContextHandler.getUsername());
//        accessoryDiscard.setCreateId(Optional.ofNullable(user).map(Result::getData).map(UserDto::getId).orElse(-1));
//        accessoryDiscardService.saveOrUpdate(accessoryDiscard);

        //退料给线边仓
        StoreOperatorDto storeOperatorDto = buildStoreOperatorDto(accessoryReturn);
        storeOperatorDto.setStoreBusinessTypeEnum(StoreBusinessTypeEnum.辅料退线);
        //备件下机/原料退线边仓=退库入库;线边仓领料=正常入库；热场退库入库=热场下机复评
        storeOperatorDto.setStoreOperatorTypeEnum(StoreOperatorTypeEnum.热场下机复评);
        Result<String> stringResult = storeFeignClients.inputStoreBill(storeOperatorDto);
        if (stringResult == null || !stringResult.getCode().equals(200)){
            throw new RuntimeException("远程调用storeFeignClients.inputStoreBill线边仓入库单失败:"+Optional.ofNullable(stringResult).map(Result::getMessage).orElse(""));
        }

//        Result<String> stringResult1 = storeFeignClients.calculateStock(storeOperatorDto);
//        if (stringResult1 == null || !stringResult1.getCode().equals(200)){
//            throw new RuntimeException("远程调用storeFeignClients.calculateStock线边仓增加库存失败:"+Optional.ofNullable(stringResult).map(Result::getMessage).orElse(""));
//        }
    }

    private StoreOperatorDto buildStoreOperatorDto(AccessoryReturn accessoryReturn) {
        StoreOperatorDto storeOperatorDto = new StoreOperatorDto();
        List<StoreOperatorDetailDto> list = new ArrayList<>();
        //设备编号
        storeOperatorDto.setDeviceNo(accessoryReturn.getEquipment().getCode());
        storeOperatorDto.setOrderNo(accessoryReturn.getOrderNum());
        storeOperatorDto.setRemark(accessoryReturn.getReason());
        storeOperatorDto.setReceiverCode(BaseContextHandler.getUserID().toString());
        storeOperatorDto.setReceiverName(BaseContextHandler.getUsername());

        StoreOperatorDetailDto detailDto = new StoreOperatorDetailDto();
        detailDto.setOutReason(accessoryReturn.getReason());
        detailDto.setMaterialModelId(accessoryReturn.getEquipmentAccessory().getMaterial().getId().intValue());
        detailDto.setMaterialModelCode(accessoryReturn.getEquipmentAccessory().getMaterial().getCodes());
        detailDto.setMaterialModelName(accessoryReturn.getEquipmentAccessory().getMaterial().getName());
        detailDto.setNum(new BigDecimal(accessoryReturn.getNum()));
        detailDto.setUnitName(accessoryReturn.getEquipmentAccessory().getMaterial().getUnit().getName());
        detailDto.setBatchNo(accessoryReturn.getEquipmentAccessory().getBatchNo());
        detailDto.setSupplierName(accessoryReturn.getEquipmentAccessory().getMaterial().getSupplier());
        detailDto.setUniqueCode(accessoryReturn.getGoodsCode());
        detailDto.setUsedTime(accessoryReturn.getUseTime());
        detailDto.setWorkShop("单晶");
        //刻码
        detailDto.setEngraving(accessoryReturn.getEquipmentAccessory().getEngraving());
        //热场设备编号
        detailDto.setCode(accessoryReturn.getEquipment().getCode());

        list.add(detailDto);
        storeOperatorDto.setBusinessData(list);
        return storeOperatorDto;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String toWmsReturn(RequestWmsVo requestWmsVo, AccessoryLog accessoryLog, String url) {
        try{
            if("-1".equals(wmsUrl)){
                return "200";
            }

            ResponseEntity<String> result = null;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            String content = JSON.toJSONString(requestWmsVo);


            HttpEntity<String> request = new HttpEntity<>(content, headers);

            result = restTemplate.postForEntity(url, request, String.class);
            String resultJson = result.getBody();
            accessoryLog.setResult(resultJson);
            if (StringUtils.isNotBlank(resultJson)) {
                //解析状态码，判断成功状态码，失败抛异常回滚，
                WmsResult wmsResult = JSON.parseObject(resultJson, WmsResult.class); //
                if("S".equals(wmsResult.getZtype())) {
                    accessoryLog.setResult(wmsResult.getZmessage());
                    accessoryLogService.saveOrUpdate(accessoryLog);
                    return "200";
                }else {
                    accessoryLog.setType("error");
                    accessoryLog.setResult(wmsResult.getZmessage());
                    accessoryLogService.saveOrUpdate(accessoryLog);
                    return "wms:"+wmsResult.getZmessage();
                }
            }else {
                accessoryLog.setType("error1");
                accessoryLog.setResult("请求wms空！");
                accessoryLogService.saveOrUpdate(accessoryLog);
                return "wms:空！";
            }
        }catch (Exception e){
            accessoryLog.setType("error2");
            accessoryLog.setResult("请求wms失败！");
            accessoryLogService.saveOrUpdate(accessoryLog);
            e.printStackTrace();
            return "wms:请求失败！:"+e.getMessage();
        }
    }

    @Override
    public AccessoryReturn findByGoodsCodeDesc(String goodsCode) {
        List<AccessoryReturn> list = dao.findByGoodsCodeOrderByIdDesc(goodsCode);
        if (list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }

    @Override
    public AccessoryReturn findByOrderNum(String orderNum) {
        List<AccessoryReturn> list = dao.findByOrderNum(orderNum);
        if (list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }


    /**
     * 查询最新的退库记录
     * @param accessoryId
     * @return
     */
    @Override
    public AccessoryReturn findByAccessoryId(Integer accessoryId) {
        List<AccessoryReturn> list = dao.findByEquipmentAccessory_IdOrderByApplyDateDesc(accessoryId.longValue());
        if (list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }



    private String getOrderNum(String deviceNo) {
        StringBuilder str = new StringBuilder();
        str.append("TKFL");
//        str.append("-");
        str.append(deviceNo);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(new Date());
        str.append(format);
        String uuid = UUID.randomUUID().toString();
        String substring = uuid.substring(0, 5);
//        str.append("-");
        str.append(substring);
        return str.toString();
    }

    private AccessoryReturn findByGoodsCodeAndState(String goodsCode, String key) {
        List<AccessoryReturn> list = dao.findByGoodsCodeAndState(goodsCode,key);
        if (list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }
}
