package com.mortals.xhx.module.company.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.SourceEnum;
import com.mortals.xhx.module.bussinesscard.model.BussinesscardEntity;
import com.mortals.xhx.module.bussinesscard.model.BussinesscardQuery;
import com.mortals.xhx.module.bussinesscard.service.BussinesscardService;
import com.mortals.xhx.module.company.model.*;
import com.mortals.xhx.module.company.model.vo.HomeStatInfo;
import com.mortals.xhx.module.company.service.CompanyPatentService;
import com.mortals.xhx.module.company.service.CompanyProductService;
import com.mortals.xhx.module.feedback.model.FeedbackQuery;
import com.mortals.xhx.module.feedback.service.FeedbackService;
import com.mortals.xhx.module.labels.model.LabelsEntity;
import com.mortals.xhx.module.labels.service.LabelsService;
import com.mortals.xhx.module.news.model.NewsCategoryEntity;
import com.mortals.xhx.module.news.model.NewsCategoryQuery;
import com.mortals.xhx.module.news.model.NewsQuery;
import com.mortals.xhx.module.news.service.NewsCategoryService;
import com.mortals.xhx.module.news.service.NewsService;
import com.mortals.xhx.module.product.model.ProductQuery;
import com.mortals.xhx.module.product.service.ProductService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.model.StaffRecordEntity;
import com.mortals.xhx.module.staff.model.StaffRecordQuery;
import com.mortals.xhx.module.staff.service.StaffRecordService;
import com.mortals.xhx.module.staff.service.StaffService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.company.dao.CompanyDao;
import com.mortals.xhx.module.company.service.CompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.module.company.service.CompanyLabelsService;
import org.springframework.util.ObjectUtils;

import java.sql.Array;
import java.util.*;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

/**
 * CompanyService
 * 公司 service实现
 *
 * @author zxfei
 * @date 2023-09-18
 */
@Service("companyService")
@Slf4j
public class CompanyServiceImpl extends AbstractCRUDServiceImpl<CompanyDao, CompanyEntity, Long> implements CompanyService {
    @Autowired
    private CompanyLabelsService companyLabelsService;
    @Autowired
    private CompanyPatentService companyPatentService;
    @Autowired
    private BussinesscardService bussinesscardService;

    @Autowired
    private CompanyService companyService;
    @Autowired
    private ProductService productService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private NewsService newsService;
    @Autowired
    private FeedbackService feedbackService;
    @Autowired
    private UserService userService;
    @Autowired
    private CompanyProductService companyProductService;
    @Autowired
    private NewsCategoryService newsCategoryService;
    @Autowired
    private StaffRecordService staffRecordService;
    @Autowired
    private LabelsService labelsService;

    @Value("${domain.name:https://oa.xinhx.co}")
    private String domain;

    @Override
    protected void findAfter(CompanyEntity params,PageInfo pageInfo, Context context, List<CompanyEntity> list) throws AppException {
        fillSubData(list);
        super.findAfter(params,pageInfo, context, list);
    }
    @Override
    protected void findAfter(CompanyEntity params, Context context, List<CompanyEntity> list) throws AppException {
        fillSubData(list);
        super.findAfter(params, context, list);
    }

