package com.ruoyi.buyerapi.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.DynaBean;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.buyerapi.domain.*;
import com.ruoyi.buyerapi.mapper.BuyerAuxiliaryVoucherMapper;
import com.ruoyi.buyerapi.mapper.BuyerProjectMapper;
import com.ruoyi.buyerapi.mapper.BuyerVoucherProjectMapper;
import com.ruoyi.buyerapi.service.IBuyerVoucherProjectService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.buyerapi.mapper.BuyerVoucherInfoMapper;
import com.ruoyi.buyerapi.service.IBuyerVoucherInfoService;

/**
 * 辅助帐凭证详细列Service业务层处理
 *
 * @author ruoyi
 * @date 2022-09-22
 */
@Service
public class BuyerVoucherInfoServiceImpl implements IBuyerVoucherInfoService
{
    @Autowired
    private BuyerVoucherInfoMapper buyerVoucherInfoMapper;

    @Autowired
    private BuyerAuxiliaryVoucherMapper buyerAuxiliaryVoucherMapper;

    @Autowired
    private SysDictDataMapper dictDataMapper;

    @Autowired
    private BuyerVoucherProjectMapper buyerVoucherProjectMapper;

    @Autowired
    private BuyerProjectMapper buyerProjectMapper;

    /**
     * 查询辅助帐凭证详细列
     *
     * @param id 辅助帐凭证详细列主键
     * @return 辅助帐凭证详细列
     */
    @Override
    public BuyerVoucherInfo selectBuyerVoucherInfoById(Long id)
    {
        return buyerVoucherInfoMapper.selectBuyerVoucherInfoById(id);
    }

    /**
     * 查询辅助帐凭证详细列列表
     *
     * @param buyerVoucherInfo 辅助帐凭证详细列
     * @return 辅助帐凭证详细列
     */
    @Override
    public List<BuyerVoucherInfo> selectBuyerVoucherInfoList(BuyerVoucherInfo buyerVoucherInfo)
    {
        return buyerVoucherInfoMapper.selectBuyerVoucherInfoList(buyerVoucherInfo);
    }

