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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.contract.SettleRelaConfigVO;
import com.gree.mall.manager.bean.contract.WebsitFollowConfigBean;
import com.gree.mall.manager.bean.contract.WebsitFollowConfigItemBean;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.AdminWebsit;
import com.gree.mall.manager.plus.entity.WebsitFollowConfig;
import com.gree.mall.manager.plus.entity.WebsitFollowConfigItem;
import com.gree.mall.manager.plus.service.AdminWebsitService;
import com.gree.mall.manager.plus.service.WebsitFollowConfigItemService;
import com.gree.mall.manager.plus.service.WebsitFollowConfigService;
import com.gree.mall.manager.utils.CommonUtils;
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.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class SettleRelaConfigLogic {
    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final WebsitFollowConfigService websitFollowConfigService;
    private final WebsitFollowConfigItemService websitFollowConfigItemService;
    private final AdminWebsitService adminWebsitService;

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

    public WebsitFollowConfigBean detail(String websitId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        final WebsitFollowConfig config = websitFollowConfigService.getById(websitId);
        WebsitFollowConfigBean bean = new WebsitFollowConfigBean();
        BeanUtils.copyProperties(config, bean);
        final List<WebsitFollowConfigItem> items = websitFollowConfigItemService.lambdaQuery()
                .eq(WebsitFollowConfigItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(WebsitFollowConfigItem::getParentId, websitId)
                .list();
        if (CollectionUtil.isNotEmpty(items)) {
            final List<AdminWebsit> websitList = adminWebsitService.lambdaQuery()
                    .eq(AdminWebsit::getCompanyWechatId, adminUser.getCompanyWechatId())
                    .in(AdminWebsit::getWebsitId, items.stream()
                            .map(WebsitFollowConfigItem::getSubWebsitId)
                            .collect(Collectors.toList()))
                    .list();
            final Map<String, AdminWebsit> websitMap = websitList.stream()
                    .collect(Collectors.toMap(AdminWebsit::getWebsitId, Function.identity()));

            List<WebsitFollowConfigItemBean> beanList = new ArrayList<>();
            for (WebsitFollowConfigItem item : items) {
                final AdminWebsit websit = websitMap.get(item.getSubWebsitId());
                WebsitFollowConfigItemBean itemBean = new WebsitFollowConfigItemBean();
                BeanUtils.copyProperties(item, itemBean);
                itemBean.setName(websit.getName());
                itemBean.setWebsitId(item.getSubWebsitId());
                itemBean.setBelongCompany(websit.getBelongCompany());
                itemBean.setBelongCompanyCode(websit.getBelongCompanyCode());
                beanList.add(itemBean);
            }
            bean.setItems(beanList);
        }
        return bean;
    }

    public Page<AdminWebsit> querySubWebsit(String websitId, String websitName, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        final List<WebsitFollowConfigItem> items = websitFollowConfigItemService.lambdaQuery()
                .eq(WebsitFollowConfigItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                .list();

        final List<String> useList = items.stream().map(WebsitFollowConfigItem::getSubWebsitId).collect(Collectors.toList());

        final Page<AdminWebsit> websitList = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(AdminWebsit::getLevel, 2)
                .like(StringUtils.isNotBlank(websitId), AdminWebsit::getWebsitId, websitId)
                .like(StringUtils.isNotBlank(websitName), AdminWebsit::getName, websitName)
                .notIn(CollectionUtil.isNotEmpty(useList), AdminWebsit::getWebsitId, useList)
                .orderByAsc(AdminWebsit::getBelongCompanyCode)
                .orderByAsc(AdminWebsit::getWebsitId)
                .page(new Page<>(pageNum, pageSize));

        return websitList;
    }

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

        this.checkConfigInfo(adminUser.getCompanyWechatId(), bean.getWebsitId(), false);

        WebsitFollowConfig config = new WebsitFollowConfig();
        config.setCompanyWechatId(adminUser.getCompanyWechatId())
                .setCompanyWechatName(adminUser.getCompanyName())
                .setWebsitId(bean.getWebsitId())
                .insert();

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            final List<WebsitFollowConfigItem> existItems = websitFollowConfigItemService.lambdaQuery()
                    .eq(WebsitFollowConfigItem::getCompanyWechatId, config.getCompanyWechatId())
                    .in(WebsitFollowConfigItem::getSubWebsitId, bean.getItems().stream()
                            .map(WebsitFollowConfigItemBean::getSubWebsitId)
                            .collect(Collectors.toList()))
                    .list();
            if (CollectionUtil.isNotEmpty(existItems)) {
                final String err = existItems.stream().map(WebsitFollowConfigItem::getSubWebsitId).collect(Collectors.joining(","));
                throw new RemoteServiceException(err + "已有上级关系");
            }
            List<WebsitFollowConfigItem> items = new ArrayList<>();
            for (WebsitFollowConfigItemBean itemBean : bean.getItems()) {
                WebsitFollowConfigItem item = new WebsitFollowConfigItem();
                item.setCompanyWechatId(config.getCompanyWechatId())
                        .setCompanyWechatName(config.getCompanyWechatName())
                        .setParentId(config.getWebsitId())
                        .setSubWebsitId(StringUtils.isBlank(itemBean.getWebsitId()) ? itemBean.getSubWebsitId() : itemBean.getWebsitId());
                items.add(item);
            }
            websitFollowConfigItemService.saveBatch(items);
        }
    }

    @Transactional
    public void edit(WebsitFollowConfigBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (adminUser.getType().equals(2)) {
            throw new RemoteServiceException("平台账号禁止操作");
        }
        final WebsitFollowConfig config = websitFollowConfigService.lambdaQuery()
                .eq(WebsitFollowConfig::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(WebsitFollowConfig::getWebsitId, bean.getWebsitId())
                .one();
        if (Objects.isNull(config)) {
            throw new RemoteServiceException("上级网点信息不存在");
        }
        // 清空关系明细
        websitFollowConfigItemService.lambdaUpdate()
                .eq(WebsitFollowConfigItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(WebsitFollowConfigItem::getParentId, bean.getWebsitId())
                .remove();
        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            final List<WebsitFollowConfigItem> existItems = websitFollowConfigItemService.lambdaQuery()
                    .eq(WebsitFollowConfigItem::getCompanyWechatId, config.getCompanyWechatId())
                    .in(WebsitFollowConfigItem::getSubWebsitId, bean.getItems().stream()
                            .map(WebsitFollowConfigItemBean::getSubWebsitId)
                            .collect(Collectors.toList()))
                    .list();
            if (CollectionUtil.isNotEmpty(existItems)) {
                final String err = existItems.stream().map(v -> v.getParentId() + ":" + v.getSubWebsitId()).collect(Collectors.joining(","));
                throw new RemoteServiceException(err + "已有上级关系");
            }
            List<WebsitFollowConfigItem> items = new ArrayList<>();
            for (WebsitFollowConfigItemBean itemBean : bean.getItems()) {
                WebsitFollowConfigItem item = new WebsitFollowConfigItem();
                item.setCompanyWechatId(config.getCompanyWechatId())
                        .setCompanyWechatName(config.getCompanyWechatName())
                        .setParentId(config.getWebsitId())
                        .setSubWebsitId(StringUtils.isBlank(itemBean.getWebsitId()) ? itemBean.getSubWebsitId() : itemBean.getWebsitId());
                items.add(item);
            }
            websitFollowConfigItemService.saveBatch(items);
        }
    }

    @Transactional
    public void importData(MultipartFile file) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        String companyWechatId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
        String companyName = adminUser.getAdminCompanyWechat().getCompanyName();

        List<Object> objects = ExcelUtils.importExcel(file);
        Map<String, List<String>> importMap = new HashMap<>();

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

            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i + 1) + "行, 上级网点编号不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i + 1) + "行, 下级网点编号不能为空");
            }

            String parentId = (String) row.get(0);
            String subId = (String) row.get(1);

            if (importMap.containsKey(StrUtil.trim(parentId))) {
                importMap.get(StrUtil.trim(parentId)).add(subId);
            } else {
                importMap.put(StrUtil.trim(parentId), new ArrayList<String>() {{ this.add(StrUtil.trim(subId)); }});
            }
        }

        if (CollectionUtil.isEmpty(importMap)) {
            throw new RemoteServiceException("导入数据为空");
        }

        // 产生关系对象
        for (Map.Entry<String, List<String>> entry : importMap.entrySet()) {
            WebsitFollowConfig config = new WebsitFollowConfig();

            boolean isInsert = this.checkConfigInfo(companyWechatId, entry.getKey(), true);

            config.setCompanyWechatId(companyWechatId)
                    .setCompanyWechatName(companyName)
                    .setWebsitId(entry.getKey());
            if (isInsert) {
                config.insert();
            }

            final List<WebsitFollowConfigItem> existItems = websitFollowConfigItemService.lambdaQuery()
                    .eq(WebsitFollowConfigItem::getCompanyWechatId, config.getCompanyWechatId())
                    .in(WebsitFollowConfigItem::getSubWebsitId, entry.getValue())
                    .list();
            if (CollectionUtil.isNotEmpty(existItems)) {
                final String err = existItems.stream().map(v -> v.getParentId() + ":" + v.getSubWebsitId()).collect(Collectors.joining(","));
                throw new RemoteServiceException(err + "已有上级关系");
            }
            List<WebsitFollowConfigItem> items = new ArrayList<>();
            for (String subId : entry.getValue()) {
                WebsitFollowConfigItem item = new WebsitFollowConfigItem();
                item.setCompanyWechatId(config.getCompanyWechatId())
                        .setCompanyWechatName(config.getCompanyWechatName())
                        .setParentId(config.getWebsitId())
                        .setSubWebsitId(subId);
                items.add(item);
            }
            websitFollowConfigItemService.saveBatch(items);
        }
    }

    private boolean checkConfigInfo(String companyWechatId, String websitId, Boolean isImport) {
        boolean isInsert = false;

        final Integer existData = websitFollowConfigService.lambdaQuery()
                .eq(WebsitFollowConfig::getCompanyWechatId, companyWechatId)
                .eq(WebsitFollowConfig::getWebsitId, websitId)
                .count();
        if (!isImport && existData > 0) {
            throw new RemoteServiceException(websitId + "已配置过关系, 添加失败");
        }

        if (isImport && existData == 0) {
            isInsert = true;
        }

        final Integer count = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, companyWechatId)
                .eq(AdminWebsit::getWebsitId, websitId)
                .eq(AdminWebsit::getLevel, 1)
                .count();
        if (count == 0) {
            throw new RemoteServiceException(websitId + "不是一级网点, 添加失败");
        }
        return isInsert;
    }
}
