package cn.axzo.msg.center.message.service.card;

import cn.axzo.msg.center.inside.notices.config.MessageSystemConfig;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.CardButton;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.CardExtensionItem;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.message.service.impl.v3.NativeAppLinkUrlConfigVisitor;
import cn.axzo.msg.center.message.service.impl.v3.V3ExtPopulator;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigWalker;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.CardState;
import cn.axzo.msg.center.service.enums.KVContentType;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.card.domain.CardElementConfig;
import cn.axzo.msg.center.service.pending.request.CardContent;
import cn.axzo.msg.center.service.pending.request.CardStateInfo;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Visitor;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModelV3Walker;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedKV;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3;
import cn.axzo.msg.center.service.pending.response.v3.model.PersonInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author yanglin
 */
@Component
@RequiredArgsConstructor
class CardParser {

    private final MessageSystemConfig messageSystemConfig;
    private final V3ExtPopulator v3ExtPopulator;
    private final CardProps cardProps;

    GeneralMessagePushVO parseCardContent(CardTemplate cardTemplate, CardContent card) {
        ParsedTemplateV3 template = cardTemplate.getTemplate();
        GeneralMessagePushVO bizBody = new GeneralMessagePushVO();
        bizBody.setCardStyleCode(template.getCardStyleCode());
        bizBody.setTemplateCode(template.getCode());
        bizBody.setCardBannerUrl(template.getIcon());
        bizBody.setCardTitle(template.getTitle());
        bizBody.setCardContent(template.getContent());
        bizBody.setSendTimestamp(new Date().getTime());
        // 取当前时间即可, 数据库存的更新时间肯定晚于等于这个时间, 因此不会存在更新丢失
        bizBody.setUpdateTime(System.currentTimeMillis());
        CardStateInfo stateInfo = card.getStateInfo();
        bizBody.setStateImage(CardStateImageConfigs
                .create(template.getStateImageConfigs())
                .determineStateImage(stateInfo.getBizState()));
        if (StringUtils.isNotBlank(card.getSubtitle())) {
            GeneralMessagePushVO.Subtitle subtitle = new GeneralMessagePushVO.Subtitle();
            subtitle.setIconUrl(messageSystemConfig.getOrgIcon());
            subtitle.setTitle(card.getSubtitle());
            bizBody.setSubtitles(Collections.singletonList(subtitle));
        }
        if (cardProps.isDebugBizBody()) {
            bizBody.addDebugInfo("bizState", stateInfo.getBizState());
            bizBody.addDebugInfo("cardState", stateInfo.getCardState());
            bizBody.addDebugInfo("isUpdatable", cardTemplate.isUpdatable());
        }
        ParsedModelV3Walker.walkDown(cardTemplate.getParsedModel(), new ParsedModel3Visitor() {
            @Override
            public void visitTemplateCardUrlConfig(UrlConfig urlConfig) {
                if (!urlConfig.hasUrl()) return;
                CardButton cardDetailButton = new CardButton();
                cardDetailButton.setTitle("详情");
                cardDetailButton.setAction(RouterCategoryEnum.JUMP.name());
                cardDetailButton.setIsHighlight(false);
                cardDetailButton.setActionPaths(getNativeAppLinks(urlConfig));
                cardDetailButton.setUrlConfig(urlConfig);
                bizBody.setCardDetailButton(cardDetailButton);
            }

            @Override
            public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
                if (!kv.isDisplayOnCard()) return;
                if (StringUtils.isBlank(kv.getValue())) return;
                CardExtensionItem item = new CardExtensionItem(kv.getKey(), kv.getValue());
                // IM人员: 张三(130****5556)
                if (kv.getContentType() == KVContentType.PERSON_ID) {
                    v3ExtPopulator.populatePersonKV(kv);
                    PersonInfo person = kv.getPersonInfo();
                    if (person != null)
                        item = new CardExtensionItem(kv.getKey(), person.getPlainPersonInfo());
                } else if (kv.getContentType() == KVContentType.PHONE) {
                    if (kv.getPhoneInfo() != null)
                        item = new CardExtensionItem(kv.getKey(), kv.getPhoneInfo().getMaskPhone());
                }
                if (bizBody.getCardExtension() == null)
                    bizBody.setCardExtension(new ArrayList<>());
                bizBody.getCardExtension().add(item);
            }

            /**
             * button.getUrlConfig().hasUrl() 这个逻辑不能前置, 因为有预设按钮
             */
            @Override
            public void visitButton(ParsedButtonV3 button) {
                List<ButtonStyleEnum> styles = button.parseStyle();
                if (!styles.contains(ButtonStyleEnum.OVER_CARD)) return;
                if (stateInfo.getCardState() == CardState.COMPLETED && button.determinePendingShow())
                    return;
                if (bizBody.getCardButtons() == null)
                    bizBody.setCardButtons(new ArrayList<>());
                CardButton imButton = new CardButton();
                bizBody.getCardButtons().add(imButton);

                boolean isActionPerformed = card.isButtonActionPerformed(button.getCode());
                imButton.setTitle(isActionPerformed ? button.getActionPerformedName() : button.getName());
                imButton.setAction(button.getCategory().name());
                imButton.setIsHighlight(styles.contains(ButtonStyleEnum.HIGH_LIGHT));
                imButton.setExecutorShow(button.getExecutorShow());
                imButton.setActionPerformed(isActionPerformed);
                if (button.getUrlConfig().hasUrl())
                    imButton.setUrlConfig(button.getUrlConfig());
                imButton.setButtonCode(button.getCode());
                imButton.setPresetButtonType(button.getPresetButtonType());
                imButton.setApiUrl(button.getApiUrl());

                if (RouterCategoryEnum.ACTION.equals(button.getCategory())) {
                    AppLink appLink = new AppLink(TerminalTypeEnum.WEB_VIEW.name(), button.getApiUrl());
                    imButton.setActionPaths(Collections.singletonList(appLink));
                } else if (button.getUrlConfig().hasUrl()) {
                    imButton.setActionPaths(getNativeAppLinks(button.getUrlConfig()));
                }
            }

            @Override
            public void visitTemplateCardExtField(CardElementConfig cfg) {
                if (StringUtils.isBlank(cfg.getValue()))
                    return;
                if (bizBody.getCardElements() == null)
                    bizBody.setCardElements(new ArrayList<>());
                bizBody.getCardElements().add(cfg);
            }

        });
        return bizBody;
    }

    private List<AppLink> getNativeAppLinks(UrlConfig urlConfig) {
        if (urlConfig == null) return Collections.emptyList();
        NativeAppLinkUrlConfigVisitor visitor = new NativeAppLinkUrlConfigVisitor();
        UrlConfigWalker.walkDown(urlConfig, visitor);
        return visitor.getLinks();
    }

}