/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.youchain.basicdata.rest;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.annotation.Log;
import com.youchain.basicdata.domain.Box;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.repository.BoxRepository;
import com.youchain.basicdata.service.BoxService;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.dto.BoxDto;
import com.youchain.basicdata.service.dto.BoxQueryCriteria;
import com.youchain.businessdata.domain.Inventory;
import com.youchain.businessdata.domain.PickDetail;
import com.youchain.businessdata.repository.InventoryRepository;
import com.youchain.businessdata.repository.PickDetailRepository;
import com.youchain.businessdata.service.InventoryService;
import com.youchain.businessdata.service.PickDetailService;
import com.youchain.exception.handler.ApiError;
import com.youchain.exception.handler.ApiResult;
import com.youchain.utils.BaseStatus;
import com.youchain.utils.BizStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;

/**
 * @author huojin
 * @website https://eladmin.vip
 * @date 2023-08-17
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "box管理")
@RequestMapping("/api/box")
@Slf4j
public class BoxController {

    private final BoxService boxService;

    private  final PickDetailService pickDetailService;

    private final InventoryService inventoryService;

    private final PointService pointService;





    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('box:list')")
    public void exportBox(HttpServletResponse response, BoxQueryCriteria criteria) throws IOException {
        boxService.download(boxService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询box")
    @ApiOperation("查询box")
    @PreAuthorize("@el.check('box:list')")
    public ResponseEntity<Object> queryBox(BoxQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(boxService.queryAll(criteria, pageable), OK);
    }

    @PostMapping
    @Log("新增box")
    @ApiOperation("新增box")
    @PreAuthorize("@el.check('box:add')")
    public ResponseEntity<Object> createBox(@Validated @RequestBody Box resources) {
        Box box =boxService.getBoxByItem(resources.getItem().getId());
        if(box!=null){
            return new ResponseEntity(ApiError.errorJosn(BAD_REQUEST.value(), resources.getItem().getCode()+"该物料已绑定按钮盒！"), HttpStatus.BAD_REQUEST);
        }else{
            boxService.create(resources);
            boxService.refreshPointStatus();
        }
        return new ResponseEntity<>(boxService.create(resources), HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改box")
    @ApiOperation("修改box")
    @PreAuthorize("@el.check('box:edit')")
    public ResponseEntity<Object> updateBox(@Validated @RequestBody Box resources) {
        Box box =boxService.getBoxByItem(resources.getItem().getId());
        if(box==null){
            boxService.update(resources);
            boxService.refreshPointStatus();
        }else if(resources.getId().equals(box.getId())){
            boxService.update(resources);
            boxService.refreshPointStatus();
        }else{
            return new ResponseEntity(ApiError.errorJosn(BAD_REQUEST.value(), resources.getItem().getCode()+"该物料已绑定按钮盒！"), HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除box")
    @ApiOperation("删除box")
    @PreAuthorize("@el.check('box:del')")
    public ResponseEntity<Object> deleteBox(@RequestBody Long[] ids) {
        boxService.deleteAll(ids);
        return new ResponseEntity<>(OK);
    }


    @PostMapping("/callBox")
    @Log("呼叫按钮盒")
    @ApiOperation("呼叫按钮盒")
    @PreAuthorize("@el.check('box:callBox')")
    public synchronized ResponseEntity<Object> callBox(@RequestBody Long[] ids) {
        long suc=0;
        long error=0;
        List<Long> BoxIds = Arrays.asList(ids);
        for (long id : BoxIds) {
            BoxDto boxdto = boxService.findById(id);
            Box box = boxService.toEntity(boxdto);
            Item item=box.getItem();
            //根据按钮盒绑定的物料查找库存
            List<Inventory> Inventorys=inventoryService.queryInventory(item.getId());
            if(Inventorys.size()>0){
                try {
                    Inventory inv=Inventorys.get(0);
                    PickDetail pd=new PickDetail();
                    pd.setPo(new Date().getTime()+"");
                    pd.setItem(item);
                    pd.setStatus(BizStatus.OPEN);
                    pd.setLineNo(pickDetailService.count()+1);
                    pd.setOrderQty(inv.getQuantity()-inv.getQueuedQty());
                    pickDetailService.create(pd);
                    pickDetailService.allocate(pd.getId(),pd.getOrderQty());
                    suc++;
                } catch (Exception e) {
                    return new ResponseEntity(ApiResult.fail(BAD_REQUEST.value(), e.getMessage(),""), HttpStatus.BAD_REQUEST);
                }
            }else{
                error++;
            }

        }

        return new ResponseEntity<>(ApiError.errorJosn(OK.value(), "呼叫成功"+suc+"条,呼叫失败"+error+"条"), HttpStatus.OK);
    }

    @PostMapping("/boxTask")
    @Log("按钮盒任务下发接口")
    @ApiOperation("按钮盒任务下发接口")
    @AnonymousAccess
    public synchronized ResponseEntity<Object> boxTask(@RequestBody String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        String stockCode = jsonObject.getString("stockCode");
        String taskCode = jsonObject.getString("taskCode");
        String issueDate = jsonObject.getString("issueDate");

        if(stockCode==null || stockCode.length()<=0){
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(),"stockCode参数为错误或为空！",""), HttpStatus.BAD_REQUEST);
        }

        Box box =boxService.getBoxByCode(stockCode);
        if(box!=null){
            //根据按钮盒查询库存，有则分配，无则提示
            Item item=box.getItem();
            List<Inventory> Inventorys =inventoryService.queryInventory(item.getId());
            if(Inventorys.size()>0){
                //分配库存
                try {
                    Inventory inv=Inventorys.get(0);
                    //生成出库明细
                    PickDetail pd=new PickDetail();
                    pd.setPo(new Date().getTime()+"");
                    pd.setItem(item);
                    pd.setStatus(BizStatus.OPEN);
                    pd.setLineNo(pickDetailService.count()+1);
                    pd.setOrderQty(inv.getQuantity()-inv.getQueuedQty());
                    pickDetailService.create(pd);
                    pickDetailService.allocate(pd.getId(),pd.getOrderQty());
                } catch (Exception e) {
                    return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(),e.getMessage(),""), HttpStatus.BAD_REQUEST);
                }
                return new ResponseEntity<>(ApiResult.success("",taskCode), OK);
            }else{
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(),"无库存,呼叫失败！",""), HttpStatus.BAD_REQUEST);
            }

        }else{
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(),"按钮盒不存在！",""), HttpStatus.BAD_REQUEST);
        }


    }

}
