package com.aegis.web.controller.emergency.dispatch;

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.emergency.dispatch.domain.DispatchResourceUsageLink;
import com.aegis.emergency.dispatch.domain.DispatchTask;
import com.aegis.emergency.dispatch.domain.DispatchTaskParticipant;
import com.aegis.emergency.dispatch.domain.DispatchTaskStep;
import com.aegis.emergency.dispatch.domain.DispatchTaskDisposal;
import com.aegis.emergency.dispatch.domain.DispatchTaskLog;
import com.aegis.emergency.dispatch.service.IDispatchTaskService;
import com.aegis.emergency.dispatch.service.IDispatchTaskDisposalService;
import com.aegis.emergency.dispatch.service.IDispatchTaskLogService;
import com.aegis.emergency.dispatch.service.IDispatchResourceUsageLinkService;
import com.aegis.emergency.dispatch.dto.MaterialAllocationRequest;
import com.aegis.emergency.dispatch.dto.EquipmentAllocationRequest;
import com.aegis.emergency.dispatch.dto.VehicleAllocationRequest;
import java.util.Collections;
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.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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 调度任务 Controller
 *
 * @author aegis
 */
@RestController
@RequestMapping("/emergency/dispatch/tasks")
public class DispatchTaskController extends BaseController {

    @Autowired
    private IDispatchTaskService dispatchTaskService;

    @Autowired
    private IDispatchTaskDisposalService disposalService;

    @Autowired
    private IDispatchTaskLogService logService;

    @Autowired
    private IDispatchResourceUsageLinkService resourceUsageLinkService;

    /**
     * 查询调度任务列表
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:list')")
    @GetMapping("/list")
    public TableDataInfo list(DispatchTask condition) {
        startPage();
        List<DispatchTask> list = dispatchTaskService.listByCondition(condition);
        return getDataTable(list);
    }

    /**
     * 查询当前登录用户关联的调度任务
     */
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/my")
    public TableDataInfo listMyTasks(DispatchTask condition,
                                     @RequestParam(value = "keyword", required = false) String keyword) {
        startPage();
        List<DispatchTask> list = dispatchTaskService.listMyTasks(condition, keyword);
        return getDataTable(list);
    }

