package com.artfess.cqxy.projectManagement.controller;

import com.artfess.base.annotation.ApiGroup;
import com.artfess.base.constants.ApiGroupConsts;
import com.artfess.base.controller.BaseController;
import com.artfess.base.model.CommonResult;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.cqxy.constructionPermit.manager.ConstructionPermitManager;
import com.artfess.cqxy.constructionPermit.model.ConstructionPermit;
import com.artfess.cqxy.designEstimate.model.Estimate;
import com.artfess.cqxy.processManagermant.manager.ProgressManageManager;
import com.artfess.cqxy.processManagermant.manager.ProgressManageReportManager;
import com.artfess.cqxy.processManagermant.model.ProgressManageReport;
import com.artfess.cqxy.projectManagement.manager.ProjectPersonnelManager;
import com.artfess.cqxy.projectManagement.model.ProjectManagement;
import com.artfess.cqxy.projectManagement.manager.ProjectManagementManager;
import com.artfess.cqxy.projectManagement.vo.MergeItemsVo;
import com.artfess.cqxy.projectManagement.vo.ProjectCostConsultationVo;
import com.artfess.cqxy.projectManagement.vo.ProjectLandCostVo;
import com.artfess.cqxy.projectManagement.vo.ProjectParentIdsVo;
import com.artfess.i18n.util.I18nUtil;
import com.artfess.sysConfig.persistence.manager.SysMenuManager;
import com.artfess.sysConfig.persistence.model.SysMenu;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 项目管理表(BizProjectManagement)表控制层
 *
 * @author 黎沐华
 * @since 2022-02-10 15:43:42
 */
@Slf4j
@RestController
@Api(tags = "项目管理-项目管理接口")
@ApiGroup(group = {ApiGroupConsts.GROUP_BIZ})
@RequestMapping("/biz/projectManagement/pm/v1")
public class ProjectManagementController extends BaseController<ProjectManagementManager, ProjectManagement> {

    @Autowired
    ProjectPersonnelManager projectPersonnelManager;

    @Autowired
    ProgressManageReportManager progressManageReportManager;

    @Autowired
    ProgressManageManager progressManageManager;

    @Autowired
    private ConstructionPermitManager constructionPermitManager;

    //新建项目时的各个单位，如业主单位、施工单位、监理单位等都是要关联到其它表的，

    /**
     * 保存或修改数据
     *
     * @param pmObject 实体对象
     * @return 新增结果
     */
    @PostMapping("/save")
    @ApiOperation(value = "S-保存或修改数据", httpMethod = "POST")
    public CommonResult<String> save(@ApiParam(name = "pmObject", value = "项目管理信息表对象") @RequestBody ProjectManagement pmObject) {
        Assert.notNull(pmObject.getProjectCode(), "项目代码不能为空");
        String msg = "";
        boolean save = false;
        if (pmObject != null && StringUtils.isBlank(pmObject.getParentId())){
            pmObject.setParentId("root");
        }
        if (StringUtils.isEmpty(pmObject.getId())) {
            pmObject.setIsDele("0");
            pmObject.setValidFlag(1);
            pmObject.setSn(baseService.createSnNum());
            save = baseService.savePm(pmObject);
            //新建项目时将所有uc_user中的用户放到人员中间表关联该项目
//            projectPersonnelManager.linkUsers(pmObject.getId());
            msg = save ? "添加成功" : "添加失败";
        } else {
            save = baseService.updateById(pmObject);
            msg = save ? "修改成功" : "修改失败";
        }
        String projectManagerId = pmObject.getProjectManagerId();
        //新建项目时将管理者放入到人员中去
        projectPersonnelManager.linkUsersByProjectManager(pmObject.getId(), projectManagerId);
        baseService.updateHasChildrenByParentId(pmObject.getId());
        return new CommonResult<>(save, msg);
    }

    /**
     * 批量导入Excel数据
     *
     * @param file Excel文件
     */
    @PostMapping("/importExcelData")
    @ApiOperation(value = "S-批量导入Excel数据")
    public CommonResult importExcelData(@ApiParam("上传文件") @RequestParam("file") MultipartFile file, String projectId) {
        baseService.importExcelData(file);
        return new CommonResult<>("导入成功");
    }

    /**
     * 导出数据到Excel
     *
     * @param queryFilter 查询条件
     */
    @PostMapping("/exportDataToExcel")
    @ApiOperation(value = "S-导出数据到Excel", notes = "参数说明：pageBean传入pageSize为-1不分页查询所有数据后导出到Excel，可以带其他查询参数，但是pageSize必须为-1")
    public CommonResult exportDataToExcel(
            @ApiParam(name = "queryFilter", value = "通用查询器")
            @RequestBody QueryFilter<ProjectManagement> queryFilter, HttpServletResponse response) throws IOException {
        baseService.exportDatatoExcel(queryFilter, response);
        return new CommonResult<>("导入成功");
    }

