package com.readrops.app.utils;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.readrops.api.utils.HttpManager;
import com.readrops.api.utils.LibUtils;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import okhttp3.Request;
import okhttp3.Response;

public final class HtmlParser {

    private static final String TAG = HtmlParser.class.getSimpleName();

    public static final String COVER_IMAGE_REGEX = "^(<p>|(<div.*>))?<img.*>";

    /**
     * Parse the html page to get all rss urls
     *
     * @param url url to request
     * @return a list of rss urls with their title
     */
    public static List<ParsingResult> getFeedLink(String url) {
        List<ParsingResult> results = new ArrayList<>();

        String head = getHTMLHeadFromUrl(url);
        if (head != null) {
            Document document = Jsoup.parse(head, url);

            Elements elements = document.select("link");

            for (Element element : elements) {
                String type = element.attributes().get("type");

                if (isTypeRssFeed(type)) {
                    String feedUrl = element.absUrl("href");
                    String label = element.attributes().get("title");

                    results.add(new ParsingResult(feedUrl, label));
                }
            }

            return results;
        } else {
            return Collections.emptyList();
        }
    }

    private static boolean isTypeRssFeed(String type) {
        return type.equals(LibUtils.RSS_DEFAULT_CONTENT_TYPE) ||
                type.equals(LibUtils.ATOM_CONTENT_TYPE) ||
                type.equals(LibUtils.JSON_CONTENT_TYPE) ||
                type.equals(LibUtils.RSS_TEXT_CONTENT_TYPE) ||
                type.equals(LibUtils.RSS_APPLICATION_CONTENT_TYPE);
    }

    /**
     * get the feed item image based on open graph metadata.
     * Warning, This method is slow.
     *
     * @param url url to request
     * @return the item image
     */
    public static String getOGImageLink(String url) throws IOException {
        String imageUrl = null;

        String head = getHTMLHeadFromUrl(url);

        Document document = Jsoup.parse(head);
        Element element = document.select("meta[property=og:image]").first();

        if (element != null)
            imageUrl = element.attributes().get("content");

        return imageUrl;
    }

    @Nullable
    public static String getFaviconLink(@NonNull String url) {
        String favUrl = null;

        String head = getHTMLHeadFromUrl(url);
        if (head == null)
            return null;

        Document document = Jsoup.parse(head, url);
        Elements elements = document.select("link");

        for (Element element : elements) {
            if (element.attributes().get("rel").toLowerCase().contains("icon")) {
                favUrl = element.absUrl("href");
                break;
            }
        }

        return favUrl;
    }

    @Nullable
    private static String getHTMLHeadFromUrl(@NonNull String url) {
        long start = System.currentTimeMillis();

        try {
            Response response = HttpManager.getInstance().getOkHttpClient()
                    .newCall(new Request.Builder().url(url).build()).execute();

            if (response.header("Content-Type").contains(LibUtils.HTML_CONTENT_TYPE)) {
                String body = response.body().string();
                String head = body.substring(body.indexOf("<head"), body.indexOf("</head>"));

                long end = System.currentTimeMillis();
                Log.d(TAG, "parsing time : " + (end - start));

                return head;
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }

    }

    public static String getDescImageLink(String description, String url) {
        Document document = Jsoup.parse(description, url);
        Elements elements = document.select("img");

        if (!elements.isEmpty())
            return elements.first().absUrl("src");
        else
            return null;
    }

    public static String deleteCoverImage(String content) {
        Document document = Jsoup.parse(content);

        if (Pattern.compile(COVER_IMAGE_REGEX).matcher(document.body().html()).find()) {
            Elements elements = document.select("img");

            if (!elements.isEmpty())
                elements.first().remove();

            return document.toString();
        } else
            return content;
    }
}
