package com.likewind.myapplication

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.ContextMenu
import android.view.MenuItem
import android.view.View
import android.webkit.*
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import com.likewind.myapplication.R
import kotlin.random.Random


class MainActivity : AppCompatActivity() {

    lateinit var webView: WebView
    lateinit var context: Context
    lateinit var activity: Activity
    lateinit var downloadListener: DownloadListener
    var writeAccess = false

    /** Permission Request Code */
    private val PERMISSION_REQUEST_CODE = 1234


    /** Sample Page from which we will download the file */
    //private val downloadPage = "https://demo.vl.fyi/PHP/DownloadFile/index.php"
    //private val downloadPage = "https://likewind.ml/doku.php?id=journey:%EC%97%AC%ED%96%89"
    private val downloadPage = "https://likewind.cloud/doku.php?id=journey:%EC%97%AC%ED%96%89"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /** Application Context and Main Activity */
        context = applicationContext
        activity = this

        /** Initialize main layout and web view */
        webView = findViewById(R.id.webView)

        /** Check permission to write in external storage */
        checkWriteAccess()
        /** Create a Download Listener */
        createDownloadListener()
        /** Display Toast Message When Download Complete */
        onDownloadComplete()
        /** Configure Web View */
        configureWebView()

        //getRandomQuote()
        //val quotes = arrayOf("Alert today – Alive tomorrow.","Say hello - test", "Are you - crazy")


        //Log.d("tag111111", "msg"+getRandomQuote())

        Toast.makeText(this, getRandomQuote(), Toast.LENGTH_SHORT).show()

