package com.ruoyi.inventory.service.impl;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.inventory.domain.Inventory;
import com.ruoyi.inventory.domain.InventoryTransactions;
import com.ruoyi.inventory.domain.TO.StocktakeItemsTo;
import com.ruoyi.inventory.domain.TO.StocktakesTO;
import com.ruoyi.inventory.domain.TO.StocktakesVo;
import com.ruoyi.inventory.mapper.StocktakeItemsMapper;
import com.ruoyi.inventory.service.IInventoryService;
import com.ruoyi.inventory.service.IInventoryTransactionsService;
import com.ruoyi.inventory.service.IStocktakeItemsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.inventory.domain.StocktakeItems;
import com.ruoyi.inventory.mapper.StocktakesMapper;
import com.ruoyi.inventory.domain.Stocktakes;
import com.ruoyi.inventory.service.IStocktakesService;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * 盘点单主Service业务层处理
 *
 * @author ruoyi
 * @date 2025-12-02
 */
@Service
public class StocktakesServiceImpl implements IStocktakesService
{
    @Autowired
    private StocktakesMapper stocktakesMapper;

    @Autowired
    private IInventoryService inventoryService; // 库存表

    @Autowired
    private IStocktakeItemsService stocktakeItemsService; // 盘点库存子表

    @Autowired
    private IInventoryTransactionsService inventoryTransactionsService; // 库存操作表
    /**
     * 查询盘点单主
     *
     * @param id 盘点单主主键
     * @return 盘点单主
     */
    @Override
    public Stocktakes selectStocktakesById(String id,String operationType)
    {
        // 获取主表信息
        Stocktakes stocktakes = stocktakesMapper.selectStocktakesById(id);
        // 获取子表信息
        Map<String,Object> query = new HashMap<>();
        query.put("stocktake_id",id);
        if("confirm".equals(operationType)){
            // 盘点确认时只查看 变更的
            query.put("adjusted",1);
        }
        List<StocktakeItemsTo> stocktakeItems = stocktakeItemsService.selectStocktakeItemsByMain(query);
        stocktakes.setStocktakeItemsList(stocktakeItems);
        return stocktakes;

    }

    /**
     * 查询盘点单主列表
     *
     * @param stocktakes 盘点单主
     * @return 盘点单主
     */
    @Override
    public List<Stocktakes> selectStocktakesList(Stocktakes stocktakes)
    {
        return stocktakesMapper.selectStocktakesList(stocktakes);
    }

    /**
     * 新增库存盘点
     * 1.新增主表
     * 2.查询 inventory 库存表 中 库存状态 1-正常、应用数据1使用 的全部数据存入子表
     * @param stocktakes 盘点单主
     * @return 结果
     */
    @Transactional
    @Override
    public int insertStocktakes(Stocktakes stocktakes)
    {
//        1.新增主表
        String id = IdUtils.simpleUUID();
        stocktakes.setId(id);
        stocktakes.setStocktakeId(id);
        stocktakes.setStocktakeType("1");
        stocktakes.setStocktakeStatus("1");
        stocktakes.setIsUsed(1L);
        stocktakes.setCreateTime(DateUtils.getNowDate());
        stocktakes.setCreateUserCode(String.valueOf(SecurityUtils.getLoginUser().getUserId()));
        int rows = stocktakesMapper.insertStocktakes(stocktakes);
//        2.查询 inventory 库存表 中 库存状态 1-正常、应用数据1使用 的全部数据存入子表
        Inventory inventory = new Inventory();
        inventory.setInventoryStatus(1L);
        inventory.setIsUsed(1L);
        List<StocktakeItemsTo> stocktakeItemsList = inventoryService.selectstocktakeItemsList();
        stocktakes.setStocktakeItemsList(stocktakeItemsList);
        insertStocktakeItems(stocktakes);
        return rows;
    }

