package cn.tomoya.android.md.util;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Cleaner;
import org.jsoup.safety.Whitelist;
import org.tautua.markdownpapers.Markdown;
import org.tautua.markdownpapers.parser.ParseException;

import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import cn.tomoya.android.md.model.api.ApiDefine;

public final class FormatUtils {

    private FormatUtils() {}

    public static String formatDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(date == null) {
            return "";
        }
        return simpleDateFormat.format(date);
    }

    /**
     * 获取最近时间字符串
     */

    private static final long MINUTE = 60 * 1000;
    private static final long HOUR = 60 * MINUTE;
    private static final long DAY = 24 * HOUR;
    private static final long WEEK = 7 * DAY;
    private static final long MONTH = 31 * DAY;
    private static final long YEAR = 12 * MONTH;

    public static String getRelativeTimeSpanString(@NonNull Date date) {
        long offset = System.currentTimeMillis() - date.getTime();
        if (offset > YEAR) {
            return (offset / YEAR) + "年前";
        } else if (offset > MONTH) {
            return (offset / MONTH) + "个月前";
        } else if (offset > WEEK) {
            return (offset / WEEK) + "周前";
        } else if (offset > DAY) {
            return (offset / DAY) + "天前";
        } else if (offset > HOUR) {
            return (offset / HOUR) + "小时前";
        } else if (offset > MINUTE) {
            return (offset / MINUTE) + "分钟前";
        } else {
            return "刚刚";
        }
    }

    /**
     * 检测是否是用户accessToken
     */
    public static boolean isAccessToken(String accessToken) {
        if (TextUtils.isEmpty(accessToken)) {
            return false;
        } else {
            if(accessToken.length() == 32) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 生成自增Integer
     */

    private static int integerSeed = 0;

    public synchronized static int getAutoIncrementInteger() {
        integerSeed++;
        return integerSeed;
    }

    /**
     * 获取菜单导航消息数目字符串
     */
    public static String getNavigationDisplayCountString(int count) {
        if (count > 99) {
            return "99+";
        } else if (count <= 0) {
            return "";
        } else {
            return String.valueOf(count);
        }
    }

    /**
     * 修复头像地址的历史遗留问题
     */
    public static String getCompatAvatarUrl(String avatarUrl) {
        if (!TextUtils.isEmpty(avatarUrl) && avatarUrl.startsWith("//gravatar.com/avatar/")) {
            return "http:" + avatarUrl;
        } else {
            return avatarUrl;
        }
    }

    /**
     * 标准URL检测
     */

    public static boolean isUserLinkUrl(@Nullable String url) {
        return !TextUtils.isEmpty(url) && url.startsWith(ApiDefine.USER_LINK_URL_PREFIX);
    }

    public static boolean isTopicLinkUrl(@Nullable String url) {
        return !TextUtils.isEmpty(url) && url.startsWith(ApiDefine.TOPIC_LINK_URL_PREFIX);
    }

    /**
     * CNode兼容性的Markdown转换
     * '@'协议转换为'/user/'相对路径
     * 解析裸链接
     * 最外层包裹'<div class="markdown-text"></div>'
     * 尽可能的实现和服务端渲染相同的结果
     */

    private static final Markdown md = new Markdown();

    public static String renderMarkdown(String text) {
        // 保证text不为null
        text = TextUtils.isEmpty(text) ? "" : text;
        // 解析@协议
        text = text.replaceAll("@([\\w\\-]+)\\b(?![\\]\\<\\.])", "[@$1](" + ApiDefine.USER_PATH_PREFIX + "$1)");
        // 解析裸链接
        text = text + " ";
        text = text.replaceAll("((http|https|ftp)://[\\w\\-.:/?=&#%]+)(\\s)", "[$1]($1)$3");
        text = text.trim();
        // 渲染markdown
        try {
            StringWriter out = new StringWriter();
            md.transform(new StringReader(text), out);
            text = out.toString();
        } catch (ParseException e) {
            // nothing to do
        }
        // 添加样式容器
        return "<div class=\"markdown-text\">" + text + "</div>";
    }

    /**
     * CNode兼容性的Html处理
     * 过滤xss
     * 保留div的class属性,但是会清除其他非白名单属性
     * 通过baseUrl补全相对地址
     */

    private static final Cleaner cleaner = new Cleaner(Whitelist.relaxed().addAttributes("div", "class")); // 主要目的是保留最外层div的markdown-text属性

    public static String handleHtml(String html) {
        // 保证html不为null
        html = TextUtils.isEmpty(html) ? "" : html;
        // 过滤xss
        Document document = cleaner.clean(Jsoup.parseBodyFragment(html, ApiDefine.HOST_BASE_URL));
        // 返回body
        return document.body().html();
    }

}