package cn.axzo.msg.center.service.pending.response.v3.model;

import cn.axzo.msg.center.push.PushData;
import cn.axzo.msg.center.push.PushMessage;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.enums.GroupType;
import cn.axzo.msg.center.service.pending.response.MessageButtonProvider;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.toList;

/**
 * @author yanglin
 */
@Setter
@Getter
public class ParsedModelV3 implements MessageButtonProvider<ParsedButtonV3>, PushMessage {

    /**
     * 前端忽略
     */
    @JsonIgnore
    private ParsedTemplateV3 template;

    /**
     * 分组
     */
    @Nullable @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<ParsedGroupV3> groups;

    /**
     * 按钮
     */
    private List<ParsedButtonV3> buttons;

    @Nullable @JsonInclude(JsonInclude.Include.NON_NULL)
    private ParsedCardStyle cardStyle;

    /**
     * 前端忽略
     */
    @JsonIgnore
    private List<ParsedKV> personKeyValues = new ArrayList<>();

    /**
     * 前端忽略
     */
    @JsonIgnore
    private List<ComponentWorkerGroup> componentWorkerGroups = new ArrayList<>();

    @JsonIgnore @JSONField(serialize = false)
    public String getTemplateCode() {
        return template == null ? null : template.getCode();
    }

    public List<ParsedKV> determineDisplayOnCardKeyValues() {
        return determineGroups().stream()
                .filter(group -> group.getGroupType() == GroupType.KV_VALUES)
                .map(ParsedGroupV3::getGroupInfo)
                .filter(Objects::nonNull)
                .map(ParsedGroupInfo::getKeyValues)
                .flatMap(Collection::stream)
                .filter(ParsedKV::isDisplayOnCard)
                .collect(toList());
    }

    public void addPersonKV(ParsedKV kv) {
        personKeyValues.add(kv);
    }

    public void addComponentWorkerGroup(ComponentWorkerGroup group) {
        componentWorkerGroups.add(group);
    }

    public void removeIdenticalGroup(ParsedGroupV3 group) {
        if (groups == null) return;
        groups.removeIf(g -> g == group);
    }

    public List<ParsedGroupV3> determineGroups() {
        return groups == null ? Collections.emptyList() : groups;
    }

    public List<ParsedButtonV3> determineButtons() {
        List<ParsedButtonV3> buttons = this.buttons == null ? Collections.emptyList() : this.buttons;
        buttons.sort(Comparator.comparingInt(ParsedButtonV3::determinePriority));
        return buttons;
    }

    public void removeEmptyKVGroups() {
        if (groups == null) return;
        groups.removeIf(g -> {
            boolean isKVGroup = g.getGroupType() == GroupType.KV_VALUES;
            return isKVGroup && g.determineKeyValues().isEmpty();
        });
    }

    @Override
    public void buttons(List<ParsedButtonV3> buttons) {
        this.buttons = buttons;
    }

    @Override
    public List<ParsedButtonV3> buttons() {
        return buttons;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

    @Override @JsonIgnore @JSONField(serialize = false)
    public String getPushTitle() {
        if (template == null) return null;
        return template.getTitle();
    }

    @Override @JsonIgnore @JSONField(serialize = false)
    public String getPushContent() {
        if (template == null) return null;
        return template.getContent();
    }

    @Override @JsonIgnore @JSONField(serialize = false)
    public UrlConfig getPushUrl() {
        if (template == null) return null;
        CardUrlConfig cardUrl = template.getCardUrlConfig();
        return cardUrl == null ? null : cardUrl.getUrlConfig();
    }

    @Override @JsonIgnore @JSONField(serialize = false)
    public PushData getPushData() {
        if (template == null) return null;
        return template.parsePushData();
    }
}