package com.storlead.sales.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.storlead.framework.common.constant.CommonConstant;
import com.storlead.framework.common.util.StringUtil;
import com.storlead.sales.pojo.entity.customer.CustomerCompanyEntity;
import com.storlead.sales.pojo.entity.customer.CustomerEntity;
import com.storlead.sales.pojo.entity.customer.LiaisonEntity;
import com.storlead.sales.service.customer.CustomerCompanyService;
import com.storlead.sales.service.customer.CustomerService;
import com.storlead.sales.service.customer.LiaisonService;
import com.storlead.mail.pojo.entity.EmailsEntity;
import com.storlead.mail.service.EmailsService;
import com.storlead.sales.pojo.entity.mail.CustomerMailBingMarkEntity;
import com.storlead.sales.mapper.mail.CustomerMailBingMarkMapper;
import com.storlead.sales.service.CustomerMailBingMarkService;
import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户联系人关联邮件绑定标记 服务实现类
 * </p>
 *
 * @author chenkq
 * @since 2024-08-30
 */
@Service
public class CustomerMailBingMarkServiceImpl extends MyBaseServiceImpl<CustomerMailBingMarkMapper, CustomerMailBingMarkEntity> implements CustomerMailBingMarkService {
    @Resource
    private LiaisonService liaisonService;
    @Resource
    private CustomerCompanyService companyService;
    @Resource
    private CustomerService customerService;

    @Resource
    private EmailsService emailsService;
//    @Override
//    public void mateBindCustomerLiaisonFromMail(Long mailId,Long ownerBy,String fromMailAddress,Integer inOutMark) {
//
//        LambdaQueryWrapper<LiaisonEntity> l = new LambdaQueryWrapper<>();
//        l.eq(LiaisonEntity::getEmail,fromMailAddress);
//        l.eq(LiaisonEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
//        l.last("limit 1");
//        LiaisonEntity liaison = liaisonService.getOne(l);
//        if (Objects.nonNull(liaison)) {
//            CustomerMailBingMarkEntity entity = new CustomerMailBingMarkEntity();
//            entity.setCustomerId(liaison.getCustomerId());
//            entity.setLiaisonId(liaison.getId());
//            entity.setMailId(mailId);
//            entity.setInOutMark(1);
//            this.saveOrUpdate(entity);
//        } else {
//            LambdaQueryWrapper<CustomerCompanyEntity> companyMp = new LambdaQueryWrapper<>();
//            companyMp.eq(CustomerCompanyEntity::getIsDelete,Integer.valueOf(0));
//            companyMp.eq(CustomerCompanyEntity::getEmail,fromMailAddress);
//            l.last("limit 1");
//            CustomerCompanyEntity company = companyService.getOne(companyMp);
//            if (Objects.nonNull(company)) {
//                CustomerMailBingMarkEntity entity = new CustomerMailBingMarkEntity();
//                entity.setCustomerId(company.getCustomerId());
//                entity.setInOutMark(1);
//                entity.setMailId(mailId);
//                this.saveOrUpdate(entity);
//            }
//        }
//    }