    private void fillSubData(List<CompanyEntity> list) {
        String regex = "src=\"file";
        String replacement;
        if(domain.endsWith("/")){
            replacement = "src=\"" + domain + "file";
        }else {
            replacement = "src=\"" + domain + "/file";
        }
        List<Long> idList = list.stream().map(i -> i.getId()).collect(Collectors.toList());
        if(ObjectUtils.isEmpty(idList))return;
        Map<Long, List<CompanyLabelsEntity>> companyLabelsListMap = companyLabelsService
                .find(new CompanyLabelsQuery().companyIdList(idList)).parallelStream()
                .collect(Collectors.groupingBy(CompanyLabelsEntity::getCompanyId));

        List<CompanyPatentEntity> companyPatentEntities = companyPatentService.find(new CompanyPatentQuery().companyIdList(idList));
        Map<Long, List<CompanyPatentEntity>> companyPatentListMap = companyPatentEntities.parallelStream().collect((Collectors.groupingBy(CompanyPatentEntity::getCompanyId)));

        list.forEach(item -> {
            item.setCompanyLabelsList(companyLabelsListMap.get(item.getId()));
            item.setCompanyPatentsList(companyPatentListMap.get(item.getId()));
            if(StringUtils.isNotEmpty(item.getCompanyIntroduction())) {
                item.setCompanyIntroduction(item.getCompanyIntroduction().replaceAll(regex, replacement));
            }
        });
    }

/*
    @Override
    protected void findAfter(CompanyEntity params, PageInfo pageInfo, Context context, List<CompanyEntity> list) throws AppException {

        list.stream().peek(item -> {
            List<CompanyPatentEntity> companyPatentEntities = companyPatentService.find(new CompanyPatentQuery().companyId(item.getId()));
            item.setCompanyPatentsList(companyPatentEntities);
        }).count();
    }
*/

