package com.mime.dualscreenview.webcontents

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.graphics.Bitmap
import android.net.Uri
import android.net.http.SslError
import android.util.Log
import android.webkit.*
import androidx.core.net.toUri
import com.google.gson.Gson
import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.common.PrefManager
import com.mime.dualscreenview.data.HistoryManager
import com.mime.dualscreenview.data.model.BookPageInfo
import com.mime.dualscreenview.data.model.BookPageInfos
import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.DidFindContents
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.realmListOf
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.select.Elements


open class BaseWebContentsViewer {

    var currentContentsProvider : BaseWebContents? = null
    lateinit var webview : WebView
    lateinit var mainControllInterface : MainControllInterface

    @JavascriptInterface
    fun onBookInfo(jsonData : String) {
        GlobalScope.launch {
            try {
                Blog.LOGE("BaseWebContentsViewer",jsonData)
                val data: JSONObject = JSONObject(jsonData)
                Blog.LOGE("BaseWebContentsViewer",data.toString())
                mainControllInterface?.onBookInfos(jsonData)
            } catch (e : Exception) {

            }
        }
    }

    @SuppressLint("JavascriptInterface")
    constructor(webview : WebView, mainControllInterface : MainControllInterface ) {
        this.webview = webview
        this.mainControllInterface = mainControllInterface
        webview.webChromeClient = rootWebChromeClient
        webview.webViewClient = rootWebViewClient
        webview.settings.textZoom = 100
        webview.addJavascriptInterface(this,"PAgit")
        webview.settings.javaScriptEnabled = true
        webview.settings.javaScriptCanOpenWindowsAutomatically = false
        webview.settings.loadWithOverviewMode = true
        webview.settings.setPluginState(WebSettings.PluginState.ON)
        webview.settings.domStorageEnabled = true
        webview.clearCache(true);
        try {
            webview.removeJavascriptInterface("MyJavaScriptInterface")
        }catch (e :Exception){e.printStackTrace()}
        webview.addJavascriptInterface( BookHelper(),"MyJavaScriptInterface")
        webview.clearHistory();
        webview.clearSslPreferences();
        WebView.setWebContentsDebuggingEnabled(true)
    }

    constructor()

    fun loadContents(webContents: BaseWebContents) {
        currentContentsProvider = webContents
        currentContentsProvider?.let {
            webview.loadUrl(it.getLastedDoamin())
        }

    }

