package com.gree.mall.manager.logic.settle.repair;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.ExcelData;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.settle.repair.DailyMonthTotalBean;
import com.gree.mall.manager.bean.settle.repair.DailyNotMonthSummaryCountBean;
import com.gree.mall.manager.bean.settle.repair.DailyWorkerIssueSalaryBean;
import com.gree.mall.manager.commonmapper.DailyMapper;
import com.gree.mall.manager.constant.DailyConstant;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.SettleDailyIssueSummaryMonthRecord;
import com.gree.mall.manager.plus.entity.SettleDailyIssueSummaryRecord;
import com.gree.mall.manager.plus.entity.SettleDailyMonthlySummary;
import com.gree.mall.manager.plus.service.SettleDailyIssueSummaryMonthRecordService;
import com.gree.mall.manager.plus.service.SettleDailyIssueSummaryRecordService;
import com.gree.mall.manager.plus.service.SettleDailyMonthlySummaryService;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class DailyMonthSummaryLogic {

    private final CommonLogic commonLogic;
    private final DailyMapper dailyMapper;
    private final SettleDailyIssueSummaryMonthRecordService issueSummaryMonthRecordService;
    private final SettleDailyMonthlySummaryService dailyMonthlySummaryService;
    private final SettleDailyIssueSummaryRecordService dailyIssueSummaryRecordService;
    private final DailyTransferLogic dailyTransferLogic;
    private final SettleDailyIssueSummaryMonthRecordService dailyIssueSummaryMonthRecordService;

    /**
     * 导出师傅月结数据汇总
     *
     * @param list
     * @return
     */
    public ExcelData monthSalaryExport(List<SettleDailyIssueSummaryMonthRecord> list) {
        String[] titles = new String[]{"工资条编号", "汇总月份", "状态", "所属网点", "所属网点编号", "服务人员", "服务人员编号", "身份证", "手机号",
                "维修结算费用总额", "需扣回费用", "增减费用", "月度计税费用总额",
                "工伤保险", "残保金", "服务费用", "个税金额", "应发工资总额", "日结累计已发", "月度实发工资",
                "工伤保险已扣", "残保金已扣", "暂扣费用累计", "备注"};
        List<List<Object>> rows = new ArrayList<>();
        for (SettleDailyIssueSummaryMonthRecord bean : list) {
            List<Object> row = new ArrayList<>();
            row.add(bean.getSalaryNo());
            row.add(bean.getMonth());
            row.add(CommonUtils.getIssueStatus(bean.getStatus()));
            row.add(bean.getWebsitName());
            row.add(bean.getWebsitNumber());
            row.add(bean.getServiceName());
            row.add(bean.getServiceNumber());
            row.add(bean.getIdCard());
            row.add(bean.getMobile());
            row.add(bean.getRepairTotalAmount());
            row.add(bean.getShouldReduceCost());
            row.add(bean.getIncrDecrCost());
            row.add(bean.getTaxToatalCost());
            row.add(bean.getShouldEmpInsuranceCost());
            row.add(bean.getShouldResidualInsuranceCost());
            row.add(bean.getServiceCost());
            row.add(bean.getIncomeCost());
            row.add(bean.getIssueCost());
            row.add(bean.getDailySendCost());
            row.add(bean.getMonthSendCost());
            row.add(bean.getEmpInsuranceCost());
            row.add(bean.getResidualInsuranceCost());
            row.add(bean.getWithholdTotalCost());
            row.add(bean.getRemark());
            // row.add(DateUtils.formatDate(bean.getCreateTime()));
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    @Transactional
    public void monthSalaryImport(MultipartFile file) throws IOException {
        List<Map<String, Object>> maps = ExcelUtils.importExcelByTitle(file.getInputStream(), 0);
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        String opName = adminUser.getNickName();

        List<SettleDailyIssueSummaryMonthRecord> issueSummaryMonthRecords = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            SettleDailyIssueSummaryMonthRecord tmp = issueSummaryMonthRecordService
                    .lambdaQuery()
                    .eq(SettleDailyIssueSummaryMonthRecord::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                    .eq(SettleDailyIssueSummaryMonthRecord::getSalaryNo, map.get("工资条编号").toString())
                    .one();

            if (null == tmp) {
                throw new RemoteServiceException(map.get("工资条编号").toString() + "工资条编号不存在");
            }

            if (!DailyConstant.ISSUE_STATUS_NOT.equals(tmp.getStatus())) {
                throw new RemoteServiceException(map.get("工资条编号").toString() + "状态为已发放");
            }

            if (tmp.getStatus() != 1) {
                throw new RemoteServiceException("存在已发放数据");
            }

            if (map.get("工伤保险") != null) {
                tmp.setShouldEmpInsuranceCost(new BigDecimal(map.get("工伤保险").toString()));
            }
            if (map.get("残保金") != null) {
                tmp.setShouldResidualInsuranceCost(new BigDecimal(map.get("残保金").toString()));
            }
            if (map.get("服务费用") != null) {
                tmp.setServiceCost(new BigDecimal(map.get("服务费用").toString()));
            }

            if (map.get("个税金额") != null) {
                tmp.setIncomeCost(new BigDecimal(map.get("个税金额").toString()));
            }

            if (map.get("应发工资总额") != null) {
                tmp.setIssueCost(new BigDecimal(map.get("应发工资总额").toString()));
            }

            tmp.setUpdateBy(opName);
            tmp.setUpdateTime(new Date());
            tmp.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
            tmp.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
            issueSummaryMonthRecords.add(tmp);
        }
        issueSummaryMonthRecordService.updateBatchById(issueSummaryMonthRecords);
    }

    @Transactional
    public void monthSalaryCalculate(String summaryMonthBatchNo, String summaryNumber) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        //月度费用计算
        List<SettleDailyIssueSummaryMonthRecord> monthRecords = issueSummaryMonthRecordService.lambdaQuery()
                .eq(SettleDailyIssueSummaryMonthRecord::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyIssueSummaryMonthRecord::getSummaryBatchNo, summaryMonthBatchNo)
                .eq(SettleDailyIssueSummaryMonthRecord::getSummaryNumber, summaryNumber)
                .eq(SettleDailyIssueSummaryMonthRecord::getStatus, DailyConstant.ISSUE_STATUS_NOT).list();
        if (monthRecords.size() == 0) {
            throw new RemoteServiceException("没有可计算的数据");
        }

        for (SettleDailyIssueSummaryMonthRecord record : monthRecords) {
            //月度实发工资
            if (record.getIssueCost() == null) {
                throw new RemoteServiceException("请先计算好月度应发工资并上传。");
            }
            BigDecimal actual = record.getIssueCost().subtract(record.getDailySendCost());
            record.setMonthSendCost(actual);
            record.setIsMonthCalculate(true);
            record.setUpdateBy(adminUser.getNickName());
            record.setUpdateTime(new Date());
            record.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
            record.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
        }
        issueSummaryMonthRecordService.saveOrUpdateBatch(monthRecords, 500);
    }

    public List<DailyNotMonthSummaryCountBean> monthlySummaryList(String summaryBatchNo) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<DailyNotMonthSummaryCountBean> list = dailyMapper.monthlySummaryList(summaryBatchNo, adminUser.getCompanyWechatIds(), adminUser.getAdminWebsitIds());
        return list;
    }

    public List<DailyNotMonthSummaryCountBean> monthlyWebsiteList(String summaryBatchNo) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        return dailyMapper.monthlyWebsiteList(summaryBatchNo, adminUser.getCompanyWechatIds(), adminUser.getAdminWebsitIds());
    }

    public List<DailyWorkerIssueSalaryBean> monthlyDetailList(String summaryMonthBatchNo, String summaryNumber,
                                                              String serviceNumber, Integer pageNo, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        return dailyMapper.monthlyDetailList(new Page<>(pageNo, pageSize), summaryMonthBatchNo, summaryNumber, serviceNumber, adminUser.getCompanyWechatIds(), adminUser.getAdminWebsitIds());
    }

    @Transactional
    public void monthlyReDo(String summaryMonthBatchNo) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }
        String opName = adminUser.getNickName();
        //拿到当前月份
        String nowMonth = DateUtil.format(new Date(), "yyyyMM");

        Integer count = dailyMonthlySummaryService.lambdaQuery()
                .eq(SettleDailyMonthlySummary::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyMonthlySummary::getSummaryMonthBatchNo, summaryMonthBatchNo)
                .ne(SettleDailyMonthlySummary::getIssueStatus, DailyConstant.SUMMARY_STATUS_NOT)
                .count();
        if (count > 0) {
            throw new RemoteServiceException("已发放，无法重新汇总");
        }
        //删除所有数据
        issueSummaryMonthRecordService.lambdaUpdate()
                .eq(SettleDailyIssueSummaryMonthRecord::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyIssueSummaryMonthRecord::getSummaryBatchNo, summaryMonthBatchNo)
                .remove();

        List<DailyMonthTotalBean> totalBeans = dailyMapper.queryMonthTotalCost(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        //生成每人月度发放数据
        //把所有发放成功数据汇总到当月
        List<SettleDailyIssueSummaryMonthRecord> monthIssues = setMonthIssue(totalBeans, summaryMonthBatchNo, opName, nowMonth);

        issueSummaryMonthRecordService.saveBatch(monthIssues, 500);

        dailyIssueSummaryRecordService.lambdaUpdate()
                .set(SettleDailyIssueSummaryRecord::getIsMonthSummary, true)
                .set(SettleDailyIssueSummaryRecord::getSummaryMonthBatchNo, summaryMonthBatchNo)
                .set(SettleDailyIssueSummaryRecord::getUpdateBy, opName)
                .set(SettleDailyIssueSummaryRecord::getUpdateTime, new Date())
                .set(SettleDailyIssueSummaryRecord::getMonth, nowMonth)
                .eq(SettleDailyIssueSummaryRecord::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyIssueSummaryRecord::getIsMonthSummary, false).update();

        DailyNotMonthSummaryCountBean bean = dailyMapper.queryNotMonthSummaryData(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        //将数据插入汇总表
        SettleDailyMonthlySummary monthlySummary = dailyMonthlySummaryService.lambdaQuery()
                .eq(SettleDailyMonthlySummary::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyMonthlySummary::getSummaryMonthBatchNo, summaryMonthBatchNo)
                .one();
        monthlySummary.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName())
                .setSummaryTime(new Date())
                .setSummaryCost(bean.getSummaryCost())
                .setSummaryOrderCount(bean.getSummaryOrderCount())
                .setSummaryPersonCount(bean.getSummaryPersonCount())
                .setSummaryMonth(nowMonth)
                .updateById();
    }


    public List<SettleDailyIssueSummaryMonthRecord> setMonthIssue(List<DailyMonthTotalBean> totalBeans, String summaryMonthBatchNo, String opName, String nowMonth) {
        List<SettleDailyIssueSummaryMonthRecord> result = new ArrayList<>();
        for (DailyMonthTotalBean totalBean : totalBeans) {
            String monthSalaryNo = commonLogic.generateNo("SF", "monthSalaryNo", 15);
            SettleDailyIssueSummaryMonthRecord monthIssue = new SettleDailyIssueSummaryMonthRecord();
            //设置月度计算为空
            monthIssue.setIsMonthCalculate(false);
            monthIssue.setSummaryBatchNo(summaryMonthBatchNo);
            monthIssue.setSalaryNo(monthSalaryNo);
            monthIssue.setRepairTotalAmount(totalBean.getRepairTotalAmount());
            monthIssue.setDailySendCost(totalBean.getIssueCost());
            //计税金额
            BigDecimal incomeCostTax = new BigDecimal(0);
            if (totalBean.getRepairTotalAmount() != null) {
                incomeCostTax = incomeCostTax.add(totalBean.getRepairTotalAmount());
            }
            if (totalBean.getIncrDecrCost() != null) {
                incomeCostTax = incomeCostTax.add(totalBean.getIncrDecrCost());
            }
            if (totalBean.getReduceCost() != null) {
                incomeCostTax = incomeCostTax.subtract(totalBean.getReduceCost());
            }
            monthIssue.setTaxToatalCost(incomeCostTax);
            monthIssue.setReduceCost(totalBean.getReduceCost());
            monthIssue.setShouldReduceCost(totalBean.getReduceCost());
            monthIssue.setReduceCost(totalBean.getReduceCost());
            monthIssue.setSummaryNumber(totalBean.getSummaryNumber());
            monthIssue.setSummaryName(totalBean.getSummaryName());
            monthIssue.setIncrDecrCost(totalBean.getIncrDecrCost());

            monthIssue.setIdCard(totalBean.getIdCard());
            monthIssue.setMobile(totalBean.getMobile());
            monthIssue.setMonth(nowMonth);
            monthIssue.setWithholdTotalCost(totalBean.getWithholdTotalCost());
            monthIssue.setWithholdCost(totalBean.getWithholdTotalCost());

            monthIssue.setShouldResidualInsuranceCost(totalBean.getResidualInsuranceCostC());
            monthIssue.setResidualInsuranceCost(totalBean.getResidualInsuranceCostC());
            monthIssue.setEmpInsuranceCost(totalBean.getEmpInsuranceCostC());
            monthIssue.setShouldEmpInsuranceCost(totalBean.getEmpInsuranceCostC());

            monthIssue.setServiceName(totalBean.getServiceName());
            monthIssue.setServiceNumber(totalBean.getServiceNumber());
            monthIssue.setWebsitName(totalBean.getWebsitName());
            monthIssue.setWebsitNumber(totalBean.getWebsitNumber());

            monthIssue.setStatus(DailyConstant.ISSUE_STATUS_NOT);

            monthIssue.setSummaryBy(opName);
            monthIssue.setSummaryTime(new Date());
            monthIssue.setCompanyWechatId(totalBean.getCompanyWechatId());
            monthIssue.setCompanyWechatName(totalBean.getCompanyWechatName());
            monthIssue.setRepairCount(totalBean.getRepairCountC());
            result.add(monthIssue);
        }
        return result;
    }

    @Transactional
    public void monthlyDo() {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }
        String opName = adminUser.getJoinNickName();
        //拿到当前月份
        String nowMonth = DateUtil.format(new Date(), "yyyyMM");

        Integer count = dailyMonthlySummaryService.lambdaQuery()
                .eq(SettleDailyMonthlySummary::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyMonthlySummary::getSummaryMonth, nowMonth)
                .count();
        if (count > 0) {
            throw new RemoteServiceException("当前月份已汇总,请勿重复汇总。");
        }
        //生成档次月度汇总批次号
        String monthSummaryBatchNo = commonLogic.generateNo("CW", "monthSummary", 15);
        //生成每人月度发放数据（发放，发放失败数据）
        List<DailyMonthTotalBean> totalBeans = dailyMapper.queryMonthTotalCost(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        if (totalBeans.size() == 0) {
            throw new RemoteServiceException("当前月份已汇总没有已发放数据");
        }

        //把所有发放成功数据汇总到当月
        List<SettleDailyIssueSummaryMonthRecord> monthIssues = setMonthIssue(totalBeans, monthSummaryBatchNo, opName, nowMonth);
        issueSummaryMonthRecordService.saveBatch(monthIssues, 500);

        dailyIssueSummaryRecordService.lambdaUpdate()
                .set(SettleDailyIssueSummaryRecord::getIsMonthSummary, true)
                .set(SettleDailyIssueSummaryRecord::getSummaryMonthBatchNo, monthSummaryBatchNo)
                .set(SettleDailyIssueSummaryRecord::getUpdateBy, opName)
                .set(SettleDailyIssueSummaryRecord::getUpdateTime, new Date())
                .set(SettleDailyIssueSummaryRecord::getMonth, nowMonth)
                .eq(SettleDailyIssueSummaryRecord::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .eq(SettleDailyIssueSummaryRecord::getIsMonthSummary, false)
                .update();
        DailyNotMonthSummaryCountBean bean = dailyMapper.queryNotMonthSummaryData(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        //将数据插入汇总表
        SettleDailyMonthlySummary monthlySummary = new SettleDailyMonthlySummary();
        monthlySummary.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName())
                .setSummaryBy(opName)
                .setSummaryTime(new Date())
                .setSummaryCost(bean.getSummaryCost())
                .setSummaryMonthBatchNo(monthSummaryBatchNo)
                .setSummaryOrderCount(bean.getSummaryOrderCount())
                .setSummaryPersonCount(bean.getSummaryPersonCount())
                .setSummaryMonth(nowMonth)
                .insert();
    }


    @Transactional
    public void monthSalaryIssue(String summaryMonthBatchNo, List<String> summaryNumberList) {
        //验证手机验证码
//        Object validMessageCode = redisUtil.get(Constant.RedisPrefix.ISSUE_SAL_MOBILE_SMS + mobile);
//        if (!code.equals(validMessageCode.toString())){
//            throw new RemoteServiceException("短信验证码输入错误");
//        }
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        Integer count = dailyIssueSummaryMonthRecordService.lambdaQuery()
                .eq(SettleDailyIssueSummaryMonthRecord::getSummaryBatchNo, summaryMonthBatchNo)
                .in(CollectionUtil.isNotEmpty(summaryNumberList), SettleDailyIssueSummaryMonthRecord::getSummaryNumber, summaryNumberList)
                .eq(SettleDailyIssueSummaryMonthRecord::getIsMonthCalculate, false).count();
        if (count > 0) {
            throw new RemoteServiceException("请先进行月度计算");
        }
        summaryNumberList = dailyTransferLogic.issueCheck(summaryMonthBatchNo, summaryNumberList, true, adminUser);
        dailyTransferLogic.issueSalary(summaryMonthBatchNo, summaryNumberList, true, adminUser);
    }


}
