package cn.axzo.msg.center.message.domain.vo;

import cn.axzo.msg.center.domain.entity.GeneralMessageRecord;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateRouterDTO;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.PresetButtonType;
import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum;
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 com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author cold_blade
 * @date 2023/10/19
 * @version 1.0
 */
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GeneralMessagePushVO implements Serializable {

    private static final long serialVersionUID = -9017550674630922381L;

    /**
     * 样式编码
     */
    private String cardStyleCode;

    /**
     * 消息的唯一标识
     */
    private String identityCode;
    /**
     * 模板编码
     */
    private String templateCode;
    /**
     * 顶部图片 - 模板icon地址
     */
    private String cardBannerUrl;
    /**
     * 卡片标题标题 - 消息标题
     */
    private String cardTitle;
    /**
     * 详情按钮
     */
    private CardButton cardDetailButton;
    /**
     * 副标题 - 消息所属组织信息
     */
    private List<Subtitle> subtitles;
    /**
     * 消息内容
     */
    private String cardContent;
    /**
     * 卡片信息
     */
    private List<CardExtensionItem> cardExtension;
    /**
     * 按钮操作区域
     */
    private List<CardButton> cardButtons;
    /**
     * 业务编码
     */
    private String bizCode;
    /**
     * 消息发送时间戳
     */
    private Long sendTimestamp;

    /**
     * 状态戳
     */
    private String stateImage;

    /**
     * 更新时间
     */
    private Long updateTime;

    /**
     * 卡片元素
     */
    private List<CardElementConfig> cardElements;

    private Map<String, Object> debugInfo;

    private Map<String, Object> extInfo;

    public void addDebugInfo(String name, Object value) {
        if (debugInfo == null)
            debugInfo = new HashMap<>();
        debugInfo.put(name, value);
    }

    public static GeneralMessagePushVO from(GeneralMessageRecord record, String templateIcon, String orgIcon,
                                            MessageTemplateRouterDTO msgTemplateRouter,
                                            List<MessageCardContentItemDTO> cardContentItems) {
        CardButton cardDetailButton = parseDetailButton(msgTemplateRouter);
        List<CardButton> cardButtons = parseCardButtons(msgTemplateRouter);
        List<CardExtensionItem> cardExtension = CollectionUtils.isEmpty(cardContentItems) ? Collections.emptyList() :
                cardContentItems.stream()
                        .map(CardExtensionItem::from)
                        .filter(i -> StringUtils.isNotBlank(i.getDetail()) && !"null".equals(i.getDetail()))
                        .collect(Collectors.toList());
        List<Subtitle> subtitles = Collections.emptyList();
        Optional<Subtitle> subtitleOp = Subtitle.from(record, orgIcon);
        if (subtitleOp.isPresent()) {
            subtitles = Lists.newArrayList(subtitleOp.get());
        }
        return GeneralMessagePushVO.builder()
                .identityCode(record.getIdentityCode())
                .templateCode(record.getTemplateCode())
                .cardBannerUrl(templateIcon)
                .cardTitle(record.getTitle())
                .cardDetailButton(cardDetailButton)
                .subtitles(subtitles)
                .cardContent(record.getContent())
                .cardExtension(cardExtension)
                .cardButtons(cardButtons)
                .bizCode(record.getBizCode())
                .sendTimestamp(record.getCreateAt().getTime())
                .build();
    }

    public static CardButton parseDetailButton(MessageTemplateRouterDTO msgTemplateRouter) {
        if (Objects.isNull(msgTemplateRouter) || Objects.isNull(msgTemplateRouter.getRouteDetail())) {
            return null;
        }
        return CardButton.from(msgTemplateRouter.getRouteDetail());
    }

    public static List<CardButton> parseCardButtons(MessageTemplateRouterDTO msgTemplateRouter) {
        if (Objects.isNull(msgTemplateRouter)
                || CollectionUtils.isEmpty(msgTemplateRouter.getRouteButtons())) {
            return Collections.emptyList();
        }
        return msgTemplateRouter.getRouteButtons().stream()
                .map(CardButton::from)
                .filter(b -> BooleanUtils.isTrue(b.isOverCard))
                .collect(Collectors.toList());
    }

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

    @Setter
    @Getter
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Subtitle {

        /**
         * 图标 - 对应消息所属组织的图标
         */
        private String iconUrl;
        /**
         * 标题 - 对应消息所属组织的名称
         */
        private String title;

        public static Optional<Subtitle> from(GeneralMessageRecord record, String orgIcon) {
            if (StringUtils.isBlank(record.getOrgName())) {
                return Optional.empty();
            }
            return Optional.of(Subtitle.builder()
                    .title(record.getOrgName())
                    .iconUrl(orgIcon)
                    .build());
        }

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

    @Setter
    @Getter
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class CardButton {

        /**
         * 按钮标题
         */
        private String title;
        /**
         * 按钮操作类型: JUMP - 页面跳转, ACTION - 接口调用, PRESET_BUTTON - 预设按钮
         */
        private String action;
        /**
         * 按钮样式 - 是否高亮
         */
        private Boolean isHighlight;
        /**
         * 按钮样式 - 是否按钮显示在卡片
         */
        private Boolean isOverCard;
        /**
         * 废弃: 按钮点击后的跳转地址
         * 替代: 使用urlConfig替代
         */
        private List<AppLink> actionPaths;

        /**
         * 各个端的url配置. action=JUMP时, 消费这个字段
         */
        private UrlConfig urlConfig;

        /**
         * 按钮来源
         */
        private RouterButtonSourceEnum source;

        /**
         * 调用api的地址. action=ACTION时, 消费这个字段
         */
        private String apiUrl;

        /**
         * 是否仅发起人可见. 预先埋点, 默认为false
         */
        private Boolean senderShow = false;

        /**
         * 是否执行人可见, true: 仅执行人可见, false: 所有人可见 (不区分发起人, 执行人)
         */
        private Boolean executorShow;

        /**
         * 按钮动作是否完成(是否失效). true: 已执行(已失效), false: 未执行 (未失效)
         */
        private Boolean actionPerformed;

        /**
         * 预设按钮类型. AGREE: 同意, REJECT: 驳回, REVOKE: 撤销
         */
        private PresetButtonType presetButtonType;

        /**
         * 按钮编码
         */
        private String buttonCode;

        static CardButton from(MessageTemplateRouterDTO.MessageRouteDetailDTO routeDetail) {
            return CardButton.builder()
                    .title(routeDetail.getName())
                    .action(RouterCategoryEnum.JUMP.name())
                    .isHighlight(false)
                    .actionPaths(routeDetail.getRouterConfigs().stream()
                            .map(e -> new AppLink(e.getTerminalType().name(), e.getUrl()))
                            .collect(Collectors.toList())
                    ).build();
        }

        static CardButton from(MessageTemplateRouterDTO.MessageRouteButtonDTO routerButton) {
            List<ButtonStyleEnum> buttonStyles = Objects.isNull(routerButton.getStyle()) ? Collections.emptyList() :
                    JSON.parseArray(routerButton.getStyle().toJSONString(), ButtonStyleEnum.class);
            if (RouterCategoryEnum.ACTION.equals(routerButton.getCategory())) {
                return CardButton.builder()
                        .title(routerButton.getName())
                        .action(routerButton.getCategory().name())
                        .isHighlight(buttonStyles.stream().anyMatch(ButtonStyleEnum.HIGH_LIGHT::equals))
                        .isOverCard(buttonStyles.stream().anyMatch(ButtonStyleEnum.OVER_CARD::equals))
                        .actionPaths(Lists.newArrayList(
                                new AppLink(TerminalTypeEnum.WEB_VIEW.name(), routerButton.getApiUrl())))
                        .build();
            }
            return CardButton.builder()
                    .title(routerButton.getName())
                    .action(routerButton.getCategory().name())
                    .isHighlight(buttonStyles.stream().anyMatch(ButtonStyleEnum.HIGH_LIGHT::equals))
                    .isOverCard(buttonStyles.stream().anyMatch(ButtonStyleEnum.OVER_CARD::equals))
                    .actionPaths(routerButton.getRouterConfigs().stream()
                            .map(e -> new AppLink(e.getTerminalType().name(), e.getUrl()))
                            .collect(Collectors.toList())
                    ).build();
        }

        @Getter
        @AllArgsConstructor
        static class ButtonAction {

            /**
             * 平台
             */
            private String platform;
            /**
             * 跳转地址
             */
            private String url;
        }
    }

    @Setter
    @Getter
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class CardExtensionItem {

        private String title;

        private String detail;

        public static CardExtensionItem from(MessageCardContentItemDTO cardContentItem) {
            return CardExtensionItem.builder()
                    .title(cardContentItem.getLabel())
                    .detail(cardContentItem.getValue())
                    .build();
        }

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