    /**
     * 修改盘点单主
     * 提交按钮类型，check是盘点，confirm 是确认盘点
     *      盘点提交：所有子表：录入调整人等字段
     *                  如果有调整，是否已调整0否1是
     *              主表:修改盘点状态为已完成：2
     *      确认盘点提交：库存表根据子表数据更新库存量
     *              主表:修改盘点状态为已确认：3
     *              库存操作表插入数据
     * @param stocktakes 盘点单主
     * @return 结果
     */
    @Transactional
    @Override
    public int updateStocktakes(StocktakesTO stocktakes)
    {
        int ret = 1;
        String stocktakesId = stocktakes.getId();
        String operationType = stocktakes.getOperationType();
        String loginUserId = String.valueOf(SecurityUtils.getLoginUser().getUserId());//变更人
        Date nowDate = DateUtils.getNowDate();//统一调整时间
        if("check".equals(operationType)){
            // 盘点提交
            List<StocktakeItemsTo> stocktakeItemsList = stocktakes.getStocktakeItemsList();
            for (StocktakeItemsTo stocktakeItems : stocktakeItemsList) {
                stocktakeItems.setAdjustedBy(loginUserId);//调整人
                stocktakeItems.setAdjustedAt(nowDate);//调整时间
                stocktakeItems.setUpdateUserCode(loginUserId);//更新人
                stocktakeItems.setUpdateTime(nowDate);//更新时间
                // 根据 差异数量 variance_quantity 是否为null 或为 0 判断盘点时是否有调整，有调整时变更调整状态为1
                Long varianceQuantity = stocktakeItems.getVarianceQuantity();
                if (varianceQuantity != null && varianceQuantity != 0L) {
                    stocktakeItems.setAdjusted(1L);
                }
                // 修改 子表
                int i = stocktakeItemsService.updateStocktakeItems(stocktakeItems);
                if (i<0){
                    return -1;
                }
            }
            // 主表:修改盘点状态为已完成：2
            stocktakes.setStocktakeStatus("2");
            stocktakes.setUpdateTime(nowDate);
            int updateStocktakes = stocktakesMapper.updateStocktakes(stocktakes);
            if (updateStocktakes < 0 ){
                ret = -1;
            }
        }
        if("confirm".equals(operationType)){
            // 确认盘点 提交
            // 库存表根据子表数据更新库存量 --因为盘点确认时查询的就是有调整的子表数据，又因为库存操作表需要的货主id子表中没有，所以需要根据id查询库存表
            List<StocktakeItemsTo> stocktakeItemsList = stocktakes.getStocktakeItemsList();
            for (StocktakeItemsTo stocktakeItems : stocktakeItemsList) {
                // 获取实际数量
                Long actualQuantity = stocktakeItems.getActualQuantity();
                // 库存表id
                String inventoryId = stocktakeItems.getInventoryId();
                // 变更前数量 之所以不用库存表中的数量，是因为变更是从盘点计划时开始算的
                Long quantity = stocktakeItems.getSystemQuantity();
                // 获取库存信息
                Inventory inv = inventoryService.selectInventoryById(inventoryId);
                inv.setUpdateTime(nowDate);//更新时间
                inv.setUpdateUserCode(loginUserId);//更新人
                inv.setQuantity(actualQuantity);// 更新实际数量
                // 修改 库存表
                int updateInventory = inventoryService.updateInventory(inv);
                if ( updateInventory < 0 ){
                    return -1;
                }else {
                    // 库存操作表插入数据
                    InventoryTransactions transactions = new InventoryTransactions();
                    transactions.setId(IdUtils.simpleUUID());
                    transactions.setTransactionType(3L);// 事务类型-盘点
                    transactions.setInventoryId(inventoryId); // 库存表Id
                    transactions.setReferenceId(stocktakesId); //关联单号，相当于主记录-盘点主表
                    transactions.setReferenceItemId(stocktakeItems.getId()); // 盘点子表id
                    transactions.setMaterialId(inv.getMaterialId());
                    transactions.setMaterialId(inv.getMaterialId());
                    transactions.setWarehouseId(inv.getWarehousesId());
                    transactions.setLocationId(inv.getLocationId());
                    transactions.setOwnerId(inv.getOwnerId());
                    transactions.setQuantityBefore(quantity);// 变更前数量
                    transactions.setQuantityAfter(actualQuantity);// 变更后数量
                    transactions.setQuantityChange(actualQuantity);
                    transactions.setTransactionTime(nowDate);
                    transactions.setOperatedBy(loginUserId);
                    int inventoryTransactions = inventoryTransactionsService.insertInventoryTransactions(transactions);
                    if (inventoryTransactions < 0) {
                        return -1;
                    }
                }
            }
            // 主表:修改盘点状态为已确认：3
            stocktakes.setStocktakeStatus("3");
            stocktakes.setUpdateTime(nowDate);
            int updateStocktakes = stocktakesMapper.updateStocktakes(stocktakes);
            if (updateStocktakes < 0 ){
                ret = -1;
            }
        }
        return ret;
    }

