package com.aegis.web.controller.resource.material;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.aegis.common.annotation.Log;
import com.aegis.common.core.controller.BaseController;
import com.aegis.common.core.domain.AjaxResult;
import com.aegis.common.core.page.TableDataInfo;
import com.aegis.common.enums.BusinessType;
import com.aegis.common.utils.StringUtils;
import com.aegis.resource.material.domain.Material;
import com.aegis.resource.material.domain.MaterialInventory;
import com.aegis.resource.material.dto.InventoryAction;
import com.aegis.resource.material.dto.InventoryAdjustment;
import com.aegis.resource.material.domain.MaterialUsage;
import com.aegis.resource.material.service.IResourceMaterialService;
import com.aegis.resource.material.service.IResourceMaterialInventoryService;
import com.aegis.resource.material.service.IResourceMaterialUsageService;

/**
 * 物资管理Controller
 * 
 * @author aegis
 */
@RestController
@RequestMapping("/resources/materials")
public class ResourceMaterialController extends BaseController {

    @Autowired
    private IResourceMaterialService materialService;

    @Autowired
    private IResourceMaterialInventoryService inventoryService;

    @Autowired
    private IResourceMaterialUsageService usageService;

    /**
     * 查询物资列表
     */
    @PreAuthorize("@ss.hasPermi('resource:material:list')")
    @GetMapping("/list")
    public TableDataInfo list(Material material) {
        startPage();
        List<Material> list = materialService.listByCondition(material);
        return getDataTable(list);
    }

    /**
     * 根据ID获取物资详情
     */
    @PreAuthorize("@ss.hasPermi('resource:material:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable Long id) {
        return success(materialService.getById(id));
    }

    /**
     * 新增物资
     */
    @PreAuthorize("@ss.hasPermi('resource:material:add')")
    @Log(title = "物资管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody Material material) {
        return toAjax(materialService.save(material));
    }

    /**
     * 修改物资
     */
    @PreAuthorize("@ss.hasPermi('resource:material:edit')")
    @Log(title = "物资管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody Material material) {
        return toAjax(materialService.updateById(material));
    }

    /**
     * 删除物资
     */
    @PreAuthorize("@ss.hasPermi('resource:material:remove')")
    @Log(title = "物资管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        boolean removed = materialService.removeByIds(Arrays.asList(ids));
        return removed ? success() : error("删除失败");
    }

    /**
     * 设置报警阈值
     */
    @PreAuthorize("@ss.hasPermi('resource:material:edit')")
    @Log(title = "物资管理", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/alert")
    public AjaxResult setAlert(@PathVariable Long id, @RequestBody Material material) {
        return toAjax(materialService.updateMaterialThreshold(id, material.getThreshold()));
    }

    /**
     * 查询库存（支持按仓库查询）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:list')")
    @GetMapping("/{id}/inventory")
    public TableDataInfo listInventory(@PathVariable Long id, MaterialInventory inventory) {
        inventory.setMaterialId(id);
        startPage();
        List<MaterialInventory> list = inventoryService.listByCondition(inventory);
        return getDataTable(list);
    }

    /**
     * 根据库存ID获取库存详情
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:query')")
    @GetMapping("/inventory/{inventoryId}")
    public AjaxResult getInventoryInfo(@PathVariable Long inventoryId) {
        return success(inventoryService.getById(inventoryId));
    }

    /**
     * 添加库存（指定仓库和数量）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:add')")
    @Log(title = "物资库存", businessType = BusinessType.INSERT)
    @PostMapping("/{id}/inventory")
    public AjaxResult addInventory(@PathVariable Long id, @Validated @RequestBody MaterialInventory inventory) {
        inventory.setMaterialId(id);
        return toAjax(inventoryService.addInventory(inventory));
    }

    /**
     * 占用库存（需指定仓库ID）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:lock')")
    @Log(title = "物资库存", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/lock")
    public AjaxResult lockInventory(@PathVariable Long id, @RequestBody Map<String, Object> params) {
        InventoryAction action = buildInventoryAction(id, params);
        return toAjax(inventoryService.lockInventory(action));
    }

    /**
     * 释放库存（需指定仓库ID）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:unlock')")
    @Log(title = "物资库存", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/unlock")
    public AjaxResult unlockInventory(@PathVariable Long id, @RequestBody Map<String, Object> params) {
        InventoryAction action = buildInventoryAction(id, params);
        return toAjax(inventoryService.unlockInventory(action));
    }

    /**
     * 消耗结算（一次性物资，需指定仓库ID）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:consume')")
    @Log(title = "物资库存", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/consume")
    public AjaxResult consumeInventory(@PathVariable Long id, @RequestBody Map<String, Object> params) {
        InventoryAction action = buildInventoryAction(id, params);
        return toAjax(inventoryService.consumeInventory(action));
    }

    /**
     * 归还入库（可重复使用物资，需指定仓库ID）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:return')")
    @Log(title = "物资库存", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/return")
    public AjaxResult returnInventory(@PathVariable Long id, @RequestBody Map<String, Object> params) {
        InventoryAction action = buildInventoryAction(id, params);
        return toAjax(inventoryService.returnInventory(action));
    }

    /**
     * 库存调整（用于盘点、损失、发现等非业务流操作）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:inventory:adjust')")
    @Log(title = "物资库存", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/adjust")
    public AjaxResult adjustInventory(@PathVariable Long id, @Validated @RequestBody InventoryAdjustment adjustment) {
        adjustment.setMaterialId(id);
        return toAjax(inventoryService.adjustInventory(adjustment));
    }

    /**
     * 查询使用记录（支持按仓库筛选）
     */
    @PreAuthorize("@ss.hasPermi('resource:material:usage:list')")
    @GetMapping("/{id}/usages")
    public TableDataInfo listUsages(@PathVariable Long id, MaterialUsage usage) {
        usage.setMaterialId(id);
        startPage();
        List<MaterialUsage> list = usageService.listByCondition(usage);
        return getDataTable(list);
    }

    /**
     * 根据ID获取使用记录详情
     */
    @PreAuthorize("@ss.hasPermi('resource:material:usage:query')")
    @GetMapping("/usages/{usageId}")
    public AjaxResult getUsageInfo(@PathVariable Long usageId) {
        return success(usageService.getById(usageId));
    }

    private InventoryAction buildInventoryAction(Long materialId, Map<String, Object> params) {
        InventoryAction action = new InventoryAction();
        action.setMaterialId(materialId);
        action.setWarehouseId(params.get("warehouseId") != null ? Long.valueOf(params.get("warehouseId").toString()) : null);
        action.setQty(params.get("qty") != null ? new BigDecimal(params.get("qty").toString()) : null);
        action.setEventId(params.get("eventId") != null ? Long.valueOf(params.get("eventId").toString()) : null);
        action.setTaskId(params.get("taskId") != null ? Long.valueOf(params.get("taskId").toString()) : null);
        action.setRemark(StringUtils.isNotNull(params.get("remark")) ? params.get("remark").toString() : null);
        return action;
    }
}