package com.hongyegroup.cpt_newsfeed.widget.expand;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.appcompat.widget.AppCompatTextView;

import com.guadou.lib_baselib.font_text_view.TypefaceUtil;
import com.guadou.lib_baselib.utils.CommUtils;
import com.hongyegroup.cpt_newsfeed.R;


/**
 * 折叠展开的TextView
 */
public class ExpandTextView extends AppCompatTextView {

    private CharSequence originText;// 原始内容文本
    private int initWidth = 0;// TextView可展示宽度
    private int mMaxLines = 3;// TextView最大行数
    private SpannableString SPAN_CLOSE = null;// 收起的文案(颜色处理)
    private SpannableString SPAN_EXPAND = null;// 展开的文案(颜色处理)
    private String TEXT_EXPAND = "  [更多]";
    private String TEXT_CLOSE = "  [收起]";
    private boolean isLongClick = false;

    public ExpandTextView(Context context) {
        super(context);
        initCloseEnd();
    }

    public ExpandTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initCloseEnd();
    }

    public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initCloseEnd();
    }

    /**
     * 设置TextView可显示的最大行数
     *
     * @param maxLines 最大行数
     */
    @Override
    public void setMaxLines(int maxLines) {
        this.mMaxLines = maxLines;
        super.setMaxLines(maxLines);
    }

    /**
     * 初始化TextView的可展示宽度
     *
     * @param width
     */
    public void initWidth(int width) {
        initWidth = width;
    }

    /**
     * 收起的文案(颜色处理)初始化
     */
    private void initCloseEnd() {
        //设置展开的文本
        SPAN_CLOSE = new SpannableString(TEXT_EXPAND);

        ButtonSpan span = new ButtonSpan(getContext(), new OnClickListener() {
            @Override
            public void onClick(View v) {
                ExpandTextView.super.setMaxLines(Integer.MAX_VALUE);
                setExpandText(originText);
                if (mCallback != null) mCallback.isExpand(1);
            }
        }, R.color.app_blue);

        SPAN_CLOSE.setSpan(span, 0, TEXT_EXPAND.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        SPAN_CLOSE.setSpan(new MyTypefaceSpan(TypefaceUtil.getMedium()), 0, TEXT_EXPAND.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    }

    /**
     * 展开的文案(颜色处理)初始化
     */
    private void initExpandEnd() {
        //设置关闭的文本
        SPAN_EXPAND = new SpannableString(TEXT_CLOSE);
        ButtonSpan span = new ButtonSpan(getContext(), new OnClickListener() {
            @Override
            public void onClick(View v) {
                ExpandTextView.super.setMaxLines(mMaxLines);
                setCloseText(originText);
                if (mCallback != null) mCallback.isExpand(0);
            }
        }, R.color.app_blue);

        SPAN_EXPAND.setSpan(span, 0, TEXT_CLOSE.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        SPAN_EXPAND.setSpan(new MyTypefaceSpan(TypefaceUtil.getMedium()), 0, TEXT_CLOSE.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    }

    /**
     * 默认设置文本方法
     */
    public void setCloseText(CharSequence text) {

        if (SPAN_CLOSE == null) {
            initCloseEnd();
        }
        boolean appendShowAll = false;// true 不需要展开收起功能， false 需要展开收起功能
        originText = text;

        // SDK >= 16 可以直接从xml属性获取最大行数
        int maxLines = 0;
        maxLines = getMaxLines();
//        StringBuilder workingTextBuilder = new StringBuilder(originText);
        CharSequence workingText = originText;
        if (maxLines != -1) {
            Layout layout = createWorkingLayout(workingText);
            if (layout.getLineCount() > maxLines) {
                //获取一行显示字符个数，然后截取字符串数
                workingText = originText.subSequence(0, layout.getLineEnd(maxLines - 1));// 收起状态原始文本截取展示的部分

                String showText = originText.subSequence(0, layout.getLineEnd(maxLines - 1)) + "..." + SPAN_CLOSE;
                Layout layout2 = createWorkingLayout(showText);

                // 对workingText进行-1截取，直到展示行数==最大行数，并且添加 SPAN_CLOSE 后刚好占满最后一行
                while (layout2.getLineCount() > maxLines) {
                    int lastSpace = workingText.length() - 1;
                    if (lastSpace == -1) {
                        break;
                    }
                    workingText = workingText.subSequence(0, lastSpace);
                    layout2 = createWorkingLayout(workingText + "..." + SPAN_CLOSE);
                }

                appendShowAll = true;

            }
        }

        setText(workingText);

        if (appendShowAll) {
            // 必须使用append，不能在上面使用+连接，否则spannable会无效
            append("...");
            append(SPAN_CLOSE);
        }

        setMovementMethod(LinkMovementMethod.getInstance());

        replaceUrlSpan();
    }

    /**
     * 展开
     */
    private void setExpandText(CharSequence text) {
        if (SPAN_EXPAND == null) {
            initExpandEnd();
        }
        Layout layout1 = createWorkingLayout(text);
        Layout layout2 = createWorkingLayout(text + TEXT_CLOSE);
        // 展示全部原始内容时 如果 TEXT_CLOSE 需要换行才能显示完整，则直接将TEXT_CLOSE展示在下一行
        if (layout2.getLineCount() > layout1.getLineCount()) {
            setText(originText + "\n");
        } else {
            setText(originText);
        }
        append(SPAN_EXPAND);

        setMovementMethod(LinkMovementMethod.getInstance());

        replaceUrlSpan();
    }

    /**
     * 填充文本之后尝试替换URLSpan
     */
    private void replaceUrlSpan() {
        CharSequence text = getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) text;

            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);

            if (urls.length > 0) {
                for (URLSpan urlSpan : urls) {
                    //拦截点击,替换Span
                    InterceptUrlSpan interceptUrlSpan = new InterceptUrlSpan(urlSpan.getURL());
                    spannableStringBuilder.setSpan(interceptUrlSpan, sp.getSpanStart(urlSpan), sp.getSpanEnd(urlSpan), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
                }

                //替换之后重新设置进去
                setText(spannableStringBuilder);
            }

        }
    }

    /**
     * 展示全部的文本
     */
    public void showAllText() {
        ExpandTextView.super.setMaxLines(Integer.MAX_VALUE);
        setExpandText(originText);
    }

    /**
     * 展示收缩文本
     */
    public void showExpandText() {
        ExpandTextView.super.setMaxLines(mMaxLines);
        setCloseText(originText);
    }

    //返回textview的显示区域的layout，该textview的layout并不会显示出来，只是用其宽度来比较要显示的文字是否过长
    private Layout createWorkingLayout(CharSequence workingText) {
        return new StaticLayout(workingText, getPaint(), initWidth - getPaddingLeft() - getPaddingRight(),
                Layout.Alignment.ALIGN_NORMAL, getLineSpacingMultiplier(), getLineSpacingExtra(), false);
    }


    private OnExpandCallback mCallback;

    public void setOnExpandCallback(OnExpandCallback callback) {
        mCallback = callback;
    }

    /**
     * 回调,展开和收缩的状态回调
     */
    public interface OnExpandCallback {
        void isExpand(int status); //0为收缩  1是展开
    }


    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (isLongClick) {
            setBackgroundColor(CommUtils.getColor(R.color.gray));
        } else {
            setBackgroundColor(CommUtils.getColor(R.color.white));
        }

        if (event.getAction() == MotionEvent.ACTION_DOWN) {

        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {

            if (isLongClick) {
                setBackgroundColor(CommUtils.getColor(R.color.gray));
            } else {
                setBackgroundColor(CommUtils.getColor(R.color.white));
            }
            isLongClick = false;
        }

        return super.onTouchEvent(event);
    }


    public void setLongClick(boolean longClick) {
        isLongClick = longClick;
    }
}