    /**
     * 根据ID查询调度任务
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable Long id) {
        return success(dispatchTaskService.getById(id));
    }

    /**
     * 根据任务编号查询
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/no/{taskNo}")
    public AjaxResult getByTaskNo(@PathVariable String taskNo) {
        return success(dispatchTaskService.getByTaskNo(taskNo));
    }

    /**
     * 新增调度任务
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:add')")
    @Log(title = "调度任务", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DispatchTask task) {
        return toAjax(dispatchTaskService.save(task));
    }

    /**
     * 修改调度任务
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}")
    public AjaxResult edit(@PathVariable Long id, @RequestBody DispatchTask task) {
        task.setId(id);
        return toAjax(dispatchTaskService.updateById(task));
    }

    /**
     * 删除调度任务
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:remove')")
    @Log(title = "调度任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(dispatchTaskService.removeByIds(java.util.Arrays.asList(ids)));
    }

    /**
     * 发布任务（draft -> published）
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:publish')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/publish")
    public AjaxResult publish(@PathVariable Long id) {
        return toAjax(dispatchTaskService.publish(id));
    }

    /**
     * 标记任务执行中（published -> in_progress）
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/in-progress")
    public AjaxResult markInProgress(@PathVariable Long id) {
        return toAjax(dispatchTaskService.markInProgress(id));
    }

    /**
     * 关闭任务（in_progress -> closed）
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/close")
    public AjaxResult close(@PathVariable Long id, @RequestBody(required = false) Map<String, String> body) {
        String remark = body != null ? body.getOrDefault("remark", "") : "";
        return toAjax(dispatchTaskService.close(id, remark));
    }

    /**
     * 取消任务（published/in_progress -> cancelled）
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/abort")
    public AjaxResult abort(@PathVariable Long id, @RequestBody(required = false) Map<String, String> body) {
        String reason = body != null ? body.getOrDefault("reason", "") : "";
        return toAjax(dispatchTaskService.abort(id, reason));
    }

    /**
     * 添加参与方
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/participants")
    public AjaxResult addParticipants(@PathVariable Long id, @RequestBody List<DispatchTaskParticipant> participants) {
        List<DispatchTaskParticipant> safeList = participants != null ? participants : Collections.emptyList();
        dispatchTaskService.addParticipants(id, safeList);
        return success();
    }

    /**
     * 查询参与方列表
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/participants")
    public AjaxResult listParticipants(@PathVariable Long id) {
        return success(dispatchTaskService.listParticipants(id));
    }

    /**
     * 移除参与方
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @DeleteMapping("/{id}/participants/{participantId}")
    public AjaxResult removeParticipant(@PathVariable Long id, @PathVariable Long participantId) {
        return toAjax(dispatchTaskService.removeParticipant(id, participantId));
    }

    /**
     * 查询行动项列表
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/steps")
    public AjaxResult listSteps(@PathVariable Long id) {
        return success(dispatchTaskService.listSteps(id));
    }

    /**
     * 追加/更新行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/steps")
    public AjaxResult upsertSteps(@PathVariable Long id, @RequestBody List<DispatchTaskStep> steps) {
        List<DispatchTaskStep> safeList = steps != null ? steps : Collections.emptyList();
        dispatchTaskService.upsertSteps(id, safeList);
        return success();
    }

    /**
     * 开始执行行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/start")
    public AjaxResult startStep(@PathVariable Long id, @PathVariable Long stepId) {
        boolean result = dispatchTaskService.startStep(id, stepId);
        return result ? success() : error("开始执行行动项失败");
    }

    /**
     * 完成行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/complete")
    public AjaxResult completeStep(@PathVariable Long id, @PathVariable Long stepId, @RequestBody(required = false) Map<String, String> body) {
        String remark = body != null ? body.get("remark") : null;
        boolean result = dispatchTaskService.completeStep(id, stepId, remark);
        return result ? success() : error("完成行动项失败");
    }

    /**
     * 标记行动项失败
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/fail")
    public AjaxResult failStep(@PathVariable Long id, @PathVariable Long stepId, @RequestBody(required = false) Map<String, String> body) {
        String reason = body != null ? body.get("reason") : null;
        boolean result = dispatchTaskService.failStep(id, stepId, reason);
        return result ? success() : error("标记行动项失败");
    }

    /**
     * 查询任务资源链接
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/resource-links")
    public AjaxResult listResourceLinks(@PathVariable Long id) {
        return success(dispatchTaskService.listResourceLinks(id));
    }

    /**
     * 查询行动项资源链接
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/steps/{stepId}/resource-links")
    public AjaxResult listStepResourceLinks(@PathVariable Long id, @PathVariable Long stepId) {
        return success(resourceUsageLinkService.listByStepId(stepId));
    }

    /**
     * 分配物资到行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/materials")
    public AjaxResult allocateMaterialToStep(@PathVariable Long id, @PathVariable Long stepId, 
                                             @RequestBody MaterialAllocationRequest request) {
        DispatchResourceUsageLink link = resourceUsageLinkService.allocateMaterialToStep(id, stepId, request);
        return success(link);
    }

    /**
     * 分配装备到行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/equipment")
    public AjaxResult allocateEquipmentToStep(@PathVariable Long id, @PathVariable Long stepId,
                                               @RequestBody EquipmentAllocationRequest request) {
        DispatchResourceUsageLink link = resourceUsageLinkService.allocateEquipmentToStep(id, stepId, request);
        return success(link);
    }

    /**
     * 分配车辆到行动项
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/steps/{stepId}/vehicles")
    public AjaxResult allocateVehicleToStep(@PathVariable Long id, @PathVariable Long stepId,
                                           @RequestBody VehicleAllocationRequest request) {
        DispatchResourceUsageLink link = resourceUsageLinkService.allocateVehicleToStep(id, stepId, request);
        return success(link);
    }

    /**
     * 移除行动项资源链接
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @DeleteMapping("/{id}/steps/{stepId}/resource-links/{linkId}")
    public AjaxResult removeStepResourceLink(@PathVariable Long id, @PathVariable Long stepId, 
                                            @PathVariable Long linkId) {
        boolean result = resourceUsageLinkService.detachResource(id, linkId);
        return result ? success() : error("移除资源失败");
    }

    /**
     * 释放物资锁定
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/resource-links/{linkId}/release")
    public AjaxResult releaseMaterialLink(@PathVariable Long id, @PathVariable Long linkId) {
        return toAjax(resourceUsageLinkService.releaseMaterialLink(id, linkId));
    }

    /**
     * 消耗物资
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/resource-links/{linkId}/consume")
    public AjaxResult consumeMaterialLink(@PathVariable Long id, @PathVariable Long linkId) {
        return toAjax(resourceUsageLinkService.consumeMaterialLink(id, linkId));
    }

    /**
     * 归还物资
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/resource-links/{linkId}/return")
    public AjaxResult returnMaterialLink(@PathVariable Long id, @PathVariable Long linkId) {
        return toAjax(resourceUsageLinkService.returnMaterialLink(id, linkId));
    }

    /**
     * 查询处置记录
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/disposals")
    public AjaxResult listDisposals(@PathVariable Long id) {
        return success(disposalService.listByTaskId(id));
    }

    /**
     * 新增处置记录
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.INSERT)
    @PostMapping("/{id}/disposals")
    public AjaxResult addDisposal(@PathVariable Long id, @RequestBody DispatchTaskDisposal disposal) {
        disposal.setTaskId(id);
        return toAjax(disposalService.save(disposal));
    }

    /**
     * 更新处置记录
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:edit')")
    @Log(title = "调度任务", businessType = BusinessType.UPDATE)
    @PutMapping("/{taskId}/disposals/{disposalId}")
    public AjaxResult updateDisposal(@PathVariable Long taskId, @PathVariable Long disposalId,
                                     @RequestBody DispatchTaskDisposal disposal) {
        disposal.setId(disposalId);
        disposal.setTaskId(taskId);
        return toAjax(disposalService.updateById(disposal));
    }

    /**
     * 查询任务日志
     */
    @PreAuthorize("@ss.hasPermi('emergency:dispatch:task:query')")
    @GetMapping("/{id}/logs")
    public AjaxResult listLogs(@PathVariable Long id) {
        List<DispatchTaskLog> logs = logService.listByTaskId(id);
        return success(logs);
    }
}