    @Override
    public void mateBindCustomerLiaisonMail(Long mailId,Long ownerBy,String recipientMailAddress,Integer inOutMark) {

        List<CustomerMailBingMarkEntity> mkeList = new ArrayList<>();
        List<String> mails = Arrays.asList(recipientMailAddress.toLowerCase().split(","));

        QueryWrapper<CustomerCompanyEntity> lw = new QueryWrapper<>();
//        lw.in("LOWER(email)", mails); // 转换查询条件中的 email 为小写进行匹配
        lw.and(w -> w.or(ow -> ow.like("email","@").in("LOWER(email)", mails))
                .or(ow -> ow.like("email1","@").in("LOWER(email1)", mails))
                .or(ow -> ow.like("email2","@").in("LOWER(email2)", mails))
                .or(ow -> ow.like("email3","@").in("LOWER(email3)", mails))
        );
//      lw.and(qw -> qw.like("email","@").in("LOWER(email)", mails)
//              .or(qw -> qw.like("email1","@").in("LOWER(email1)", mails)
//              .or(qw -> qw.like("email2","@").in("LOWER(email2)", mails)
//              .or(qw -> qw.like("email3","@").in("LOWER(email3)", mails)).eq("is_delete",CommonConstant.DEL_FLAG_0);
        lw.eq("is_delete", CommonConstant.DEL_FLAG_0);
        List<CustomerCompanyEntity> companys = companyService.list(lw);

        if (!CollectionUtils.isEmpty(companys)) {
            for (CustomerCompanyEntity company : companys) {
                CustomerMailBingMarkEntity entity = new CustomerMailBingMarkEntity();
                entity.setCustomerId(company.getCustomerId());
                entity.setMailId(mailId);
                entity.setInOutMark(inOutMark);
                mkeList.add(entity);
            }
        }

        Map<Long,CustomerMailBingMarkEntity> mbMap = mkeList.stream().collect(Collectors.toMap(CustomerMailBingMarkEntity::getCustomerId, a -> a));

        QueryWrapper<LiaisonEntity> l = new QueryWrapper<>();
        l.and(w -> w.or(ow -> ow.like("email","@").in("LOWER(email)", mails))
                .or(ow -> ow.like("email1","@").in("LOWER(email1)", mails))
                .or(ow -> ow.like("email2","@").in("LOWER(email2)", mails))
                .or(ow -> ow.like("email3","@").in("LOWER(email3)", mails))
        );
        l.eq("is_delete", CommonConstant.DEL_FLAG_0);
        List<LiaisonEntity> liaisons = liaisonService.list(l);

        if (!CollectionUtils.isEmpty(liaisons)) {
            Map<Long, Set<Long>> cusLiaisonMap = liaisons.stream().filter(e ->Objects.nonNull(e.getCustomerId())).collect(Collectors.groupingBy(e -> e.getCustomerId(),Collectors.mapping(LiaisonEntity::getId,Collectors.toSet())));
            if (!CollectionUtils.isEmpty(cusLiaisonMap)) {
                cusLiaisonMap.forEach((customerIdk,liaisonIds) -> {
                    CustomerMailBingMarkEntity entity = mbMap.get(customerIdk);
                    if (Objects.isNull(entity)) {
                        entity = new CustomerMailBingMarkEntity();
                        entity.setCustomerId(customerIdk);
                        mkeList.add(entity);
                    }
                    entity.setLiaisonIds(StringUtil.join(liaisonIds,","));
                    entity.setInOutMark(inOutMark);
                    entity.setMailId(mailId);
                });
            }
        }
        if (!CollectionUtils.isEmpty(mkeList)) {
            saveOrUpdateBatch(mkeList);
        }
    }
    @Override
    public void updateCustomerMailBingMark(Long customerId,List<String> cmails,Long liaisonId,List<String> lmails) {

        if (Objects.isNull(customerId)) {
            return;
        }
        if (!CollectionUtils.isEmpty(cmails)) {
            LambdaQueryWrapper<EmailsEntity> mailWp = new LambdaQueryWrapper<>();
            mailWp.select(EmailsEntity::getId,EmailsEntity::getFolder);
            mailWp.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));