    val rootWebChromeClient = object : WebChromeClient() {
        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            super.onProgressChanged(view, newProgress)
        }
    }

    fun findListItem(callBakItems : DidFindContents) {
        currentContentsProvider?.findListItem(webview,callBakItems)
    }

    fun loadLastInfo(lastInfo: LastInfo) {
        lastInfo?.let { last ->
            currentContentsProvider = WebContentsManger.getBaseWebContentsBy(last.contentsName)
            if (last.pageUrl.startsWith("https://")) {
                webview.loadUrl(last.pageUrl)
            } else {
                try {
                    webview.loadUrl(PrefManager.getLastDomain().plus(last.pageUrl))
                } catch (e : Exception) {
                    webview.loadUrl(PrefManager.getLastDomain())
                }
            }
        }
    }

    val rootWebViewClient = object : WebViewClient() {
//        override fun shouldInterceptRequest(
//            view: WebView?,
//            request: WebResourceRequest?
//        ): WebResourceResponse? {
//            Log.e("shouldInterceptRequest", " >>>> ${request?.url?.toString()} ,  ${request?.url?.toString()?.contains("gif")}")
//
//            if(request?.url?.toString()?.contains("gif") ?: false) {
//                return WebResourceResponse("text/javascript", "UTF-8", null);
//            }
////            if(request?.url?.toString()?.contains(currentContentsProvider?.acccceptResourceKeyword() ?: "") == false && request?.url?.toString()?.contains(currentContentsProvider?.getLastedDoamin() ?: "") == false) {
////                return WebResourceResponse("text/javascript", "UTF-8", null);
////            }
//            return super.shouldInterceptRequest(view, request)
//        }

        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            super.onPageStarted(view, url, favicon)
            mainControllInterface?.onStartLoad()
        }

        override fun onReceivedSslError(
            view: WebView?,
            handler: SslErrorHandler?,
            error: SslError?
        ) {
//            super.onReceivedSslError(view, handler, error)
            Blog.LOGE(log= "onReceivedSslError >> ${error}")
            handler?.proceed()
        }
        override fun onReceivedHttpError(
            view: WebView?,
            request: WebResourceRequest?,
            errorResponse: WebResourceResponse?
        ) {
            Blog.LOGE(log= "onReceivedHttpError >> ${errorResponse}")
//            super.onReceivedHttpError(view, request, errorResponse)
        }


        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            finishedUrl = url ?: ""
            view?.let {
                url?.toUri()?.let {
                    PrefManager.putLastDomain(it.scheme.plus("::/").plus(it.host))
                }

                if(url?.contains("/list/") ?: false && url?.contains("agit") ?: false){
                    findListItem {
                        Blog.LOGE("onPageFinished", url ?: "")
                    }
                } else if (url?.contains("booktoki") ?: false){
//                    findListItem {
//                        Blog.LOGE("onPageFinished", url ?: "")
//                    }
                }
                view?.postDelayed({
                    view?.evaluateJavascript(
                        "function getAll() {\n" +
                                "           MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
                                "        };getAll()"
                    ) { result ->
                        (result as? String)?.let {

                        }
                    }
                }, 500L)

                currentContentsProvider?.doOnloaded(it , { result ->
                    result?.let { mainControllInterface.onLoadedContents(it) }
                } , { complete ->
                    if(complete) {
                        mainControllInterface?.completePageLoad(LastInfo().apply {
                            this.pageUrl = url?.toUri()?.path ?: currentContentsProvider?.getLastedDoamin() ?: ""
                            this.contentsName = currentContentsProvider?.getWebcontentsName() ?: ""
                            this.pageIndex = 0
                        })
                    }
                })
            }
        }
    }
    var finishedUrl : String = ""
    inner class BookHelper {
        @JavascriptInterface
        fun sendValueFromHtml(string: String) {

            Jsoup.parse(string)?.let { html ->

                val toon_intro =  html.getElementsByClass("toon_index")?.first()
                val view_padding =  html.select("#bo_v_con")
                if (toon_intro != null) {
                    Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: ${html.title()}")
                    val bookPageInfos = BookPageInfos()
                    bookPageInfos.bookPageUrl = Uri.parse(finishedUrl).path
                    bookPageInfos.bookTitle = if (toon_intro.getElementsByTag("h3").size > 0) toon_intro.getElementsByTag("h3").get(0).text() else ""
                    bookPageInfos.pages = realmListOf<BookPageInfo>()
                    
                    Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: bookPageInfos >>>> ${Gson().toJson(bookPageInfos)}")
                    val listParent = toon_intro.getElementsByTag("ul").first()
                    if (listParent != null) {
                        listParent.getElementsByTag("li").reversed().forEachIndexed { idx, bookitem ->
                            Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: bookItemInfo ${bookitem.html()}")
                            try {
                                val bookPageInfo = BookPageInfo()
                                bookPageInfo.bookTitle = bookPageInfos.bookTitle
                                bookPageInfo.chapterNum = idx + 1
                                bookPageInfo.chapterID = idx + 1
                                bookPageInfo.chapterTitle = bookitem.getElementsByTag("a").getT()
                                bookPageInfo.bookPageUrl = bookPageInfos.bookPageUrl
                                val href = bookitem.getElementsByTag("a").get(0).attr("href")
                                bookPageInfo.pathUrl = Uri.parse(href).path
                                bookPageInfos.pages.add(bookPageInfo)
                            }catch (nfe : NumberFormatException) {
                                nfe.printStackTrace()
                            }
                        }.apply {

                            HistoryManager.openRealm.writeBlocking {
                                copyToRealm(bookPageInfos, UpdatePolicy.ALL)
//                                Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: bookPageInfos saved >>>> ${bookPageInfos.bookPageUrl}")
                            }
                            mainControllInterface.onBookInfos(bookPageInfos)
                        }
                    }
                }else if (view_padding.size > 0){
//                    Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: ${html.title()}")
                    val contents = StringBuffer()
                    view_padding.get(0).getElementsByTag("P").forEach {
                        it.text().apply {
                            contents.append(this).append("\n")
                        }

                    }
                    if (contents.length > 20) {
                        Uri.parse(finishedUrl).path?.let {
                            HistoryManager.getBooPageInfoContentsSave(it, contents.toString())
                            mainControllInterface.onLoadedContents(contents.toString())
                        }
                    }
                } else {
                    Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: ${html.title()}")
//                    Blog.LOGE("finishedUrl >>> ${finishedUrl}  :::: whole body ${html}")
                }
            }
        }
    }
}

fun Elements.getT()  = if (size > 0) get(0).text() else ""