package com.yhy.module.core.controller.admin.workbench;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.yhy.module.core.controller.admin.workbench.vo.HistoryBoqListReqVO;
import com.yhy.module.core.controller.admin.workbench.vo.WbBoqDivisionRespVO;
import com.yhy.module.core.controller.admin.workbench.vo.WbBoqDivisionSaveReqVO;
import com.yhy.module.core.controller.admin.workbench.vo.WbBoqDivisionSwapSortReqVO;
import com.yhy.module.core.service.workbench.WbBoqDivisionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
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.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 yhy
 */
@Tag(name = "工作台 - 分部分项树")
@RestController
@RequestMapping("/core/wb/boq-division")
@Validated
public class WbBoqDivisionController {

    @Resource
    private WbBoqDivisionService wbBoqDivisionService;

    @Resource
    private com.yhy.module.core.service.workbench.QuotaQtyFormulaService quotaQtyFormulaService;

    @PostMapping("/create")
    @Operation(summary = "创建节点（分部、清单或定额）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:create')")
    public CommonResult<Long> createNode(@Valid @RequestBody WbBoqDivisionSaveReqVO createReqVO) {
        return success(wbBoqDivisionService.createNode(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新节点")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:update')")
    public CommonResult<Boolean> updateNode(@Valid @RequestBody WbBoqDivisionSaveReqVO updateReqVO) {
        wbBoqDivisionService.updateNode(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除节点")
    @Parameter(name = "id", description = "节点ID", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:delete')")
    public CommonResult<Boolean> deleteNode(@RequestParam("id") Long id) {
        wbBoqDivisionService.deleteNode(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获取节点详情")
    @Parameter(name = "id", description = "节点ID", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<WbBoqDivisionRespVO> getNode(@RequestParam("id") Long id) {
        return success(wbBoqDivisionService.getNode(id));
    }

    @GetMapping("/tree")
    @Operation(summary = "获取分部分项树（可按标签页过滤）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<List<WbBoqDivisionRespVO>> getTree(
            @RequestParam("compileTreeId") @Parameter(description = "编制模式树的单位工程节点ID", required = true) Long compileTreeId,
            @RequestParam(value = "tabType", required = false) @Parameter(description = "标签页类型：division/measure/other/unit_summary，不传返回全量") String tabType,
            @RequestParam(value = "excludeZeroQtyBoq", required = false, defaultValue = "false") @Parameter(description = "是否过滤工程量为0或空的清单节点") Boolean excludeZeroQtyBoq) {
        if (tabType != null && !tabType.isEmpty()) {
            return success(wbBoqDivisionService.getTreeByTab(compileTreeId, tabType, excludeZeroQtyBoq));
        }
        return success(wbBoqDivisionService.getTree(compileTreeId, excludeZeroQtyBoq));
    }

    @GetMapping("/tree-for-unified-fee")
    @Operation(summary = "获取统一取费范围选择树（专供统一取费弹窗使用）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<List<WbBoqDivisionRespVO>> getTreeForUnifiedFee(
            @RequestParam("compileTreeId") @Parameter(description = "编制模式树的单位工程节点ID", required = true) Long compileTreeId,
            @RequestParam(value = "tabType", required = false) @Parameter(description = "标签页类型：division/measure") String tabType,
            @RequestParam(value = "feeChapter", required = false) @Parameter(description = "取费章节ID列表，逗号分隔") List<Long> feeChapter) {
        return success(wbBoqDivisionService.getTreeForUnifiedFee(compileTreeId, tabType, feeChapter));
    }

    @GetMapping("/tree-with-price")
    @Operation(summary = "获取分部分项树（含定额单价计算）")
    @Parameter(name = "compileTreeId", description = "编制模式树的单位工程节点ID", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<List<WbBoqDivisionRespVO>> getTreeWithPrice(@RequestParam("compileTreeId") Long compileTreeId) {
        return success(wbBoqDivisionService.getTreeWithPrice(compileTreeId));
    }

    @PutMapping("/swap-sort")
    @Operation(summary = "交换排序")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:update')")
    public CommonResult<Boolean> swapSort(@Valid @RequestBody WbBoqDivisionSwapSortReqVO swapReqVO) {
        wbBoqDivisionService.swapSort(swapReqVO);
        return success(true);
    }

    @GetMapping("/history-list")
    @Operation(summary = "获取历史清单/分部列表（跨项目，分页）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<PageResult<WbBoqDivisionRespVO>> getHistoryList(@Valid HistoryBoqListReqVO reqVO) {
        return success(wbBoqDivisionService.getHistoryListPage(reqVO));
    }

    @PostMapping("/copy")
    @Operation(summary = "复制清单到目标位置（含定额和工料机）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:create')")
    public CommonResult<Long> copyBoq(
            @RequestParam("sourceBoqId") @Parameter(description = "源清单节点ID") Long sourceBoqId,
            @RequestParam("targetCompileTreeId") @Parameter(description = "目标单位工程节点ID") Long targetCompileTreeId,
            @RequestParam("targetParentId") @Parameter(description = "目标父节点ID") Long targetParentId) {
        return success(wbBoqDivisionService.copyBoqWithChildren(sourceBoqId, targetCompileTreeId, targetParentId));
    }

    @PostMapping("/copy-division")
    @Operation(summary = "复制分部到目标位置（含子清单、定额和工料机）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:create')")
    public CommonResult<Long> copyDivision(
            @RequestParam("sourceDivisionId") @Parameter(description = "源分部节点ID") Long sourceDivisionId,
            @RequestParam("targetCompileTreeId") @Parameter(description = "目标单位工程节点ID") Long targetCompileTreeId,
            @RequestParam("targetParentId") @Parameter(description = "目标父节点ID") Long targetParentId) {
        return success(wbBoqDivisionService.copyDivisionWithChildren(sourceDivisionId, targetCompileTreeId, targetParentId));
    }

    @PostMapping("/copy-from-guide")
    @Operation(summary = "从清单指引复制清单子目到分部分项（含定额和工料机）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:create')")
    public CommonResult<Long> copyFromGuide(
            @RequestParam("compileTreeId") @Parameter(description = "目标单位工程节点ID") Long compileTreeId,
            @RequestParam("parentId") @Parameter(description = "目标父节点ID（分部节点）") Long parentId,
            @RequestParam("boqSubItemId") @Parameter(description = "清单子目ID") Long boqSubItemId,
            @RequestParam("sourceBoqItemTreeId") @Parameter(description = "清单项树节点ID") Long sourceBoqItemTreeId) {
        return success(wbBoqDivisionService.copyFromGuide(compileTreeId, parentId, boqSubItemId, sourceBoqItemTreeId));
    }

    @GetMapping("/validate-formula")
    @Operation(summary = "验证定额工程量公式")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<FormulaValidationRespVO> validateFormula(
            @RequestParam("formula") @Parameter(description = "公式字符串，如 QDL*2") String formula,
            @RequestParam(value = "qdlValue", required = false) @Parameter(description = "清单工程量测试值") java.math.BigDecimal qdlValue) {
        com.yhy.module.core.service.workbench.QuotaQtyFormulaService.FormulaValidationResult result = 
            quotaQtyFormulaService.validateFormula(formula);
        
        FormulaValidationRespVO respVO = new FormulaValidationRespVO();
        respVO.setValid(result.isValid());
        respVO.setError(result.getError());
        
        // 如果验证通过且提供了测试值，计算结果
        if (result.isValid() && qdlValue != null) {
            respVO.setResult(quotaQtyFormulaService.calculateQuotaQty(formula, qdlValue));
        } else {
            respVO.setResult(result.getTestResult());
        }
        
        return success(respVO);
    }

    @GetMapping("/calculate-quota-qty")
    @Operation(summary = "计算定额工程量")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<java.math.BigDecimal> calculateQuotaQty(
            @RequestParam("formula") @Parameter(description = "公式字符串，如 QDL*2") String formula,
            @RequestParam("qdlValue") @Parameter(description = "清单工程量值") java.math.BigDecimal qdlValue) {
        return success(quotaQtyFormulaService.calculateQuotaQty(formula, qdlValue));
    }

    @GetMapping("/tree-by-tab")
    @Operation(summary = "按标签页获取分部分项树（四个标签页独立）")
    @PreAuthorize("@ss.hasPermission('core:wb-boq-division:query')")
    public CommonResult<List<WbBoqDivisionRespVO>> getTreeByTab(
            @RequestParam("compileTreeId") @Parameter(description = "编制模式树的单位工程节点ID") Long compileTreeId,
            @RequestParam(value = "tabType", required = false) @Parameter(description = "标签页类型：division/measure/other/unit_summary") String tabType) {
        return success(wbBoqDivisionService.getTreeByTab(compileTreeId, tabType));
    }

    /**
     * 公式验证响应VO
     */
    @lombok.Data
    public static class FormulaValidationRespVO {
        @io.swagger.v3.oas.annotations.media.Schema(description = "是否有效")
        private Boolean valid;
        @io.swagger.v3.oas.annotations.media.Schema(description = "错误信息")
        private String error;
        @io.swagger.v3.oas.annotations.media.Schema(description = "计算结果")
        private java.math.BigDecimal result;
    }
}
