package net.mabako.steamgifts.adapters.viewholder;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.view.View;

import net.mabako.steamgifts.activities.UrlHandlingActivity;
import net.mabako.steamgifts.core.R;

import java.util.regex.Pattern;

public final class StringUtils {
    private static final Pattern
            tdPattern = Pattern.compile("</td>([\\s\\r\\n]+)<td"),
            thPattern = Pattern.compile("</th>([\\s\\r\\n]+)<th");

    public static CharSequence fromHtml(@NonNull Context context, String source) {
        return fromHtml(context, source, true, null);
    }

    public static CharSequence fromHtml(@NonNull Context context, String source, boolean useCustomViewHandler, @Nullable Html.ImageGetter imageGetter) {
        if (TextUtils.isEmpty(source))
            return source;

        source = source
                .replace("\r\n", "\n")
                .replace("</tr>", "</tr><br/>");
        source = thPattern.matcher(tdPattern.matcher(source).replaceAll(" | </td><td")).replaceAll(" | </th><th");

        if (useCustomViewHandler) {
            try {
                CharSequence cs = Html.fromHtml(source, imageGetter, new CustomHtmlTagHandler());
                cs = trim(cs, 0, cs.length());
                return addProperLinks(context, cs);
            } catch (Exception e) {
                Log.e(StringUtils.class.getSimpleName(), "Failed to parse HTML with custom parser", e);
            }
        }

        CharSequence cs = Html.fromHtml(source, imageGetter, null);
        cs = trim(cs, 0, cs.length());
        return addProperLinks(context, cs);
    }

    private static CharSequence trim(CharSequence s, int start, int end) {
        while (start < end && Character.isWhitespace(s.charAt(start))) {
            start++;
        }

        while (end > start && Character.isWhitespace(s.charAt(end - 1))) {
            end--;
        }

        return s.subSequence(start, end);
    }

    /**
     * Convert all {@link URLSpan} (which uses the default browser) to use our custom {@link ClickableSpan} instead.
     *
     * @param context
     * @param charSequence
     * @return
     */
    private static CharSequence addProperLinks(final Context context, CharSequence charSequence) {
        if (TextUtils.isEmpty(charSequence))
            return charSequence;

        SpannableStringBuilder stringBuilder = new SpannableStringBuilder(charSequence);
        URLSpan[] urls = stringBuilder.getSpans(0, charSequence.length(), URLSpan.class);
        for (URLSpan span : urls) {
            int start = stringBuilder.getSpanStart(span);
            int end = stringBuilder.getSpanEnd(span);
            int flags = stringBuilder.getSpanFlags(span);

            final String url = span.getURL();
            if (url.startsWith("http://") || url.startsWith("https://")) {
                // Custom Span for clicking
                stringBuilder.setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        // Do we have anything in the app we can open with that url?
                        UrlHandlingActivity.getIntentForUri(context, Uri.parse(url), true).start((Activity) context);
                    }
                }, start, end, flags);
                stringBuilder.removeSpan(span);
            }
        }

        return stringBuilder;
    }

    public static void setBackgroundDrawable(Context context, View view, boolean highlighted) {
        setBackgroundDrawable(context, view, highlighted, R.attr.colorHighlightBackground);
    }

    @SuppressWarnings("deprecation")
    public static void setBackgroundDrawable(Context context, View view, boolean highlighted, @AttrRes int attr) {
        if (highlighted) {
            int attrs[] = new int[]{attr};
            TypedArray ta = context.getTheme().obtainStyledAttributes(attrs);

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                view.setBackgroundDrawable(ta.getDrawable(0));
            } else {
                view.setBackground(ta.getDrawable(0));
            }
        } else {
            view.setBackgroundResource(R.color.colorTransparent);
        }
    }

    private StringUtils() {
    }
}

@@ -551,16 +551,45 @@
 ew.View;
+%0Aimport android.widget.Toast;
 %0A%0Aimport
@@ -747,16 +747,231 @@
 Utils %7B%0A
+    private static final String TAG = StringUtils.class.getSimpleName();%0A%0A    /**%0A     * Base path to resolve relative URLs.%0A     */%0A    private static final Uri BASE_URI = Uri.parse(%22https://www.steamgifts.com%22);%0A%0A
     priv
@@ -2881,16 +2881,25 @@
 erLinks(
+@NonNull 
 final Co
@@ -3469,66 +3469,539 @@
     
-if (url.startsWith(%22http://%22) %7C%7C url.startsWith(%22https://%22
+Uri uri = Uri.parse(span.getURL());%0A%0A            // We only have a relative URL, relative to the base site.%0A            // This would ignore you if you'd reference ../somewhere or alike with the path not starting with /.%0A            if (uri.isRelative() && url.startsWith(%22/%22)) %7B%0A                uri = Uri.withAppendedPath(BASE_URI, url);%0A                Log.v(TAG, %22Resolved relative URL %22 + url + %22 to %22 + uri);%0A            %7D%0A%0A            if (uri.isAbsolute() && (%22https%22.equals(uri.getScheme()) %7C%7C %22http%22.equals(uri.getScheme())
 )) %7B
@@ -4045,16 +4045,62 @@
 licking%0A
+                final Uri clickableUri = uri;%0A
         
@@ -4394,22 +4394,20 @@
 xt, 
-Uri.parse(url)
+clickableUri
 , tr
@@ -4502,32 +4502,380 @@
 s);%0A            
+%7D else %7B%0A                stringBuilder.setSpan(new ClickableSpan() %7B%0A                    @Override%0A                    public void onClick(View widget) %7B%0A                        Toast.makeText(context, %22Unable to open link %22 + url + %22.%22, Toast.LENGTH_LONG).show();%0A                    %7D%0A                %7D, start, end, flags);%0A            %7D%0A        
     stringBuilde
@@ -4893,30 +4893,16 @@
 n(span);
-%0A            %7D
 %0A       

resolve relative URLs in giveaway descriptions, comments etc. and show an appropriate message if it could not be opened.