    @Override
    protected void saveAfter(CompanyEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getCompanyLabelsList())) {
            entity.getCompanyLabelsList().stream().peek(item -> {

                LabelsEntity labelsEntity = labelsService.get(item.getLabelId(), context);
                item.setLabelName(labelsEntity.getLabelName());
                item.setCompanyId(entity.getId());
                item.setCompanyName(entity.getCompanyName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            companyLabelsService.save(entity.getCompanyLabelsList());
        }

        if (!ObjectUtils.isEmpty(entity.getCompanyPatentsList())) {
            entity.getCompanyPatentsList().stream().peek(item -> {

                item.setCompanyId(entity.getId());
                item.setCompanyName(entity.getCompanyName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            companyPatentService.save(entity.getCompanyPatentsList());
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(CompanyEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getCompanyLabelsList())) {
            Long[] companyLabelsIds = companyLabelsService.find(new CompanyLabelsQuery().companyId(entity.getId())).stream().map(CompanyLabelsEntity::getId).toArray(Long[]::new);
            companyLabelsService.remove(companyLabelsIds, context);
            entity.getCompanyLabelsList().stream().peek(item -> {
                item.setCompanyId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            companyLabelsService.save(entity.getCompanyLabelsList());
        }

        if (!ObjectUtils.isEmpty(entity.getCompanyPatentsList())) {
            Long[] companyPantentIds = companyPatentService.find(new CompanyPatentQuery().companyId(entity.getId())).stream().map(CompanyPatentEntity::getId).toArray(Long[]::new);
            companyPatentService.remove(companyPantentIds, context);
            entity.getCompanyPatentsList().stream().peek(item -> {
                item.setCompanyId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            companyPatentService.save(entity.getCompanyPatentsList());
        }

        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<CompanyLabelsEntity> companyLabelslist = companyLabelsService.find(new CompanyLabelsQuery().companyIdList(Arrays.asList(ids)));
        companyLabelsService.removeList(companyLabelslist, context);

        List<CompanyPatentEntity> companyPatentEntities = companyPatentService.find(new CompanyPatentQuery().companyIdList(Arrays.asList(ids)));
        companyPatentService.removeList(companyPatentEntities, context);


        super.removeAfter(ids, context, result);
    }

    @Override
    public Rest<HomeStatInfo> indexStat(Context context) {
        HomeStatInfo homeStatInfo = new HomeStatInfo();
        //统计公司数量
        List<CompanyEntity> companyList = companyService.find(new CompanyQuery(), context);
        homeStatInfo.setEnterpriseNums(companyList.size());
        //
        int productNums = productService.count(new ProductQuery(), context);
        homeStatInfo.setProductNums(productNums);

        List<StaffEntity> staffList = staffService.find(new StaffQuery().staffStatusList(Arrays.asList(1,2)), context);

        homeStatInfo.setStaffNums(staffList.size());

        int newsNums = newsService.count(new NewsQuery(), context);
        homeStatInfo.setNewsNums(newsNums);

        int feedbackNums = feedbackService.count(new FeedbackQuery(), context);
        homeStatInfo.setFeedbackNums(feedbackNums);

        //客户数据待定
        Long userCount = staffList.stream().filter(f -> f.getSource() == SourceEnum.外部人员.getValue()).count();
        //   int userCount = userService.count(new UserQuery(), context);
        homeStatInfo.setCustomerNums(userCount.intValue());

        //产品分布
        companyList.forEach(company -> {
            int count = companyProductService.count(new CompanyProductQuery().companyId(company.getId()), context);
            company.setProductNums(count);
        });
        homeStatInfo.setProductDistributionList(companyList);

        //发送名片分布
        List<BussinesscardEntity> bussinesscardList = bussinesscardService.find(new BussinesscardQuery());
        Map<Long, Integer> collect = bussinesscardList.stream().collect(Collectors.groupingBy(x -> x.getCompanyId(), Collectors.summingInt(BussinesscardEntity::getSendBusinessCardTimes)));
/*        Map<String, Integer> collect = staffList.stream().collect(Collectors.groupingBy(x -> x.getCompanyIds(), Collectors.summingInt(StaffEntity::getSendBusinessCardTimes)));
 */
        companyList.forEach(company -> {
            //归集公司发送卡片数量
            Long companyId = company.getId();
            company.setBusinessCardNums(collect.getOrDefault(companyId,0));
/*            collect.entrySet().stream().forEach(item -> {
                String key = item.getKey();
                Integer nums = item.getValue();
                List<String> split = StrUtil.split(key, ",");
                if (split.contains(companyId.toString())) {
                    company.setBusinessCardNums(company.getBusinessCardNums() + nums);
                }
            });*/
        });
        homeStatInfo.setBusinessCardDistributionList(companyList);

        List<NewsCategoryEntity> newsCategoryList = newsCategoryService.find(new NewsCategoryQuery(), context);
        newsCategoryList.forEach(category -> {
            int count = newsService.count(new NewsQuery().categoryId(category.getId()), context);
            category.setNewsNums(count);
        });
        homeStatInfo.setNewsDistributionList(newsCategoryList);

        //近三十天访问记录
        List<Map<String, Object>> dayAccessList = new ArrayList<>();

        DateTime beforeDay = DateUtil.offsetDay(new Date(), -30);
        for (int i = 0; i < 30; i++) {
            DateTime curDate = DateUtil.offsetDay(beforeDay, i);
            Map<String, Object> map = new HashMap<>();
            map.put("dateStr",curDate.toDateStr());
            map.put("nums", 0);
            StaffRecordQuery staffRecordQuery = new StaffRecordQuery();
            staffRecordQuery.setCreateTimeStart(curDate.toDateStr());
            staffRecordQuery.setCreateTimeEnd(curDate.toDateStr());
            List<StaffRecordEntity> staffRecordEntities = staffRecordService.find(staffRecordQuery, context);
            if (!ObjectUtils.isEmpty(staffRecordEntities)) {
                int sum = staffRecordEntities.stream().mapToInt(item -> item.getSumViews()).sum();
                map.put("nums", sum);
            }
            dayAccessList.add(map);
        }

        homeStatInfo.setAccessStatList(dayAccessList);

        homeStatInfo.setSendCardStaffList(staffList);
        return Rest.ok(homeStatInfo);
    }

    @Override
    public CompanyEntity get(Long key, Context context) throws AppException {
        CompanyEntity entity = this.dao.get(key);
        if(entity != null){
            if(StringUtils.isNotEmpty(entity.getCompanyIntroduction())) {
                String regex = "src=\"file";
                String replacement;
                if(domain.endsWith("/")){
                    replacement = "src=\"" + domain + "file";
                }else {
                    replacement = "src=\"" + domain + "/file";
                }
                entity.setCompanyIntroduction(entity.getCompanyIntroduction().replaceAll(regex, replacement));
            }
        }
        return entity;
    }

}