        registerForContextMenu(webView)
    }

    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
        } else {
            super.onBackPressed()
        }
    }

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)
        menuInflater.inflate(R.menu.context, menu)
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_share -> {
                webView.loadUrl("https://likewind.cloud/doku.php?id=journey:%EC%97%AC%ED%96%89")

                //binding.webView.url?.let { url ->
                // 페이지 공유
                //    share(url)
                //}
                return true
            }
            R.id.action_browser -> {
                webView.reload()
                //binding.webView.url?.let { url ->
                // 기본 웹 브라우저에서 열기
                //    browse(url)
                //}
                return true
            }
            R.id.action_location -> {
                webView.loadUrl("https://likewind.cloud/doku.php?id=journey:bicycle_route")
            }

            R.id.action_guestbook -> {
                webView.loadUrl("https://likewind.cloud/doku.php?id=guestbook")
            }

            R.id.action_help -> {
                webView.loadUrl("https://likewind.cloud/doku.php?id=computer:programming:%EC%97%AC%ED%96%89%EA%B8%B0_%EC%95%B1_%EC%82%AC%EC%9A%A9%EB%B2%95")
            }
        }
        return super.onContextItemSelected(item)
    }


    private fun onDownloadComplete()
    {
        /**  Code that receives and handles broadcast intents sent by Context.sendBroadcast(Intent) */
        val onComplete = object : BroadcastReceiver() {
            override fun onReceive(ctxt: Context, intent: Intent) {
                Toast.makeText(context,"File Downloaded",Toast.LENGTH_LONG).show()
            }
        }

        /** Register to receives above broadcast */
        registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    @SuppressLint("SetJavaScriptEnabled")
    private fun configureWebView()
    {

        /** Web View General Setup */

        /**
        When user clicks on an URL the default behaviour is android open the default application
        which handles URL. It means android will open a default browser. We need to handle this.
        Why? Because we need to open the URL in the same web view. In our MyWebViewClient we
        will override shouldOverrideUrlLoading function to again load the new url in our
        web view.
         */
        webView.webViewClient = MyWebViewClient()
        /** getSettings() : Gets the WebSettings object used to control the settings for this WebView. */
        /** We will use it to enable the Java Script Support. */
        webView.settings.javaScriptEnabled = true
        webView.settings.builtInZoomControls = true
        webView.settings.setSupportZoom(true)
        webView.settings.displayZoomControls = false

        
        /** loadUrl : Loads the given URL. */
        webView.loadUrl(downloadPage)

        /** File Download Listener */
        webView.setDownloadListener(downloadListener)
    }


    /**
     * Custom WebViewClient to override URL Loading.
     */

    private inner class MyWebViewClient : WebViewClient() {

        /**
         * Override to open URL in WebView
         * */
        override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
            view.loadUrl(url)
            return true
        }

        /**
         * Override to open URL in WebView
         * */
        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
            view.loadUrl(request.url.toString())
            return true
        }
    }


    private fun createDownloadListener()
    {


        /** A New Download Listener for our WebView */
        downloadListener = DownloadListener { url, userAgent, contentDescription, mimetype, contentLength ->

            /**
             * This class contains all the information necessary to request a new download.
             * The URI is the only required parameter. Note that the default download destination
             * is a shared volume where the system might delete your file if it needs to reclaim
             * space for system use.
             * */
            val request = DownloadManager.Request(Uri.parse(url))

            /**
             * If the file to be downloaded is to be scanned by MediaScanner, this method should
             * be called before DownloadManager.enqueue(Request) is called.
             */
            request.allowScanningByMediaScanner()

            /**
             * Control whether a system notification is posted by the download manager while this
             * download is running or when it is completed.
             * */
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)

            /**
             * Guesses canonical filename that a download would have, using the
             * URL and contentDisposition.
             * */

            //Log.d("tag0", "msg"+url)
            //Log.d("tag1", "msg"+contentDescription)

            var str_arr = url.split(":")

            //Log.d("tag1-1", "msg"+str_arr.get(0))
            //Log.d("tag1-1", "msg"+str_arr.get(1))
            //Log.d("tag1-1", "msg"+str_arr.get(2))
            //Log.d("tag1-1", "msg"+str_arr.last())

            //val fileName = URLUtil.guessFileName(url, contentDescription, mimetype)

            val fileName = str_arr.last()   // modify code by wjkim

            //Log.d("tag2", "msg"+fileName)

            /**
             * Set the local destination for the downloaded file to a path within the public
             * external storage directory (as returned by Environment.getExternalStoragePublicDirectory(String)).
             * */
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)

            /**
             * Get Download Manager Service
             * */
            val dManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager

            /**
             * Enqueue a new request to Download our File.
             * */

            if(writeAccess)
                dManager.enqueue(request)
            else
            {
                Toast.makeText(context,"Unable to download file. Required Privileges are not available.",Toast.LENGTH_LONG).show()
                checkWriteAccess()
            }

        }
    }

    private fun checkWriteAccess()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            /**
             * Check for permission status.
             * */
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
            {
                if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE))
                {
                    val builder = AlertDialog.Builder(activity)
                    builder.setMessage("Required permission to write external storage to save downloaded file.")
                    builder.setTitle("Please Grant Write Permission")
                    builder.setPositiveButton("OK") { _, _->
                        ActivityCompat.requestPermissions(
                            activity,
                            arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                            PERMISSION_REQUEST_CODE
                        )
                    }
                    builder.setNeutralButton("Cancel", null)
                    val dialog = builder.create()
                    dialog.show()
                } else {
                    ActivityCompat.requestPermissions(
                        activity,
                        arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                        PERMISSION_REQUEST_CODE
                    )
                }
            }
            else {
                /**
                 * Already have required permission.
                 * */
                // modify code
                writeAccess = true
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            PERMISSION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    writeAccess=true
                } else {
                    // Permission denied
                    writeAccess=false
                    Toast.makeText(context,"Permission Denied. This app will not work with right permission.",Toast.LENGTH_LONG).show()
                }
            }
        }
    }

    private fun getRandomQuote(): String {
        val quotes = arrayOf(
            "자신을 둘러싼 껍질을 깨고 나오면 닭이 되지만, 남이 껍질을 깨주면 계란 후라이가 된다",
            "그 누구도 인생이 끝날 때 '아, 사무실에서 더 열심히 일할 걸' 이라는 말을 하고 싶어 하지 않는다",
            "여유를 갖고 자신의 개성대로 사세요",
            "생각하며 살지 않으면, 사는대로 생각하게 된다",
            "꿈만 꾸지 말고, 종이에 적어라",
            "배는 항구에 있을 때 가장 안전하다. 하지만 배는 그럴려고 만들어진 것이 아니다"
        )

        val randomValue = Random.nextInt(quotes.size)
        return quotes[randomValue]
    }

}