    /**
     * 删除数据
     *
     * @param ids 主键集合
     * @return 删除结果
     */
    @PostMapping("/delete")
    @ApiOperation(value = "S-删除数据", httpMethod = "POST")
    public CommonResult delete(@ApiParam(name = "ids", value = "ID集合") @RequestParam("ids") String ids) {
        Assert.notNull(ids, "主键集合不能为空");
        boolean state = baseService.removeByIds(Arrays.asList(ids.split(",")));
        String msg = state ? "删除成功" : "删除失败";
        return new CommonResult(state, msg);
    }

    /**
     * 修改项目排序号
     *
     * @param params 主键
     * @return msg
     */
    @PostMapping("/updateSequence")
    @ApiOperation(value = "S-修改项目排序号", notes = "前端拖动记录进行排序，那么要传入发生变动的记录的ID及排序号，如\"params\":{\"ID值\":\"排序号\",\"ID值\":\"排序号\"}", httpMethod = "POST")
    public CommonResult sort(@ApiParam(name = "params", value = "参数说明：Key：ID，Value：排序号") @RequestBody HashMap<String, Integer> params) {
        baseService.updateSequence(params);
        return new CommonResult(true, "操作成功");
    }

    /**
     * 启禁用项目
     *
     * @param id 主键
     * @return msg
     */
    @PostMapping("/totalEnable/{id}")
    @ApiOperation(value = "S-启禁用项目", httpMethod = "POST")
    public CommonResult totalEnable(@ApiParam(name = "id", value = "主键ID") @PathVariable String id) {
        ProjectManagement recoded = baseService.getById(id);
        int validFlag = recoded.getValidFlag() == 0 ? 1 : 0;
        recoded.setValidFlag(validFlag);
        boolean update = baseService.updateById(recoded);
        String msg = (validFlag == 1 ? "启用" : "禁用") + (update ? "成功" : "失败");
        return new CommonResult(update, msg);
    }