    @Override
    public List<BuyerVoucherInfoExport> selectBuyerVoucherInfoListExport(String projectId) {
        List<BuyerVoucherInfoExport> result = new ArrayList<>();
        BuyerVoucherInfoExport totalBean = new BuyerVoucherInfoExport();
        totalBean.setDate("合计金额");

        // 获取当前凭证字典
        List<SysDictData> subjects = dictDataMapper.selectDictDataByType("voucher_type");

        // 查询当前项目下所有凭证列表
        BuyerAuxiliaryVoucher buyerAuxiliaryVoucher = new BuyerAuxiliaryVoucher();
        buyerAuxiliaryVoucher.setProjectId(projectId);
        buyerAuxiliaryVoucher.setDeptId(SecurityUtils.getCompanyId());
        List<BuyerAuxiliaryVoucher> vouchers = buyerAuxiliaryVoucherMapper.selectBuyerAuxiliaryVoucherList(buyerAuxiliaryVoucher);

        // 凭证列表
        for(BuyerAuxiliaryVoucher voucher : vouchers){

            BuyerVoucherInfo buyerVoucherInfo = new BuyerVoucherInfo();
            buyerVoucherInfo.setVoucherId(voucher.getId());
            List<BuyerVoucherInfo> voucherInfos = buyerVoucherInfoMapper.selectBuyerVoucherInfoList(buyerVoucherInfo);

            // 凭证详情列表
            for(int i = 0; i < voucherInfos.size(); i++){
                BuyerVoucherInfoExport bean = new BuyerVoucherInfoExport();
                if(i == 0){
                    bean.setDate(DateUtil.format(voucher.getDate(), "yyyy-MM-dd"));
                    for(SysDictData data : subjects){
                        if(data.getDictValue().equals(voucher.getType())){
                            bean.setType(data.getDictLabel());
                            break;
                        }
                    }
                    bean.setCode(voucher.getCode());
                    // 查询凭证详细列表
                }
                BuyerVoucherInfo voucherInfo = voucherInfos.get(i);
                bean.setSummary(voucherInfo.getSummary());
                // 查询关联项目数据
                BuyerVoucherProject project = new BuyerVoucherProject();
                project.setVoucherId(voucherInfo.getVoucherId());
                project.setSubject(buyerVoucherInfo.getSubject2());
                project.setProjectId(projectId);
                List<BuyerVoucherProject> projectList = buyerVoucherProjectMapper.selectBuyerVoucherProjectList(project);

                if(null != projectList && projectList.size() > 0) {
                    if ("type1".equals(projectList.get(0).getSubject())) {
                        bean.setType1Amount(projectList.get(0).getPrice());
                    } else if ("type2".equals(projectList.get(0).getSubject())) {
                        bean.setType2Amount(projectList.get(0).getPrice());
                    } else if ("type3".equals(projectList.get(0).getSubject())) {
                        bean.setType3Amount(projectList.get(0).getPrice());
                    } else if ("type4".equals(projectList.get(0).getSubject())) {
                        bean.setType4Amount(projectList.get(0).getPrice());
                    } else if ("type5".equals(projectList.get(0).getSubject())) {
                        bean.setType5Amount(projectList.get(0).getPrice());
//                    } else if ("type6".equals(projectList.get(0).getSubject())) {
//                        bean.setType6Amount(projectList.get(0).getPrice());
                    } else if ("type7".equals(projectList.get(0).getSubject())) {
                        bean.setType7Amount(projectList.get(0).getPrice());
                    } else if ("type8".equals(projectList.get(0).getSubject())) {
                        bean.setType8Amount(projectList.get(0).getPrice());
                    } else if ("type9".equals(projectList.get(0).getSubject())) {
                        bean.setType9Amount(projectList.get(0).getPrice());
                    }
                    bean.setAccountAmount(bean.getAccountAmount().add(projectList.get(0).getPrice()));
                }
                totalBean.setAccountAmount(totalBean.getAccountAmount().add(bean.getAccountAmount()));
                totalBean.setType1Amount(totalBean.getType1Amount().add(bean.getType1Amount()));
                totalBean.setType2Amount(totalBean.getType2Amount().add(bean.getType2Amount()));
                totalBean.setType3Amount(totalBean.getType3Amount().add(bean.getType3Amount()));
                totalBean.setType4Amount(totalBean.getType4Amount().add(bean.getType4Amount()));
                totalBean.setType5Amount(totalBean.getType5Amount().add(bean.getType5Amount()));
//                totalBean.setType6Amount(totalBean.getType6Amount().add(bean.getType6Amount()));
                totalBean.setType7Amount(totalBean.getType7Amount().add(bean.getType7Amount()));
                totalBean.setType8Amount(totalBean.getType8Amount().add(bean.getType8Amount()));
                totalBean.setType9Amount(totalBean.getType8Amount().add(bean.getType9Amount()));
                bean.setExpenseType("1".equals(voucher.getExpenseType())?"资本化支出":"费用化支出");
                result.add(bean);
            }
        }
        result.add(totalBean);
        return result;
    }

