package com.gree.mall.manager.logic.worker;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.notice.NoticeWebsitVO;
import com.gree.mall.manager.bean.worker.WorkerWarrantyDetail;
import com.gree.mall.manager.bean.worker.WorkerWarrantyVO;
import com.gree.mall.manager.commonmapper.NoticeRecordBeanMapper;
import com.gree.mall.manager.enums.admin.AdminWebsitTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.StringUtil;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class WorkerWarrantyLogic {

    @Autowired
    NoticeRecordBeanMapper noticeRecordMapper;

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    WorkerWarrantyService workerWarrantyService;

    @Autowired
    WorkerWarrantyRefundService workerWarrantyRefundService;

    @Autowired
    WebsitUserService websitUserService;

    @Autowired
    UserService userService;

    @Autowired
    AdminWebsitService adminWebsitService;


    @Autowired
    WorkerWarrantyPayService workerWarrantyPayService;

    public IPage<WorkerWarrantyVO> list(Page page, ZfireParamBean zfireParam) {

        //获取当前登录企业id
        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<String> adminCompanyIds = adminUser.getCompanyWechatIds();
        //1.组装查询条件
        zfireParam = FieldUtils.supplyParam(zfireParam, WorkerWarrantyVO.class,adminUser);

        IPage<WorkerWarrantyVO> workerWarrantyVOIPage = noticeRecordMapper.listWarranty(new Page(zfireParam.getPageNum(), zfireParam.getPageSize()), zfireParam, adminCompanyIds);

        return workerWarrantyVOIPage;
    }

    @Transactional(rollbackFor = Exception.class)
    public void refund(WorkerWarrantyRefund workerWarrantyRefund) {
        WorkerWarranty workerWarranty = workerWarrantyService.getById(workerWarrantyRefund.getWarrantyId());

        if (workerWarranty.getRefundAmount().add(workerWarrantyRefund.getRefundAmount()).doubleValue() > workerWarranty.getPayableAmount().doubleValue()) {
            throw new RemoteServiceException("总退金额大于了缴纳金额");
        }

        workerWarranty.setRefundAmount(workerWarranty.getRefundAmount().add(workerWarrantyRefund.getRefundAmount()));
        workerWarranty.setRefundTime(new Date());
        workerWarranty.updateById();
        workerWarrantyRefund.insert();
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(BigDecimal shouldAmount, BigDecimal everyAmount, List<String> websitUserId) {
        List<WorkerWarranty> workerWarranties = new ArrayList<>();

        for (String s : websitUserId) {
            WebsitUser websitUser = websitUserService.getById(s);
            User user = userService.getById(websitUser.getUserId());
            if (workerWarrantyService.lambdaQuery().eq(WorkerWarranty::getMobile,user.getMobile())
                    .count() > 0) {
                throw new RemoteServiceException(user.getNickName()+"师傅已经添加过质保金");
            }

            WorkerWarranty workerWarranty = new WorkerWarranty();
            workerWarranty.setWebsitId(websitUser.getWebsitId());
            workerWarranty.setWebsitName(websitUser.getWebsitName());
            workerWarranty.setCompanyWechatId(websitUser.getCompanyWechatId());
            workerWarranty.setCompanyWechatName(websitUser.getCompanyWechatName());
            workerWarranty.setWorkerId(websitUser.getUserId());
            workerWarranty.setWorkerNumber(websitUser.getWorkerNumber());
            workerWarranty.setWorkerName(user.getNickName());
            workerWarranty.setIdCard(user.getIdCard());
            workerWarranty.setMobile(user.getMobile());
            workerWarranty.setEveryAmount(everyAmount);
            workerWarranty.setShouldAmount(shouldAmount);

            if (workerWarranties.stream().filter(item -> item.getMobile().equals(workerWarranty.getMobile())).count() > 0) {
                continue;
            }

            workerWarranties.add(workerWarranty);
        }


        workerWarrantyService.saveBatch(workerWarranties);
    }

    @Transactional(rollbackFor = Exception.class)
    public void importData(MultipartFile file) throws IOException {

        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<Object> objects = ExcelUtils.importExcel(file);

        List<WorkerWarranty> workerWarranties = new ArrayList<>();
        List<WorkerWarrantyRefund> workerWarrantyRefunds = new ArrayList<>();
        List<WorkerWarrantyPay> workerWarrantyPays = new ArrayList<>();

        List<WorkerWarranty> workerWarrantyList = workerWarrantyService.lambdaQuery()
                .eq(WorkerWarranty::getCompanyWechatId, adminUser.getCompanyWechatId())
                .in(CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds()) && !adminUser.getType().equals(1), WorkerWarranty::getWebsitId, adminUser.getAdminWebsitIds())
                .list();



        //网点名称
/*        Map<String, AdminWebsit> adminWebsitMap = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, adminUser.getCompanyWechatId())
                .in(CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds()) && !adminUser.getType().equals(1), AdminWebsit::getWebsitId, adminUser.getAdminWebsitIds())
                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.C.getKey())
                .list().stream().collect(Collectors.toMap(AdminWebsit::getWebsitId, Function.identity()));
        log.info("网点");*/

        //网点名称
        Map<String, User> userMap = userService.lambdaQuery()
                .eq(User::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(User::getType,"WORKER")
                .ne(User::getMobile,"")
                .isNotNull(User::getMobile)
                .list().stream().collect(Collectors.toMap(User::getMobile, Function.identity()));

        log.info("用户");

        for (int i = 0; i < objects.size(); i++) {
            int rowIndex = i + 2;
            List<Object> row = (List<Object>) objects.get(i);

            AdminWebsit adminWebsit = adminWebsitService.getById((String) row.get(0));
           // AdminWebsit adminWebsit = adminWebsitMap.get((String) row.get(0));
            User user = userMap.get((String) row.get(8));


            WorkerWarranty workerWarranty = new WorkerWarranty();


            workerWarranty.setWebsitId(adminWebsit.getWebsitId());
            workerWarranty.setWebsitName(adminWebsit.getName());



            workerWarranty.setInTime(DateUtil.parse((String)row.get(4), "yyyy-MM-dd"));
            if (!StringUtil.isEmpty((String)row.get(5)))
             workerWarranty.setOutTime(DateUtil.parse((String)row.get(5), "yyyy-MM-dd"));




            workerWarranty.setCompanyWechatId(adminWebsit.getCompanyWechatId());
            workerWarranty.setCompanyWechatName(adminWebsit.getCompanyWechatName());
            workerWarranty.setWorkerNumber(user.getWorkerNumber());
            workerWarranty.setWorkerName(user.getNickName());
            workerWarranty.setIdCard(user.getIdCard());
            workerWarranty.setMobile(user.getMobile());
            workerWarranty.setWorkerId(user.getUserId());
            if (!StringUtil.isEmpty((String)row.get(11)))
                workerWarranty.setEveryAmount(Convert.toBigDecimal(row.get(11)));


            if (!StringUtil.isEmpty((String)row.get(12)))
                workerWarranty.setPayableNum(Convert.toInt(row.get(12)));

            workerWarranty.setShouldAmount(Convert.toBigDecimal(row.get(10)));

            List<WorkerWarranty> workerWarrantyListUp = workerWarrantyList.stream().filter(item -> item.getMobile().equals(workerWarranty.getMobile())

            ).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(workerWarrantyListUp))
                workerWarranty.setWarrantyId(workerWarrantyListUp.get(0).getWarrantyId());
            else
                workerWarranty.setWarrantyId(IdWorker.getIdStr());


            if (!StringUtil.isEmpty((String)row.get(3))) {
                workerWarranty.setRefundAmount(Convert.toBigDecimal(row.get(3)));
                workerWarranty.setRefundTime(DateUtil.parse((String) row.get(2), "yyyy-MM-dd"));

                WorkerWarrantyRefund workerWarrantyRefund = new WorkerWarrantyRefund();
                workerWarrantyRefund.setWarrantyId(workerWarranty.getWarrantyId());
                workerWarrantyRefund.setRefundAmount(workerWarranty.getRefundAmount());
                workerWarrantyRefund.setRefundTime(workerWarranty.getRefundTime());
                workerWarrantyRefunds.add(workerWarrantyRefund);
            }



            if (row.size() > 11) {
                List<WorkerWarrantyPay> workerWarrantyPays1 = this.importPayAmount(row, workerWarranty.getWarrantyId(), rowIndex);
                workerWarrantyPays.addAll(workerWarrantyPays1);

                if (CollectionUtils.isNotEmpty(workerWarrantyListUp))
                    workerWarranty.setPayableAmount(workerWarrantyListUp.get(0).getPayableAmount());
                for (WorkerWarrantyPay workerWarrantyPay : workerWarrantyPays1) {
                    workerWarranty.setPayableAmount(workerWarrantyPay.getPayAmount().add((workerWarranty.getPayableAmount() == null?BigDecimal.ZERO:workerWarranty.getPayableAmount())));
                }
            }

            if (CollectionUtils.isNotEmpty(workerWarrantyListUp) && workerWarranty.getRefundAmount() != null)
                workerWarranty.setRefundAmount(workerWarrantyListUp.get(0).getRefundAmount().add(workerWarranty.getRefundAmount()));

            workerWarranty.setWaitAmount(workerWarranty.getShouldAmount().subtract(workerWarranty.getPayableAmount() == null?BigDecimal.ZERO:workerWarranty.getPayableAmount()));

            if (workerWarranty.getWaitAmount().doubleValue() < 0)
                throw new RemoteServiceException("第"+rowIndex+"行"+"缴纳金额超过应缴纳金额");

            if (workerWarranty.getRefundAmount() != null && workerWarranty.getRefundAmount().doubleValue() > workerWarranty.getPayableAmount().doubleValue()) {
                throw new RemoteServiceException("总退金额大于了缴纳金额");
            }
            workerWarranties.add(workerWarranty);

        }

        if (CollectionUtils.isNotEmpty(workerWarranties))
            workerWarrantyService.saveOrUpdateBatch(workerWarranties);
        if (CollectionUtils.isNotEmpty(workerWarrantyPays))
            workerWarrantyPayService.saveBatch(workerWarrantyPays);
        if (CollectionUtils.isNotEmpty(workerWarrantyRefunds))
            workerWarrantyRefundService.saveBatch(workerWarrantyRefunds);
    }


    private List<WorkerWarrantyPay> importPayAmount(List<Object> row, String id, int index) {

        List<WorkerWarrantyPay> workerWarrantyPays = new ArrayList<>();
        //默认最多10个机型
        for (int i = 0; i < 24; i++) {
            if (row.size() < (2 * i + 14))
                break;
            String payAmount = (String) row.get(2 * i + 13);
            String payAmountTime = (String) row.get(2 * i + 14);

            if (StringUtils.isBlank(payAmount)) {
                continue;
            }

            if (StringUtil.isEmpty(payAmountTime))
                throw new RemoteServiceException("第"+index+"行"+"缴纳时间未填");

            WorkerWarrantyPay workerWarrantyPay = new WorkerWarrantyPay();
            workerWarrantyPay.setWarrantyId(id);
            workerWarrantyPay.setPayAmount(Convert.toBigDecimal(payAmount));
            workerWarrantyPay.setPayTime(DateUtil.parse(payAmountTime, "yyyy-MM-dd"));

            workerWarrantyPays.add(workerWarrantyPay);

        }

        return workerWarrantyPays;

    }


    public WorkerWarrantyDetail detail(String warrantyId) {
        WorkerWarranty workerWarranty = workerWarrantyService.getById(warrantyId);

        WorkerWarrantyDetail workerWarrantyDetail = BeanUtil.toBean(workerWarranty, WorkerWarrantyDetail.class);

        List<WorkerWarrantyRefund> workerWarrantyRefunds = workerWarrantyRefundService.lambdaQuery()
                .eq(WorkerWarrantyRefund::getWarrantyId, warrantyId)
                .orderByDesc(WorkerWarrantyRefund::getRefundTime)
                .list();
        List<WorkerWarrantyPay> workerWarrantyPays = workerWarrantyPayService.lambdaQuery()
                .eq(WorkerWarrantyPay::getWarrantyId, warrantyId)
                .orderByDesc(WorkerWarrantyPay::getPayTime)
                .list();

        workerWarrantyDetail.setWorkerWarrantyPays(workerWarrantyPays);
        workerWarrantyDetail.setWorkerWarrantyRefunds(workerWarrantyRefunds);

        return workerWarrantyDetail;

    }
}