    /**
     * 设为当前项目
     *
     * @param id 主键
     * @return msg
     */
    @PostMapping("/currentProject/{id}")
    @ApiOperation(value = "S-设为当前项目", httpMethod = "POST")
    public CommonResult currentProject(@ApiParam(name = "id", value = "主键ID") @PathVariable String id) {
        boolean flag = baseService.setCurrentProject(id) == 1;
        String msg = flag ? "操作成功" : "操作失败";
        return new CommonResult(flag, msg);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @PostMapping("/detail/{id}")
    @ApiOperation(value = "S-根据ID查询详情", httpMethod = "POST")
    public CommonResult<ProjectManagement> selectOne(@ApiParam(name = "id", value = "主键ID") @PathVariable String id) {
        Assert.notNull(id, "主键不能为空");
        ProjectManagement result = baseService.getById(id);
        boolean state = !BeanUtils.isEmpty(result);
        return new CommonResult<ProjectManagement>(state, state ? "操作成功" : "该ID没有对应数据", result);
    }

    /**
     * 分页查询所有数据
     *
     * @param queryFilter 通用查询器
     * @return 分页数据
     */
    @PostMapping("/page")
    @ApiOperation(value = "S-分页查询所有数据", notes = "参数说明：pageBean传入pageSize为-1表示不分页查询，在通用查询器中的query对象组传入查询参数", httpMethod = "POST")
    public CommonResult<PageList<ProjectManagement>> page(@ApiParam(name = "queryFilter", value = "通用查询器")
                                                              @RequestBody QueryFilter<ProjectManagement> queryFilter) {
        PageList<ProjectManagement> result = baseService.queryAllByPage(queryFilter);
        List<ProjectManagement> rows = result.getRows();
        // 查询累计总投资和本月进度
        for (ProjectManagement pm : rows){
            // 这是原来的，是从月报中统计的进度以及累计总投资，新的总投资将从工程支付中统计
            ProgressManageReport overvieByProjectId = progressManageReportManager.getProjectOvervieByProjectId(pm.getId());
            if(overvieByProjectId != null){
                // 形象进度 weeklyMouthlyWork
                pm.setConstructionProgress(overvieByProjectId.getWeeklyMouthlyWork());
                // 累计总投资 projectOvervie
//                BigDecimal projectOvervie = overvieByProjectId.getProjectOvervie();
//                if (projectOvervie!=null){
//                    BigDecimal bigDecimal = projectOvervie.divide(new BigDecimal(10000)).stripTrailingZeros().setScale(0, BigDecimal.ROUND_HALF_DOWN);
//                    pm.setAccumulatedProjectPayment(bigDecimal);
//                }
            }
            // 从工程支付中查询累计总投资
            BigDecimal projectOvervie = progressManageManager.geTamountAppropriatedTotalByProjectId(pm.getId());
            if (projectOvervie!=null){
                BigDecimal bigDecimal = projectOvervie.divide(new BigDecimal(10000)).stripTrailingZeros().setScale(0, BigDecimal.ROUND_HALF_DOWN);
                pm.setAccumulatedProjectPayment(bigDecimal);
            }
            if(null != pm.getProjectMoney()){
                pm.setProjectMoney(pm.getProjectMoney().stripTrailingZeros());
            }
        }
        return new CommonResult<PageList<ProjectManagement>>(true, "操作成功", result);
    }

    /**
     * 分页查询所有数据
     *
     * @param queryFilter 通用查询器
     * @return 分页数据
     */
    @PostMapping("/noFilterPage")
    @ApiOperation(value = "S-分页查询所有数据（不会根据用户权限过滤项目）", notes = "参数说明：pageBean传入pageSize为-1表示不分页查询，在通用查询器中的query对象组传入查询参数", httpMethod = "POST")
    public CommonResult<PageList<ProjectManagement>> noFilterPage(@ApiParam(name = "queryFilter", value = "通用查询器")
                                                          @RequestBody QueryFilter<ProjectManagement> queryFilter) {
        PageList<ProjectManagement> result = baseService.noFilterPage(queryFilter);
        return new CommonResult<PageList<ProjectManagement>>(true, "操作成功", result);
    }

    /**
     * 不分页查询所有数据数据
     *
     * @return 所有数据
     */
    @PostMapping("/All")
    @ApiOperation(value = "S-不分页查询所有数据")
    public CommonResult<List<ProjectManagement>> all() {
//        List<ProjectManagement> result = baseService.getAll();
        QueryFilter<ProjectManagement> queryFilter = QueryFilter.build();
        queryFilter.withDefaultPage();
        List<ProjectManagement> result = baseService.queryList(queryFilter);
        return new CommonResult<>(true, "操作成功", result);
    }

    @PostMapping("/mergeItems")
    @ApiOperation(value = "S-合并项目(将若干项目合并到一个项目下)")
    public CommonResult<String> mergeItems(@ApiParam(name = "mergeItemsVo", value = "项目合并VO对象") @RequestBody MergeItemsVo mergeItemsVo) {
        baseService.mergeItems(mergeItemsVo);
        return new CommonResult<String>(true, "项目合并成功");
    }

    @PostMapping("/splitItems")
    @ApiOperation(value = "S-拆分项目(将若干项目拆分成独立项目)")
    public CommonResult<String> splitItems(@ApiParam(name = "ids", value = "需要拆分的项目ID，多个使用逗号分隔") @RequestParam("ids") String ids) {
        baseService.splitItems(ids);
        return new CommonResult<String>(true, "项目拆分成功");
    }

    @PostMapping("/updateParentIdByIds")
    @ApiOperation(value = "S-根据项目ID修改父项目的ID")
    public CommonResult<String> updateParentIdByIds(@ApiParam(name = "projectParentIdsVo", value = "项目修改ParentId，VO对象")
                                                        @RequestBody ProjectParentIdsVo projectParentIdsVo) {
        Assert.notNull(projectParentIdsVo, "项目ID不能为空");
        baseService.updateParentIdByIds(projectParentIdsVo.getParentId(), projectParentIdsVo.getIds());
        return new CommonResult<String>(true, "操作成功");
    }

    @PostMapping("/updateCostConsultationById")
    @ApiOperation(value = "S-根据项目ID修改造价咨询单位")
    public CommonResult<String> updateCostConsultationById(@ApiParam(name = "projectCostConsultationVo", value = "造价咨询单位VO")
                                                    @RequestBody ProjectCostConsultationVo projectCostConsultationVo) {
        Assert.notNull(projectCostConsultationVo, "项目ID不能为空");
        Assert.notNull(projectCostConsultationVo.getId(), "项目ID不能为空");
        Assert.notNull(projectCostConsultationVo.getCostConsultation(), "全过程造价咨询单位");
        baseService.updateCostConsultationById(projectCostConsultationVo.getId(), projectCostConsultationVo.getCostConsultation());
        return new CommonResult<String>(true, "造价咨询单位修改成功");
    }

    @PostMapping("/updateLandCostById")
    @ApiOperation(value = "S-根据项目ID修改土地费用")
    public CommonResult<String> updateLandCostById(@ApiParam(name = "projectLandCostVo", value = "根据项目ID修改土地费用")
                                                           @RequestBody ProjectLandCostVo projectLandCostVo) {
        Assert.notNull(projectLandCostVo, "参数不能为空");
        Assert.notNull(projectLandCostVo.getId(), "项目ID不能为空");
        baseService.updateLandCostById(projectLandCostVo);
        return new CommonResult<String>(true, "土地费用保存成功");
    }
}