    /**
     * 逻辑-批量删除盘点单主
     *
     * @param ids 需要删除的盘点单主主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteStocktakesByIds(String[] ids)
    {
        stocktakesMapper.deleteStocktakeItemsByStocktakeIds(ids);
        return stocktakesMapper.deleteStocktakesByIds(ids);
    }

    /**
     * 删除盘点单主信息
     *
     * @param id 盘点单主主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteStocktakesById(String id)
    {
        stocktakesMapper.deleteStocktakeItemsByStocktakeId(id);
        return stocktakesMapper.deleteStocktakesById(id);
    }

    /**
     * 新增盘点单明细信息
     *
     * @param stocktakes 盘点单主对象
     */
    public void insertStocktakeItems(Stocktakes stocktakes)
    {
        List<StocktakeItemsTo> stocktakeItemsList = stocktakes.getStocktakeItemsList();
        String stocktakeid = stocktakes.getId(); // 盘点单号
        String createUserCode = stocktakes.getCreateUserCode();// 创建人
        Date createTime = stocktakes.getCreateTime();// 创建日期
        if (StringUtils.isNotNull(stocktakeItemsList))
        {
            List<StocktakeItems> list = new ArrayList<StocktakeItems>();
            for (StocktakeItems stocktakeItems : stocktakeItemsList)
            {
                String id = IdUtils.simpleUUID();
                stocktakeItems.setId(id);
                stocktakeItems.setStocktakeId(stocktakeid);
                stocktakeItems.setStocktakeStatus("1");
                stocktakeItems.setIsUsed(1L);
                stocktakeItems.setCreateUserCode(createUserCode);
                stocktakeItems.setCreateTime(createTime);
                list.add(stocktakeItems);

            }
            if (list.size() > 0)
            {
                stocktakesMapper.batchStocktakeItems(list);
            }
        }
    }
    /**
     * @description: 查询处理统计
     * @author cs
     * @date 2025/12/8
     * @version 1.0
     */
    @Override
    public List<StocktakesVo> selectStocktakesListCount(StocktakesVo stocktakes)
    {
        List<StocktakesVo> list = stocktakesMapper.selectStocktakesListCount(stocktakes);
        return list;
    }

    /**
     * @description: 查询处理统计-详情
     * @author cs
     * @date 2025/12/9
     * @version 1.0
     */
    @Override
    public List<StocktakesVo> selectStocktakesCountInfo(StocktakesVo stocktakes)
    {
        List<StocktakesVo> list = stocktakeItemsService.selectStocktakesCountInfo(stocktakes);
        return list;
    }

    /**
     * @description: 首页-本月盘点次数
     * @author cs
     * @date 2025/12/10
     * @version 1.0
     */
    public int selectStocktakesCountByMonth(){
        Stocktakes stocktakes = new Stocktakes();
        Map<String, Object> params = stocktakeItemsService.getMonthDay();
        stocktakes.setParams(params);
        return stocktakesMapper.selectStocktakesCountByMonth(stocktakes);
    }
}
