package com.ruoyi.web.controller.oa;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oa.domain.*;
import com.ruoyi.oa.service.*;
import org.springframework.beans.factory.annotation.Autowired;
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.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * cmc合同评审Controller
 * 
 * @author cmc
 * @date 2024-03-15
 */
@RestController
@RequestMapping("/oa/contract")
public class CmcContractController extends BaseController
{
    @Autowired
    private ICmcContractService cmcContractService;

    /**
     * 查询cmc合同评审列表
     */
    @GetMapping("/list")
    public TableDataInfo list(CmcContract cmcContract)
    {
        startPage();
        List<CmcContract> list = cmcContractService.selectCmcContractListP(cmcContract);
        return getDataTable(list);
    }

    /**
     * 模糊查询cmc合同评审列表
     */
    @GetMapping("/listFuzzy")
    public TableDataInfo listFuzzy(CmcContract cmcContract)
    {
        startPage();
        List<CmcContract> list = cmcContractService.selectCmcContractListFuzzy(cmcContract);
        return getDataTable(list);
    }

    /**
     * 获取cmc承接合同统计信息
     */
    @GetMapping("/statistic")
    public AjaxResult getContractStatistic(CmcContract cmcContract) throws ParseException {
        JSONObject jsonObject = new JSONObject();
        JSONArray yearCountArray = new JSONArray();
        JSONObject yearCountObject = new JSONObject();
        JSONArray monthCountArray = new JSONArray();
        JSONObject monthCountObject = new JSONObject();
        JSONArray sourceCountArray = new JSONArray();
        JSONObject sourceCountObject = new JSONObject();
        JSONArray yearAmountArray = new JSONArray();
        JSONObject yearAmountObject = new JSONObject();
        JSONArray monthAmountArray = new JSONArray();
        JSONObject monthAmountObject = new JSONObject();
        JSONArray sourceAmountArray = new JSONArray();
        JSONObject sourceAmountObject = new JSONObject();
        JSONArray paidYearCountArray = new JSONArray();
        JSONObject paidYearCountObject = new JSONObject();
        JSONArray paidMonthCountArray = new JSONArray();
        JSONObject paidMonthCountObject = new JSONObject();
        JSONArray paidSourceCountArray = new JSONArray();
        JSONObject paidSourceCountObject = new JSONObject();
        JSONArray paidYearAmountArray = new JSONArray();
        JSONObject paidYearAmountObject = new JSONObject();
        JSONArray paidMonthAmountArray = new JSONArray();
        JSONObject paidMonthAmountObject = new JSONObject();
        JSONArray paidSourceAmountArray = new JSONArray();
        JSONObject paidSourceAmountObject = new JSONObject();
        int totalCount = 0;
        int paidTotalCount = 0;
        BigDecimal totalAmount = new BigDecimal(0);
        BigDecimal paidTotalAmount = new BigDecimal(0);
        String beginTime = "";
        String endTime = "";
        //每年合同数量及金额
        if (cmcContract.getSignDate() == null) {
            if (cmcContract.getParams().size() == 0) {
                for (int i = 2019; i <= Calendar.getInstance().get(Calendar.YEAR); i++) {
                    cmcContract.setContractCode("HT" + String.valueOf(i));
                    List<CmcContract> yearContractList = cmcContractService.selectCmcContractList(cmcContract);
                    cmcContract.setContractCode("-" + (i - 2000));
                    yearContractList.addAll(cmcContractService.selectCmcContractList(cmcContract));
                    int yearCountI = yearContractList.size();
                    int paidYearCountI = 0;
                    BigDecimal yearAmountI = new BigDecimal(0);
                    BigDecimal paidAmountI = new BigDecimal(0);
                    for (CmcContract contract : yearContractList) {
                        if (contract.getAmount() != null) {
                            yearAmountI = yearAmountI.add(contract.getAmount());
                            if (contract.getPaidAmount() != null) {
                                paidAmountI = paidAmountI.add(contract.getPaidAmount());
                                paidYearCountI++;
                            }
                        }
                    }
                    totalCount += yearCountI;
                    paidTotalCount += paidYearCountI;
                    totalAmount = totalAmount.add(yearAmountI);
                    paidTotalAmount = paidTotalAmount.add(paidAmountI);
                    yearCountObject.put(String.valueOf(i), yearCountI);
                    paidYearCountObject.put(String.valueOf(i), paidYearCountI);
                    yearAmountObject.put(String.valueOf(i), yearAmountI);
                    paidYearAmountObject.put(String.valueOf(i), paidAmountI);
                }
            }
            else {
                beginTime = (String) cmcContract.getParams().get("beginTime");
                endTime = (String) cmcContract.getParams().get("endTime");
                List<String> monthList = DateUtils.getMonthBetweenDate(beginTime, endTime);
                for (int i = 0; i < monthList.size(); i++) {
                    String beginTimeString = monthList.get(i) + "-01";
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(Calendar.YEAR, Integer.parseInt(monthList.get(i).split("-")[0]));
                    calendar.set(Calendar.MONTH, Integer.parseInt(monthList.get(i).split("-")[1]) - 1);
                    calendar.set(Calendar.DAY_OF_MONTH, 1);
                    String endTimeString = monthList.get(i) + "-" + calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                    Map<String, Object> params = new HashMap<>();
                    params.put("beginTime", beginTimeString + " 00:00:00");
                    params.put("endTime", endTimeString + " 23:59:59");
                    cmcContract.setParams(params);
                    List<CmcContract> monthContractList = cmcContractService.selectCmcContractListByRange(cmcContract);
                    int monthCount = monthContractList.size();
                    int paidMonthCount = 0;
                    BigDecimal monthAmount = new BigDecimal(0);
                    BigDecimal paidMonthAmount = new BigDecimal(0);
                    for (CmcContract contract : monthContractList) {
                        if (contract.getAmount() != null) {
                            monthAmount = monthAmount.add(contract.getAmount());
                            if (contract.getPaidAmount() != null) {
                                paidMonthAmount = paidMonthAmount.add(contract.getPaidAmount());
                                paidMonthCount++;
                            }
                        }
                    }
                    totalCount += monthCount;
                    paidTotalCount += paidMonthCount;
                    totalAmount = totalAmount.add(monthAmount);
                    paidTotalAmount = paidTotalAmount.add(paidMonthAmount);
                    monthCountObject.put(monthList.get(i), monthCount);
                    monthAmountObject.put(monthList.get(i),monthAmount);
                    paidMonthCountObject.put(monthList.get(i), paidMonthCount);
                    paidMonthAmountObject.put(monthList.get(i), paidMonthAmount);
                }
            }
            cmcContract.setContractCode(null);
        }
        else if (cmcContract.getSignDate() != null) {
            //输入年份合同数量及金额
            totalCount = cmcContractService.selectCmcContractList(cmcContract).size();
            yearCountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()), totalCount);
            for (int i = 1; i <= 12; i++) {
                String month = i < 10 ? "0" + i : String.valueOf(i);
                String beginTimeString = new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month + "-01";
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.YEAR, Integer.parseInt(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate())));
                calendar.set(Calendar.MONTH, i - 1);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                String endTimeString = new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month + "-" + calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                Map<String, Object> params = new HashMap<>();
                params.put("beginTime", beginTimeString + " 00:00:00");
                params.put("endTime", endTimeString + " 23:59:59");
                cmcContract.setParams(params);
                List<CmcContract> monthContractList = cmcContractService.selectCmcContractListByRange(cmcContract); 
                int monthCount = monthContractList.size();
                int paidMonthCount = 0;
                BigDecimal monthAmount = new BigDecimal(0);
                BigDecimal paidMonthAmount = new BigDecimal(0);
                for (CmcContract contract : monthContractList) {
                    if (contract.getAmount() != null) {
                        monthAmount = monthAmount.add(contract.getAmount());
                        if (contract.getPaidAmount() != null) {
                            paidMonthAmount = paidMonthAmount.add(contract.getPaidAmount());
                            paidMonthCount++;
                        }
                    }
                }
                monthCountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month, monthCount);
                monthAmountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month,monthAmount);
                paidMonthCountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month, paidMonthCount);
                paidMonthAmountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()) + "-" + month, paidMonthAmount);
            }
            for (CmcContract contract : cmcContractService.selectCmcContractList(cmcContract)) {
                if (contract.getAmount() != null) {
                    totalAmount = totalAmount.add(contract.getAmount());
                    if (contract.getPaidAmount() != null) {
                        paidTotalAmount = paidTotalAmount.add(contract.getPaidAmount());
                        paidTotalCount++;
                    }
                }
            }
            paidYearCountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()), paidTotalCount);
            yearAmountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()), totalAmount);
            paidYearAmountObject.put(new SimpleDateFormat("yyyy").format(cmcContract.getSignDate()), paidTotalAmount);
        }
        if (!endTime.equals("")) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, Integer.parseInt(endTime.split("-")[0]));
            calendar.set(Calendar.MONTH, Integer.parseInt(endTime.split("-")[1]) - 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            endTime = endTime.split("-")[0] + "-" + endTime.split("-")[1] + "-"
                    + calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        getProjectSourceStatistic(cmcContract, sourceCountObject, paidSourceCountObject, sourceAmountObject, paidSourceAmountObject, totalCount, paidTotalCount, totalAmount, paidTotalAmount, beginTime, endTime);
        yearCountArray.add(yearCountObject);
        monthCountArray.add(monthCountObject);
        sourceCountArray.add(sourceCountObject);
        yearAmountArray.add(yearAmountObject);
        monthAmountArray.add(monthAmountObject);
        sourceAmountArray.add(sourceAmountObject);
        paidYearCountArray.add(paidYearCountObject);
        paidMonthCountArray.add(paidMonthCountObject);
        paidSourceCountArray.add(paidSourceCountObject);
        paidYearAmountArray.add(paidYearAmountObject);
        paidMonthAmountArray.add(paidMonthAmountObject);
        paidSourceAmountArray.add(paidSourceAmountObject);
        jsonObject.put("yearCount", yearCountArray);
        jsonObject.put("monthCount", monthCountArray);
        jsonObject.put("sourceCount", sourceCountArray);
        jsonObject.put("yearAmount", yearAmountArray);
        jsonObject.put("monthAmount", monthAmountArray);
        jsonObject.put("sourceAmount", sourceAmountArray);
        jsonObject.put("paidYearCount", paidYearCountArray);
        jsonObject.put("paidMonthCount", paidMonthCountArray);
        jsonObject.put("paidSourceCount", paidSourceCountArray);
        jsonObject.put("paidYearAmount", paidYearAmountArray);
        jsonObject.put("paidMonthAmount", paidMonthAmountArray);
        jsonObject.put("paidSourceAmount", paidSourceAmountArray);
        return success(jsonObject);
    }

    /**
     * 导出cmc合同评审列表
     */
    @Log(title = "cmc合同评审", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CmcContract cmcContract)
    {
        List<CmcContract> list;
        if (cmcContract.getQueryString() != null && !cmcContract.getQueryString().equals(""))
            list = cmcContractService.selectCmcContractListFuzzy(cmcContract);
        else
            list = cmcContractService.selectCmcContractList(cmcContract);
        ExcelUtil<CmcContract> util = new ExcelUtil<CmcContract>(CmcContract.class);
        util.exportExcel(response, list, "cmc合同评审数据");
    }

    /**
     * 导出选择字段cmc合同评审列表
     */
    @Log(title = "cmc合同评审", businessType = BusinessType.EXPORT)
    @PostMapping("/exportSelectFields")
    public void export(HttpServletResponse response, CmcContract cmcContract, String selectFields)
    {
        List<CmcContract> list;
        if (cmcContract.getQueryString() != null && !cmcContract.getQueryString().equals(""))
            list = cmcContractService.selectCmcContractListFuzzy(cmcContract);
        else
            list = cmcContractService.selectCmcContractList(cmcContract);
        List<String> selectFieldList = Arrays.asList(selectFields.split(","));
        ExcelUtil<CmcContract> util = new ExcelUtil<CmcContract>(CmcContract.class);
        util.exportExcel(response, selectFieldList, list, "cmc合同评审数据", StringUtils.EMPTY);
    }

    /**
     * 获取cmc合同评审详细信息
     */
    @GetMapping(value = "/{contractId}")
    public AjaxResult getInfo(@PathVariable("contractId") String contractId)
    {
        return success(cmcContractService.selectCmcContractByContractId(contractId));
    }

    /**
     * 通过合同id获取cmc合同评审统计信息
     */
    @GetMapping(value = "statistic/{contractId}")
    public AjaxResult getContractStatisticByContractId(@PathVariable("contractId") String contractId)
    {
        return success(cmcContractService.selectCmcContractStatisticByContractId(contractId));
    }

    /**
     * cmc合同评审统计信息按字段排序
     */
    @GetMapping( "/sort")
    public AjaxResult getContractStatisticSortByField(String field)
    {
        JSONObject jsonObject = new JSONObject();
        List<CmcContract> cmcContractList = cmcContractService.selectCmcContractStatistic();
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(cmcContractList));
        if (field == null || field.equals("")) {
            jsonObject.put("sort", jsonArray);
        }else if (field.equals("amount")) {
            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("amount").subtract(((JSONObject)a).getBigDecimal("amount")).intValue());
            jsonObject.put("sort", jsonArray);
        }else if (field.equals("subAmount")) {
            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("subAmount").subtract(((JSONObject)a).getBigDecimal("subAmount")).intValue());
            jsonObject.put("sort", jsonArray);
        }else if (field.equals("budgetAmount")) {
            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("budgetAmount").subtract(((JSONObject)a).getBigDecimal("budgetAmount")).intValue());
            jsonObject.put("sort", jsonArray);
        }else if (field.equals("borrowAmount")) {
            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("borrowAmount").subtract(((JSONObject)a).getBigDecimal("borrowAmount")).intValue());
            jsonObject.put("sort", jsonArray);
        }else if (field.equals("settleAmount")) {
            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("settleAmount").subtract(((JSONObject)a).getBigDecimal("settleAmount")).intValue());
            jsonObject.put("sort", jsonArray);
        }
        return success(jsonObject);
    }

    /**
     * 新增cmc合同评审
     */
    @Log(title = "cmc合同评审", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CmcContract cmcContract)
    {
        return toAjax(cmcContractService.insertCmcContract(cmcContract));
    }

    /**
     * 修改cmc合同评审
     */
    @Log(title = "cmc合同评审", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CmcContract cmcContract)
    {
        return toAjax(cmcContractService.updateCmcContract(cmcContract));
    }

    /**
     * 删除cmc合同评审
     */
    @Log(title = "cmc合同评审", businessType = BusinessType.DELETE)
	@DeleteMapping("/{contractIds}")
    public AjaxResult remove(@PathVariable String[] contractIds)
    {
        return success(cmcContractService.deleteCmcContractByContractIds(contractIds));
    }

    //院内外项目数量及金额
    public void getProjectSourceStatistic(CmcContract cmcContract, JSONObject sourceCountObject, JSONObject paidSourceCountObject, JSONObject sourceAmountObject, JSONObject paidSourceAmountObject,
                                          int totalCount, int paidTotalCount, BigDecimal totalAmount, BigDecimal paidTotalAmount, String beginTime, String endTime) {
        int cCount;
        int wCount;
        int nCount;
        int paidCCount = 0;
        int paidWCount = 0;
        int paidNCount;
        BigDecimal cAmount = new BigDecimal(0);
        BigDecimal wAmount = new BigDecimal(0);
        BigDecimal nAmount;
        BigDecimal paidCAmount = new BigDecimal(0);
        BigDecimal paidWAmount = new BigDecimal(0);
        BigDecimal paidNAmount;
        cmcContract.setProjectSource("1");
        List<CmcContract> sourceList;
        if (beginTime.equals(""))
            sourceList = cmcContractService.selectCmcContractListP(cmcContract);
        else {
            Map<String, Object> params = new HashMap<>();
            params.put("beginTime", beginTime + " 00:00:00");
            params.put("endTime", endTime + " 23:59:59");
            cmcContract.setParams(params);
            sourceList = cmcContractService.selectCmcContractListByRange(cmcContract);
        }
        wCount = sourceList.size();
        for (CmcContract contract : sourceList) {
            if (contract.getAmount() != null) {
                wAmount = wAmount.add(contract.getAmount());
                if (contract.getPaidAmount() != null) {
                    paidWAmount = paidWAmount.add(contract.getPaidAmount());
                    if (contract.getPaidAmount().compareTo(contract.getAmount()) >= 0)
                        paidWCount++;
                }
            }
        }
        nCount = totalCount - wCount;
        paidNCount = paidTotalCount - wCount;
        nAmount = totalAmount.subtract(wAmount);
        paidNAmount = paidTotalAmount.subtract(paidWAmount);
        sourceCountObject.put("院外项目", wCount);
        paidSourceCountObject.put("已完成回款院外项目", paidWCount);
        sourceAmountObject.put("院外项目承接金额", wAmount);
        paidSourceAmountObject.put("院外项目回款金额", paidWAmount);
        cmcContract.setProjectSource("0");
        if (beginTime.equals(""))
            sourceList = cmcContractService.selectCmcContractListP(cmcContract);
        else {
            Map<String, Object> params = new HashMap<>();
            params.put("beginTime", beginTime + " 00:00:00");
            params.put("endTime", endTime + " 23:59:59");
            cmcContract.setParams(params);
            sourceList = cmcContractService.selectCmcContractListByRange(cmcContract);
        }
        cCount = sourceList.size();
        for (CmcContract contract : sourceList) {
            if (contract.getAmount() != null) {
                cAmount = cAmount.add(contract.getAmount());
                if (contract.getPaidAmount() != null) {
                    paidCAmount = paidCAmount.add(contract.getPaidAmount());
                    if (contract.getPaidAmount().compareTo(contract.getAmount()) >= 0)
                        paidCCount++;
                }
            }
        }
        nCount = nCount - cCount;
        paidNCount = paidNCount - cCount;
        nAmount = nAmount.subtract(cAmount);
        paidNAmount = paidNAmount.subtract(paidCAmount);
        sourceCountObject.put("院内项目", cCount);
        paidSourceCountObject.put("已完成回款院内项目", paidCCount);
        sourceAmountObject.put("院内项目承接金额", cAmount);
        paidSourceAmountObject.put("院内项目回款金额", paidCAmount);
        cmcContract.setProjectSource(null);
        sourceCountObject.put("未关联项目", nCount);
        paidSourceCountObject.put("已完成回款未关联项目", paidNCount);
        sourceAmountObject.put("未关联项目承接金额", nAmount);
        paidSourceAmountObject.put("未关联项目回款金额", paidNAmount);
    }

}