    @Override
    public List<BuyerVoucherInfoTotalExport> totalVoucherInfoList(String[] projectIds) {
        List<BuyerVoucherInfoTotalExport> result = new ArrayList<>();

        // 获取当前凭证字典
        List<SysDictData> subjects = dictDataMapper.selectDictDataByType("buyer_project_status");
        // 查询项目列表
        BuyerProject buyerProject = new BuyerProject();
        buyerProject.setCompanyId(SecurityUtils.getCompanyId());
        if (null != projectIds && projectIds.length > 0) {
            buyerProject.setIds(projectIds);
        }
        List<BuyerProject> projects = buyerProjectMapper.selectBuyerProjectList(buyerProject);
        // 金额合计
        BuyerVoucherInfoTotalExport totalBean = new BuyerVoucherInfoTotalExport();
        totalBean.setProjectCode("金额合计");

        // 其中：其他事项
        BuyerVoucherInfoTotalExport otherBean = new BuyerVoucherInfoTotalExport();
        otherBean.setProjectCode("其中：其他事项");

        // 资本化合计
        BuyerVoucherInfoTotalExport expenseType1Bean = new BuyerVoucherInfoTotalExport();
        expenseType1Bean.setProjectCode("资本化合计");

        // 费用化合计
        BuyerVoucherInfoTotalExport expenseType2Bean = new BuyerVoucherInfoTotalExport();
        expenseType2Bean.setProjectCode("费用化合计");

        for(BuyerProject project : projects){
            // 查询关联项目数据
            BuyerVoucherProject _voucherProject = new BuyerVoucherProject();
            _voucherProject.setProjectId(project.getId());
            List<BuyerVoucherProject> projectList = buyerVoucherProjectMapper.selectBuyerVoucherProjectList(_voucherProject);

            // 根据支出类型分组
            Map<String,List<BuyerVoucherProject>> mapListOfExpenseType = projectList.stream().collect(Collectors.groupingBy(BuyerVoucherProject::getExpenseType));

            // 根据支出类型 分组
            for(Object key : mapListOfExpenseType.keySet()){
                BuyerVoucherInfoTotalExport bean = new BuyerVoucherInfoTotalExport();
                // 判断是否为第一个
                if(key.equals(mapListOfExpenseType.keySet().toArray()[0])){
                    bean.setProjectCode(project.getCode());
                    bean.setProjectName(project.getName());
                    for(SysDictData data : subjects){
                        if(data.getDictValue().equals(project.getStatus())){
                            bean.setProjectStatus(data.getDictLabel());
                            break;
                        }
                    }
                }

                // 判断是否为第一个
                bean.setExpenseType("1".equals(key) ? "资本化支出" : "费用化支出");
                List<BuyerVoucherProject> expenseTypes = mapListOfExpenseType.get(key);
                // 遍历关联项目
                for(int i = 0; i < expenseTypes.size(); i++){
                    if ("type1".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType1Amount(bean.getType1Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type2".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType2Amount(bean.getType2Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type3".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType3Amount(bean.getType3Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type4".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType4Amount(bean.getType4Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type5".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType5Amount(bean.getType5Amount().add(expenseTypes.get(i).getPrice()));
//                    } else if ("type6".equals(expenseTypes.get(i).getSubject())) {
//                        bean.setType6Amount(bean.getType6Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type7".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType7Amount(bean.getType7Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type8".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType8Amount(bean.getType8Amount().add(expenseTypes.get(i).getPrice()));
                    } else if ("type9".equals(expenseTypes.get(i).getSubject())) {
                        bean.setType9Amount(bean.getType9Amount().add(expenseTypes.get(i).getPrice()));
                    }
                }
                // 统计前6项
                bean.setType66Amount(
//                        bean.getType6Amount().add(
                            bean.getType5Amount().add(
                                bean.getType4Amount().add(
                                    bean.getType3Amount().add(
                                        bean.getType2Amount().add(
                                            bean.getType1Amount())))));
                bean.setType81Amount(bean.getType8Amount().multiply(BigDecimal.valueOf(0.8)));
                bean.setDeductionAmount(bean.getType66Amount()
                        .add(bean.getType71Amount())
                        .add(bean.getType81Amount())
                        .add(bean.getType91Amount()));

                // 处理金额合计
                totalBean.setType1Amount(totalBean.getType1Amount().add(bean.getType1Amount()));
                totalBean.setType2Amount(totalBean.getType2Amount().add(bean.getType2Amount()));
                totalBean.setType3Amount(totalBean.getType3Amount().add(bean.getType3Amount()));
                totalBean.setType4Amount(totalBean.getType4Amount().add(bean.getType4Amount()));
                totalBean.setType5Amount(totalBean.getType5Amount().add(bean.getType5Amount()));
//                totalBean.setType6Amount(totalBean.getType6Amount().add(bean.getType6Amount()));
                totalBean.setType66Amount(totalBean.getType66Amount().add(bean.getType66Amount()));
                totalBean.setType7Amount(totalBean.getType7Amount().add(bean.getType7Amount()));
                totalBean.setType8Amount(totalBean.getType8Amount().add(bean.getType8Amount()));
                totalBean.setType81Amount(totalBean.getType81Amount().add(bean.getType81Amount()));
                totalBean.setType9Amount(totalBean.getType8Amount().add(bean.getType9Amount()));

                // 处理支出类型统计
                if("1".equals(key)){
                    expenseType1Bean.setType1Amount(expenseType1Bean.getType1Amount().add(bean.getType1Amount()));
                    expenseType1Bean.setType2Amount(expenseType1Bean.getType2Amount().add(bean.getType2Amount()));
                    expenseType1Bean.setType3Amount(expenseType1Bean.getType3Amount().add(bean.getType3Amount()));
                    expenseType1Bean.setType4Amount(expenseType1Bean.getType4Amount().add(bean.getType4Amount()));
                    expenseType1Bean.setType5Amount(expenseType1Bean.getType5Amount().add(bean.getType5Amount()));
//                    expenseType1Bean.setType6Amount(expenseType1Bean.getType6Amount().add(bean.getType6Amount()));
                    expenseType1Bean.setType66Amount(expenseType1Bean.getType66Amount().add(bean.getType66Amount()));
                    expenseType1Bean.setType7Amount(expenseType1Bean.getType7Amount().add(bean.getType7Amount()));
                    expenseType1Bean.setType8Amount(expenseType1Bean.getType8Amount().add(bean.getType8Amount()));
                    expenseType1Bean.setType81Amount(expenseType1Bean.getType81Amount().add(bean.getType81Amount()));
                    expenseType1Bean.setType9Amount(expenseType1Bean.getType8Amount().add(bean.getType9Amount()));
                }else{
                    expenseType2Bean.setType1Amount(expenseType2Bean.getType1Amount().add(bean.getType1Amount()));
                    expenseType2Bean.setType2Amount(expenseType2Bean.getType2Amount().add(bean.getType2Amount()));
                    expenseType2Bean.setType3Amount(expenseType2Bean.getType3Amount().add(bean.getType3Amount()));
                    expenseType2Bean.setType4Amount(expenseType2Bean.getType4Amount().add(bean.getType4Amount()));
                    expenseType2Bean.setType5Amount(expenseType2Bean.getType5Amount().add(bean.getType5Amount()));
//                    expenseType2Bean.setType6Amount(expenseType2Bean.getType6Amount().add(bean.getType6Amount()));
                    expenseType2Bean.setType66Amount(expenseType2Bean.getType66Amount().add(bean.getType66Amount()));
                    expenseType2Bean.setType7Amount(expenseType2Bean.getType7Amount().add(bean.getType7Amount()));
                    expenseType2Bean.setType8Amount(expenseType2Bean.getType8Amount().add(bean.getType8Amount()));
                    expenseType2Bean.setType81Amount(expenseType2Bean.getType81Amount().add(bean.getType81Amount()));
                    expenseType2Bean.setType9Amount(expenseType2Bean.getType8Amount().add(bean.getType9Amount()));
                }
                result.add(bean);
            }
        }
        BigDecimal type71Amount2 = totalBean.getType66Amount()
                .multiply(BigDecimal.valueOf(0.1))
                .divide(BigDecimal.valueOf(0.9), 2);
        totalBean.setType71Amount(type71Amount2.compareTo(totalBean.getType7Amount()) > 0
                ? totalBean.getType7Amount() : type71Amount2);

        BigDecimal type91Amount1 = (totalBean.getType66Amount()
                .add(totalBean.getType71Amount())
                .add(totalBean.getType81Amount()))
                .multiply(BigDecimal.valueOf(2))
                .divide(BigDecimal.valueOf(3), 2);
        BigDecimal type91Amount2 = totalBean.getType9Amount().multiply(BigDecimal.valueOf(0.8));
                totalBean.setType91Amount(otherBean.getType91Amount());
        totalBean.setType91Amount(type91Amount1.compareTo(type91Amount2) > 0 ? type91Amount2 : type91Amount1);

        // 处理其他
        result.add(expenseType1Bean);
        result.add(expenseType2Bean);
        result.add(otherBean);
        totalBean.setDeductionAmount(totalBean.getType66Amount()
                .add(totalBean.getType71Amount())
                .add(totalBean.getType81Amount())
                .add(totalBean.getType91Amount()));
        result.add(totalBean);
        return result;
    }

    /**
     * 新增辅助帐凭证详细列
     *
     * @param buyerVoucherInfo 辅助帐凭证详细列
     * @return 结果
     */
    @Override
    public int insertBuyerVoucherInfo(BuyerVoucherInfo buyerVoucherInfo)
    {
        buyerVoucherInfo.setCreateTime(DateUtils.getNowDate());
        return buyerVoucherInfoMapper.insertBuyerVoucherInfo(buyerVoucherInfo);
    }

    /**
     * 修改辅助帐凭证详细列
     *
     * @param buyerVoucherInfo 辅助帐凭证详细列
     * @return 结果
     */
    @Override
    public int updateBuyerVoucherInfo(BuyerVoucherInfo buyerVoucherInfo)
    {
        buyerVoucherInfo.setUpdateTime(DateUtils.getNowDate());
        return buyerVoucherInfoMapper.updateBuyerVoucherInfo(buyerVoucherInfo);
    }

    /**
     * 批量删除辅助帐凭证详细列
     *
     * @param ids 需要删除的辅助帐凭证详细列主键
     * @return 结果
     */
    @Override
    public int deleteBuyerVoucherInfoByIds(Long[] ids)
    {
        return buyerVoucherInfoMapper.deleteBuyerVoucherInfoByIds(ids);
    }

    /**
     * 删除辅助帐凭证详细列信息
     *
     * @param id 辅助帐凭证详细列主键
     * @return 结果
     */
    @Override
    public int deleteBuyerVoucherInfoById(Long id)
    {
        return buyerVoucherInfoMapper.deleteBuyerVoucherInfoById(id);
    }
}