            String sql1 = " CONCAT(',',recipient,',') regexp (',"+ StringUtils.join(cmails,",|,")+",')";
            String sql2 = " CONCAT(',',recipient_cc,',') regexp (',"+ StringUtils.join(cmails,",|,")+",')";
            String sql3 = " CONCAT(',',`from`,',') regexp (',"+ StringUtils.join(cmails,",|,")+",')";
            mailWp.apply("((("+sql1+" or "+sql2+") and folder = 'SENT') or ("+sql3+" and folder = 'INBOX'))");
//            mailWp.apply("(((FIND_IN_SET('" + customerMail + "',recipient) or FIND_IN_SET('" + customerMail + "',recipient_cc)) and folder = 'SENT') or (`from` = '" + customerMail + "' and folder = 'INBOX'))");
            List<EmailsEntity> emailsls = emailsService.list(mailWp);
            if (CollectionUtils.isEmpty(emailsls)) {
                return;
            }
            /**
             * 已保存的数据，防止重复
             */
            Map<String, CustomerMailBingMarkEntity> cusMailMap = new HashMap<>();
            List<CustomerMailBingMarkEntity> cmb = this.list(new LambdaQueryWrapper<CustomerMailBingMarkEntity>().eq(CustomerMailBingMarkEntity::getCustomerId, customerId));
            if (CollectionUtils.isEmpty(cmb)) {
                cusMailMap = cmb.stream()
                        .collect(Collectors.toMap(
                                e -> e.getMailId() + "-" + e.getCustomerId(),  // 将 mailId 和 cusId 合并为一个键
                                e -> e // 将整个对象作为值
                        ));
            }
            List<CustomerMailBingMarkEntity> bindMarkLsAdd = new ArrayList<>();
            for (EmailsEntity mails : emailsls) {
                String key = mails.getId() + "-" + customerId;
                if (cusMailMap.containsKey(key)) {
                    continue;
                }
                CustomerMailBingMarkEntity entity = new CustomerMailBingMarkEntity();
                entity.setCustomerId(customerId);
                entity.setMailId(mails.getId());
                entity.setInOutMark("INBOX".equals(mails.getFolder()) ? 1 : 2);
                bindMarkLsAdd.add(entity);
            }
            if (CollectionUtils.isEmpty(bindMarkLsAdd)) {
                return;
            }
            saveBatch(bindMarkLsAdd);
        }
        if (!CollectionUtils.isEmpty(lmails) && Objects.nonNull(liaisonId)) {
            updateCustomerLiaisonMailBingMark(customerId,liaisonId,lmails);
        } else {
            LocalDateTime localDateTime = emailsService.getCustomerLastFollowUpTime(customerId);
            if (Objects.nonNull(localDateTime)) {
                CustomerEntity customer =  customerService.getById(customerId);
                if (Objects.nonNull(customer.getLastFollowUpTime())) {
                    LambdaUpdateWrapper<CustomerEntity> u = new LambdaUpdateWrapper<>();
                    u.eq(CustomerEntity::getId,customerId);
                    if (localDateTime.isAfter(customer.getLastFollowUpTime())) {
                        u.set(CustomerEntity::getLastFollowUpTime,localDateTime);
                        customerService.update(u);
                    }
                } else {
                    if (Objects.nonNull(customer.getCreateTime())) {
                        LocalDateTime createlDateTime = customer.getCreateTime().toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDateTime();
                        LambdaUpdateWrapper<CustomerEntity> u = new LambdaUpdateWrapper<>();
                        u.eq(CustomerEntity::getId,customerId);
                        if (localDateTime.isAfter(createlDateTime)) {
                            u.set(CustomerEntity::getLastFollowUpTime,localDateTime);
                            customerService.update(u);
                        } else {
                            u.set(CustomerEntity::getLastFollowUpTime,createlDateTime);
                            customerService.update(u);
                        }
                    }
                }
            }
        }
    }


    @Override
    public void updateCustomerLiaisonMailBingMark(Long customerId,Long liaisonId,List<String> mails) {

        if (!CollectionUtils.isEmpty(mails)) {
            LambdaQueryWrapper<EmailsEntity> mailWp = new LambdaQueryWrapper<>();
            mailWp.select(EmailsEntity::getId,EmailsEntity::getFolder);
            mailWp.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));

            String sql1 = " CONCAT(',',recipient,',') regexp (',"+ StringUtils.join(mails,",|,")+",')";
            String sql2 = " CONCAT(',',recipient_cc,',') regexp (',"+ StringUtils.join(mails,",|,")+",')";
            String sql3 = " CONCAT(',',`from`,',') regexp (',"+ StringUtils.join(mails,",|,")+",')";
            mailWp.apply("((("+sql1+" or "+sql2+") and folder = 'SENT') or ("+sql3+" and folder = 'INBOX'))");

