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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.ExcelData;
import com.gree.mall.manager.bean.activity.PromotionActivityBatchBean;
import com.gree.mall.manager.bean.activity.PromotionActivityBean;
import com.gree.mall.manager.bean.activity.PromotionActivityVO;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.promotion.PromotionStatusEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.PromotionActivity;
import com.gree.mall.manager.plus.entity.PromotionActivityItem;
import com.gree.mall.manager.plus.entity.PromotionActivityRecord;
import com.gree.mall.manager.plus.entity.PromotionQuestionnaire;
import com.gree.mall.manager.plus.service.PromotionActivityItemService;
import com.gree.mall.manager.plus.service.PromotionActivityRecordService;
import com.gree.mall.manager.plus.service.PromotionActivityService;
import com.gree.mall.manager.plus.service.PromotionQuestionnaireService;
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 javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class PromotionActivityLogic {
    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final PromotionActivityService promotionActivityService;
    private final PromotionActivityItemService promotionActivityItemService;
    private final PromotionActivityRecordService promotionActivityRecordService;
    private final PromotionQuestionnaireService promotionQuestionnaireService;

    public IPage<PromotionActivityVO> list(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.supplyParam(zfireParamBean, PromotionActivityVO.class, adminUser);
        // 网点权限
        String websitId = adminUser.getType() == 0 ? adminUser.getAdminWebsitIds().get(0) : null;
        IPage<PromotionActivityVO> page = commonMapper.promotionActivityList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean, websitId);

        return page;
    }

    public PromotionActivityBean detail(String promotionActivityId) {
        final PromotionActivity activity = promotionActivityService.getById(promotionActivityId);
        PromotionActivityBean bean = new PromotionActivityBean();
        BeanUtils.copyProperties(activity, bean);

        final List<PromotionActivityItem> items = promotionActivityItemService.lambdaQuery()
                .eq(PromotionActivityItem::getPromotionActivityId, promotionActivityId)
                .list();
        bean.setItems(items);
        final List<PromotionActivityRecord> records = promotionActivityRecordService.lambdaQuery()
                .eq(PromotionActivityRecord::getPromotionActivityId, promotionActivityId)
                .orderByDesc(PromotionActivityRecord::getCreateTime)
                .list();
        bean.setRecords(records);
        return bean;
    }

    @Transactional
    public void add(HttpServletRequest request, PromotionActivityBean bean) {
        final AdminUserCom adminUser = commonLogic.getAdminUser();

        if (StringUtils.isBlank(bean.getPromotionQuestionnaireId())) {
            throw new RemoteServiceException("设置活动id不能为空");
        }

        if (StringUtils.isBlank(bean.getUserName())) {
            throw new RemoteServiceException("客户名称不能为空");
        }

        if (StringUtils.isBlank(bean.getLinkName())) {
            throw new RemoteServiceException("联系人不能为空");
        }

        if (StringUtils.isBlank(bean.getUserMobile())) {
            throw new RemoteServiceException("客户电话不能为空");
        }

        if (StringUtils.isBlank(bean.getUserAddress())) {
            throw new RemoteServiceException("客户地址不能为空");
        }

        if (CollectionUtil.isEmpty(bean.getItems())) {
            throw new RemoteServiceException("报名信息不能为空");
        }

        final PromotionQuestionnaire questionnaire = promotionQuestionnaireService.getById(bean.getPromotionQuestionnaireId());

        if (DateUtil.date().getTime() < questionnaire.getStartTime().getTime()) {
            throw new RemoteServiceException("活动未生效");
        }

        if (questionnaire.getIsStop() || DateUtil.date().getTime() > questionnaire.getEndTime().getTime()) {
            throw new RemoteServiceException("活动已失效");
        }

        final String id = commonLogic.generateNo("", "PromotionActivity", 13);
        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId())
                    .setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
        }
        bean.setPromotionActivityId(id)
                .insert();

        for (PromotionActivityItem item : bean.getItems()) {
            if (StringUtils.isBlank(item.getId())) {
                throw new RemoteServiceException("活动答案源明细id不能为空");
            }
            item.setPromotionActivityItemId(null)
                    .setPromotionActivityId(bean.getPromotionActivityId())
                    .setPromotionQuestionnaireId(bean.getPromotionQuestionnaireId());
        }

        promotionActivityItemService.saveBatch(bean.getItems());
    }

    @Transactional
    public void batchFollow(PromotionActivityBatchBean bean) {
        final AdminUserCom adminUser = commonLogic.getAdminUser();
        if (StringUtils.isBlank(bean.getRemark())) {
            throw new RemoteServiceException("备注不能为空");
        }
        if (Objects.isNull(bean.getStatus())) {
            throw new RemoteServiceException("跟进结果不能为空");
        }
        if (CollectionUtil.isEmpty(bean.getIds())) {
            throw new RemoteServiceException("活动id不能为空");
        }
        promotionActivityService.lambdaUpdate()
                .set(PromotionActivity::getStatus, bean.getStatus().getKey())
                .set(PromotionActivity::getUpdateBy, adminUser.getNickName())
                .set(PromotionActivity::getUpdateTime, DateUtil.date())
                .eq(PromotionActivity::getStatus, PromotionStatusEnum.ING.getKey())
                .in(PromotionActivity::getPromotionActivityId, bean.getIds())
                .update();

        List<PromotionActivityRecord> records = new ArrayList<>();
        for (String id : bean.getIds()) {
            PromotionActivityRecord record = new PromotionActivityRecord();
            record.setPromotionActivityId(id)
                    .setRemark(bean.getRemark())
                    .setStatus(bean.getStatus().getKey());
            records.add(record);
        }
        promotionActivityRecordService.saveBatch(records);
    }

    public ExcelData export(Date statDate, Date endDate) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<List<Object>> rows = new ArrayList<>();

        String companyId = "";
        String companyName = "";
        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            companyId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
            companyName = adminUser.getAdminCompanyWechat().getCompanyName();
        }

        ExcelData excelData = new ExcelData();
        final List<PromotionActivity> activityList = promotionActivityService.lambdaQuery()
                .eq(StringUtils.isNotBlank(companyId), PromotionActivity::getCompanyWechatId, companyId)
                .between(PromotionActivity::getCreateTime, statDate, endDate)
                .list();

        List<String> titleList = new ArrayList<>();
        titleList.add("活动提交单号");
        titleList.add("所属商户");
        titleList.add("所属网点");
        titleList.add("活动名称");
        titleList.add("客户名称");
        titleList.add("客户电话");
        titleList.add("客户地址");
        titleList.add("提交人");
        titleList.add("提交时间");

        if (CollectionUtil.isEmpty(activityList)) {
            excelData.setTitles(titleList);
            excelData.setRows(rows);
            return excelData;
        }

        final List<PromotionQuestionnaire> questionnaireList = promotionQuestionnaireService.lambdaQuery()
                .in(PromotionQuestionnaire::getId, activityList.stream()
                        .map(PromotionActivity::getPromotionQuestionnaireId)
                        .collect(Collectors.toList()))
                .list();

        final Map<String, PromotionQuestionnaire> questionnaireMap = questionnaireList.stream()
                .collect(Collectors.toMap(PromotionQuestionnaire::getId, Function.identity()));

        final List<PromotionActivityItem> itemList = promotionActivityItemService.lambdaQuery()
                .in(PromotionActivityItem::getPromotionActivityId, activityList.stream()
                        .map(PromotionActivity::getPromotionActivityId)
                        .collect(Collectors.toList()))
                .list();

        final Map<String, List<PromotionActivityItem>> itemMap = itemList.stream()
                .collect(Collectors.groupingBy(PromotionActivityItem::getPromotionActivityId));

        // 计算出最大题目数量
        int questCount = 0;
        for (Map.Entry<String, List<PromotionActivityItem>> entry : itemMap.entrySet()) {
            if (entry.getValue().size() > questCount) {
                questCount = entry.getValue().size();
            }
        }


        for (int i = 0; i < questCount; i++) {
            titleList.add("题目" + (i+1));
            titleList.add("题型");
            titleList.add("答案（多个逗号隔开）");
        }

        int requireRowSize = titleList.size();

        for (PromotionActivity activity : activityList) {
            List<Object> row = new ArrayList<>();
            row.add(activity.getPromotionActivityId());
            row.add(activity.getCompanyWechatName());
            row.add(activity.getCustomWebsitName());

            final PromotionQuestionnaire questionnaire = questionnaireMap.get(activity.getPromotionQuestionnaireId());
            if (Objects.nonNull(questionnaire)) {
                row.add(questionnaire.getName());
            } else {
                row.add("");
            }

            row.add(activity.getUserName());
            row.add(activity.getUserMobile());
            row.add(activity.getUserAddress());
            row.add(activity.getCreateBy());
            row.add(DateUtil.formatDateTime(activity.getCreateTime()));

            final List<PromotionActivityItem> items = itemMap.get(activity.getPromotionActivityId());
            if (CollectionUtil.isNotEmpty(items)) {
                for (PromotionActivityItem item : items) {
                    row.add(item.getQuestion());
                    // 类型 1=单选 2=多选 3=填写
                    String typeStr = "";
                    if (item.getType() == 1) {
                        typeStr = "单选";
                    } else if (item.getType() == 2) {
                        typeStr = "多选";
                    } else if (item.getType() == 3) {
                        typeStr = "填写";
                    } else if (item.getType() == 4) {
                        typeStr = "图片";
                    } else if (item.getType() == 5) {
                        typeStr = "视频";
                    }

                    row.add(typeStr);
                    if (item.getType() < 4) {
                        final JSONArray jsonArray = JSONUtil.parseArray(item.getAnswer());
                        List<String> answerList = new ArrayList<>();
                        for (int i = 0; i < jsonArray.size(); i++) {
                            final Map map = jsonArray.get(i, Map.class);
                            final boolean active = (Boolean) map.get("active");
                            if (active || item.getType() == 3) {
                                // 选中或type为3填写的
                                answerList.add(map.get("option_value").toString());
                            }
                        }
                        row.add(CollectionUtil.isEmpty(answerList) ? "" : StrUtil.join(",", answerList));
                    } else {
                        row.add("");
                    }
                }
            }

            if (row.size() != requireRowSize) {
                int needRowSize = requireRowSize - row.size();
                if (needRowSize > 0) {
                    for (int i = 0; i < needRowSize; i++) {
                        row.add("");
                    }
                }
            }

            rows.add(row);
        }

        excelData.setTitles(titleList);
        excelData.setRows(rows);
        return excelData;
    }
}
