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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.contract.ContractTemplateBean;
import com.gree.mall.manager.bean.contract.ContractTemplateVO;
import com.gree.mall.manager.bean.contract.ContractWebsitBean;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.ContractTypeEnum;
import com.gree.mall.manager.enums.material.StateEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.ContractTemplate;
import com.gree.mall.manager.plus.entity.ContractTemplateBak;
import com.gree.mall.manager.plus.entity.ContractWebsit;
import com.gree.mall.manager.plus.service.AdminWebsitService;
import com.gree.mall.manager.plus.service.ContractTemplateService;
import com.gree.mall.manager.plus.service.ContractWebsitService;
import com.gree.mall.manager.utils.fadada.Auth4FDDUtil;
import com.gree.mall.manager.utils.oss.OSSUtil;
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.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ContractTemplateLogic {
    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final ContractTemplateService contractTemplateService;
    private final ContractWebsitService contractWebsitService;
    private final AdminWebsitService adminWebsitService;
    private final OSSUtil ossUtil;

    public IPage<ContractTemplateVO> list(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.supplyParam(zfireParamBean, ContractTemplateVO.class, adminUser);
        return commonMapper.contractTemplatePage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }

    public ContractTemplateBean detail(String contractTemplateId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        final ContractTemplate template = contractTemplateService.getById(contractTemplateId);
        ContractTemplateBean bean = new ContractTemplateBean();
        BeanUtils.copyProperties(template, bean);
        // 查询已选子网点
        List<ContractWebsitBean> websitBeanList = commonMapper.contractWebsitList(contractTemplateId);
        bean.setItems(websitBeanList);

        return bean;
    }

    public IPage<ContractWebsitBean> queryRelaWebsit(String contractTemplateId, String websitId, String websitName,
                                                     Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<ContractWebsitBean> page = commonMapper.querySettleRelaWebsit(new Page<>(pageNum, pageSize), contractTemplateId, websitId, websitName);
        return page;
    }

    @Transactional
    public void add(ContractTemplateBean contractTemplate) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (adminUser.getType().equals(2)) {
            throw new RemoteServiceException("平台账号禁止操作");
        }
        contractTemplate.setCompanyWechatId(adminUser.getCompanyWechatId())
                .setCompanyWechatName(adminUser.getCompanyName());

        this.validRequireParams(contractTemplate);
        // 检查二级网点的主合同有没有
        this.checkMainDate(contractTemplate);

        String urlWw = contractTemplate.getContractTemplatePdf();
        String templateId = IdWorker.getIdStr();

        Auth4FDDUtil.uploadTemplate(templateId, null, urlWw);

        contractTemplate.setFadadaTemplateId(templateId)
                .setContractTemplateName(contractTemplate.getContractTemplateName().trim())
                .setStatus(StateEnum.ON.getKey())
                .insert();

        if (CollectionUtil.isNotEmpty(contractTemplate.getItems())) {
            contractWebsitService.saveBatch(contractTemplate.getItems().stream()
                    .peek(v -> v.setContractTemplateId(contractTemplate.getContractTemplateId())
                            .setCompanyWechatId(contractTemplate.getCompanyWechatId())
                            .setCompanyWechatName(contractTemplate.getCompanyWechatName())
                            .setId(IdWorker.getIdStr()))
                    .collect(Collectors.toList()));
        }
    }

    @Transactional
    public void update(ContractTemplateBean contractTemplate) {
        this.validRequireParams(contractTemplate);
        this.checkMainDate(contractTemplate);
        ContractTemplate byId = contractTemplateService.getById(contractTemplate.getContractTemplateId());
        if (!byId.getContractTemplatePdf().equals(contractTemplate.getContractTemplatePdf())) {
            String urlWw = contractTemplate.getContractTemplatePdf();
            String templateId = IdWorker.getIdStr();
            Auth4FDDUtil.uploadTemplate(templateId, null, urlWw);
            byId.setFadadaTemplateId(templateId);
        }

        byId.setContractTemplateName(contractTemplate.getContractTemplateName().trim())
                .setValidDate(contractTemplate.getValidDate())
                .setExpireDate(contractTemplate.getExpireDate())
                .setContractTemplatePdf(contractTemplate.getContractTemplatePdf())
                .setFollowContractTemplateId(contractTemplate.getFollowContractTemplateId())
                .updateById();

        if (contractTemplate.getContractType().equals(ContractTypeEnum.MAIN.getKey())) {
            contractTemplateService.lambdaUpdate()
                    .set(ContractTemplate::getValidDate, byId.getValidDate())
                    .set(ContractTemplate::getExpireDate, byId.getExpireDate())
                    .eq(ContractTemplate::getFollowContractTemplateId, contractTemplate.getContractTemplateId())
                    .update();
        }

        contractWebsitService.lambdaUpdate()
                .eq(ContractWebsit::getContractTemplateId, contractTemplate.getContractTemplateId())
                .remove();
        if (CollectionUtil.isNotEmpty(contractTemplate.getItems())) {
            contractWebsitService.saveBatch(contractTemplate.getItems().stream()
                    .peek(v -> v.setContractTemplateId(byId.getContractTemplateId())
                            .setCompanyWechatId(byId.getCompanyWechatId())
                            .setCompanyWechatName(byId.getCompanyWechatName())
                            .setId(IdWorker.getIdStr()))
                    .collect(Collectors.toList()));
        }
    }

    public void delete(String contractTemplateId) {
        ContractTemplate template = contractTemplateService.lambdaQuery()
                .eq(ContractTemplate::getContractTemplateId, contractTemplateId)
                .one();
        ContractTemplateBak contractTemplateBak = new ContractTemplateBak();
        BeanUtils.copyProperties(template, contractTemplateBak);
        template.deleteById();
        contractTemplateBak.insert();
    }

    public void updateStatus(String contractTemplateId, StateEnum status) {
        ContractTemplateBean bean = new ContractTemplateBean();
        ContractTemplate template = contractTemplateService.lambdaQuery()
                .eq(ContractTemplate::getContractTemplateId, contractTemplateId)
                .one();
        BeanUtils.copyProperties(template, bean);
        final List<ContractWebsit> websitList = contractWebsitService.lambdaQuery()
                .eq(ContractWebsit::getContractTemplateId, template.getContractTemplateId())
                .list();

        final List<ContractWebsitBean> websitBeanList = BeanUtil.copyToList(websitList, ContractWebsitBean.class);
        bean.setItems(websitBeanList);

        if (status.getKey().equals(StateEnum.ON.getKey())) {
            this.checkMainDate(bean);
        }
        ContractTemplate contractTemplate = new ContractTemplate();
        contractTemplate.setStatus(status.getKey())
                .setContractTemplateId(contractTemplateId)
                .updateById();
    }


    private void validRequireParams(ContractTemplateBean contractTemplate) {
        if (StringUtils.isBlank(contractTemplate.getContractTemplateName())) {
            throw new RemoteServiceException("合同名称不能为空");
        }
        if (StringUtils.isBlank(contractTemplate.getContractType())) {
            throw new RemoteServiceException("合同类型不能为空");
        }
        if (contractTemplate.getContractType().equals(ContractTypeEnum.MAIN.getKey())) {
            contractTemplate.setFollowContractTemplateId(null);
        }
        if (StringUtils.isBlank(contractTemplate.getContractTemplateId())
                && ContractTypeEnum.MAIN.getKey().equals(contractTemplate.getContractType())
                && Objects.isNull(contractTemplate.getValidDate())) {
            throw new RemoteServiceException("主合同类型生效日期不能为空");
        }
        if (StringUtils.isBlank(contractTemplate.getContractTemplateId())
                && ContractTypeEnum.MAIN.getKey().equals(contractTemplate.getContractType())
                && Objects.isNull(contractTemplate.getExpireDate())) {
            throw new RemoteServiceException("主合同类型失效日期不能为空");
        }
        if (ContractTypeEnum.MAIN.getKey().equals(contractTemplate.getContractType())
                && contractTemplate.getValidDate().after(contractTemplate.getExpireDate())) {
            throw new RemoteServiceException("生效日期不能大于失效日期");
        }
        if (StringUtils.isBlank(contractTemplate.getContractTemplateId())) {
            Integer count = contractTemplateService.lambdaQuery()
                    .eq(ContractTemplate::getContractTemplateName, contractTemplate.getContractTemplateName().trim())
                    .count();
            if (count > 0) {
                throw new RemoteServiceException("合同名称已存在，不能重复");
            }
        }
        if (StringUtils.isBlank(contractTemplate.getContractTemplatePdf())) {
            throw new RemoteServiceException("合同模板不能为空");
        }
        if (StringUtils.isNotBlank(contractTemplate.getFollowContractTemplateId())
                && ContractTypeEnum.FOLLOW.getKey().equals(contractTemplate.getContractType())) {
            final ContractTemplate mainContract = contractTemplateService.getById(contractTemplate.getFollowContractTemplateId());
            if (Objects.nonNull(mainContract)) {
                contractTemplate.setValidDate(mainContract.getValidDate())
                        .setExpireDate(mainContract.getExpireDate());
            }
        }
    }

    private void checkMainDate(ContractTemplateBean contractTemplate) {
        if (!contractTemplate.getContractType().equals(ContractTypeEnum.MAIN.getKey())) {
            return;
        }
        if (CollectionUtil.isEmpty(contractTemplate.getItems())) {
            return;
        }
        List<String> ids = commonMapper.selectMainContractIdByValidDate(contractTemplate.getCompanyWechatId(), contractTemplate.getValidDate());
        if (StringUtils.isNotBlank(contractTemplate.getContractTemplateId())
                && CollectionUtil.isNotEmpty(ids)) {
            ids.remove(contractTemplate.getContractTemplateId());
        }
        if (CollectionUtil.isNotEmpty(ids)) {
            for (ContractWebsitBean item : contractTemplate.getItems()) {
                final Integer count = contractWebsitService.lambdaQuery()
                        .in(ContractWebsit::getContractTemplateId, ids)
                        .in(ContractWebsit::getSubWebsitId, item.getSubWebsitId())
                        .count();
                if (count > 0) {
                    throw new RemoteServiceException(item.getSubWebsitId() + "的生效日期在" + String.join(",", ids) + "其他主合同的有效期内，请检查");
                }
            }
        }
    }
}