//            mailWp.apply("(((FIND_IN_SET('" + liaisonMail + "',recipient) or FIND_IN_SET('" + liaisonMail + "',recipient_cc)) and folder = 'SENT') or (`from` = '" + liaisonMail + "' and folder = 'INBOX'))");
            List<EmailsEntity> emailsls = emailsService.list(mailWp);
            if (CollectionUtils.isEmpty(emailsls)) {
                return;
            }
            /**
             * 已保存的数据，防止重复
             */
            Map<String, CustomerMailBingMarkEntity> cusMailMap = new HashMap<>();
            List<CustomerMailBingMarkEntity> cmb = this.list(new LambdaQueryWrapper<CustomerMailBingMarkEntity>().eq(CustomerMailBingMarkEntity::getCustomerId, customerId));
            if (CollectionUtils.isEmpty(cmb)) {
                cusMailMap = cmb.stream()
                        .collect(Collectors.toMap(
                                e -> e.getMailId() + "-" + e.getCustomerId(),  // 将 mailId 和 cusId 合并为一个键
                                e -> e // 将整个对象作为值
                        ));
            }

            List<CustomerMailBingMarkEntity> bindMarkLsAdd = new ArrayList<>();
            List<CustomerMailBingMarkEntity> bindMarkLsUpdate = new ArrayList<>();

            for (EmailsEntity mail : emailsls) {
                String key = mail.getId() + "-" + customerId;
                if (cusMailMap.containsKey(key)) {
                    CustomerMailBingMarkEntity entity = cusMailMap.get(key);
                    entity.setInOutMark("INBOX".equals(mail.getFolder()) ? 1 : 2);
                    if (StrUtil.isNotBlank(entity.getLiaisonIds())) {
                        Set<String> liaisonIdSet = new HashSet<>(Arrays.asList(entity.getLiaisonIds().split(",")));
                        liaisonIdSet.add(liaisonId.toString());
                        entity.setLiaisonIds(StringUtil.join(liaisonIdSet, ","));
                        bindMarkLsUpdate.add(entity);
                    }
                } else {
                    CustomerMailBingMarkEntity entity = new CustomerMailBingMarkEntity();
                    entity.setInOutMark("INBOX".equals(mail.getFolder()) ? 1 : 2);
                    entity.setCustomerId(customerId);
                    entity.setMailId(mail.getId());
                    entity.setLiaisonIds(liaisonId.toString());
                    bindMarkLsAdd.add(entity);
                }
            }
            if (!CollectionUtils.isEmpty(bindMarkLsAdd)) {
                saveBatch(bindMarkLsAdd);
            }
            if (!CollectionUtils.isEmpty(bindMarkLsUpdate)) {
                updateBatchById(bindMarkLsUpdate);
            }
            if (CollectionUtils.isEmpty(bindMarkLsUpdate) && CollectionUtils.isEmpty(bindMarkLsAdd)) {
                return;
            }
        }

        LocalDateTime localDateTime = emailsService.getCustomerLastFollowUpTime(customerId);
        if (Objects.nonNull(localDateTime)) {
            CustomerEntity customer =  customerService.getById(customerId);
            if (Objects.isNull(customer)) {
                return;
            }
            if (Objects.nonNull(customer.getLastFollowUpTime())) {
                LambdaUpdateWrapper<CustomerEntity> u = new LambdaUpdateWrapper<>();
                u.eq(CustomerEntity::getId,customerId);
                if (localDateTime.isAfter(customer.getLastFollowUpTime())) {
                    u.set(CustomerEntity::getLastFollowUpTime,localDateTime);
                    customerService.update(u);
                }
            } else {
                if (Objects.nonNull(customer.getCreateTime())) {
                    LocalDateTime createlDateTime = customer.getCreateTime().toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDateTime();
                    LambdaUpdateWrapper<CustomerEntity> u = new LambdaUpdateWrapper<>();
                    u.eq(CustomerEntity::getId,customerId);
                    if (localDateTime.isAfter(createlDateTime)) {
                        u.set(CustomerEntity::getLastFollowUpTime,localDateTime);
                        customerService.update(u);
                    } else {
                        u.set(CustomerEntity::getLastFollowUpTime,createlDateTime);
                        customerService.update(u);
                    }
                }
            }
        }
    }

    @Override
    public List<Long> selectCustomerIdsByMailId(Long mailId) {
        return this.baseMapper.selectCustomerIdsByMailId(mailId);
    }
}
