package com.cyjai.agent

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.ViewGroup
import android.view.View
import android.webkit.CookieManager
import android.webkit.JavascriptInterface
import android.webkit.PermissionRequest
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowCompat
import java.util.Locale

class MainActivity : AppCompatActivity() {

    private lateinit var webView: WebView
    private var filePathCallback: ValueCallback<Array<Uri>>? = null

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        webView = WebView(this)
        webView.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        webView.isVerticalScrollBarEnabled = false
        webView.isHorizontalScrollBarEnabled = false
        webView.overScrollMode = View.OVER_SCROLL_NEVER
        setContentView(webView)

        ViewCompat.setOnApplyWindowInsetsListener(webView) { view, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            view.setPadding(0, systemBars.top, 0, systemBars.bottom)
            insets
        }
        ViewCompat.requestApplyInsets(webView)

        val cookieManager = CookieManager.getInstance()
        cookieManager.setAcceptCookie(true)
        cookieManager.setAcceptThirdPartyCookies(webView, true)

        webView.settings.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            databaseEnabled = true
            mediaPlaybackRequiresUserGesture = false
            // 你的 Nginx 对静态资源设置了 immutable 长缓存，这里对 App 侧禁用缓存，确保样式更新及时生效
            cacheMode = WebSettings.LOAD_NO_CACHE
            useWideViewPort = true
            loadWithOverviewMode = true
            setSupportZoom(false)
            builtInZoomControls = false
            displayZoomControls = false
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                safeBrowsingEnabled = true
            }
        }
        webView.clearCache(true)

        webView.addJavascriptInterface(ThemeBridge(), "AndroidThemeBridge")

        webView.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                injectThemeObserver()
                injectMobileOverlayWidthPatch()
                injectNoPageScrollPatch()
            }

            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                val url = request?.url?.toString() ?: return false
                if (isApkUrl(url)) {
                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                    startActivity(intent)
                    return true
                }
                return !url.startsWith(HOME_URL)
            }
        }

        webView.webChromeClient = object : WebChromeClient() {
            override fun onPermissionRequest(request: PermissionRequest) {
                // 按需放行媒体权限（例如文件上传触发的媒体访问）
                request.grant(request.resources)
            }

            override fun onShowFileChooser(
                webView: WebView?,
                filePathCallback: ValueCallback<Array<Uri>>?,
                fileChooserParams: FileChooserParams?
            ): Boolean {
                this@MainActivity.filePathCallback?.onReceiveValue(null)
                this@MainActivity.filePathCallback = filePathCallback

                val intent = fileChooserParams?.createIntent() ?: Intent(Intent.ACTION_GET_CONTENT).apply {
                    addCategory(Intent.CATEGORY_OPENABLE)
                    type = "*/*"
                }
                startActivityForResult(intent, FILE_CHOOSER_REQUEST_CODE)
                return true
            }
        }

        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (webView.canGoBack()) {
                    webView.goBack()
                } else {
                    finish()
                }
            }
        })

        if (savedInstanceState == null) {
            webView.loadUrl(buildHomeUrl(), mapOf(
                "Cache-Control" to "no-cache, no-store, must-revalidate",
                "Pragma" to "no-cache"
            ))
        } else {
            webView.restoreState(savedInstanceState)
        }
    }

    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode != FILE_CHOOSER_REQUEST_CODE) return

        val results = WebChromeClient.FileChooserParams.parseResult(resultCode, data)
        filePathCallback?.onReceiveValue(results)
        filePathCallback = null
    }

    override fun onSaveInstanceState(outState: Bundle) {
        webView.saveState(outState)
        super.onSaveInstanceState(outState)
    }

    override fun onDestroy() {
        webView.destroy()
        super.onDestroy()
    }

    private fun applySystemBarTheme(rawTheme: String?) {
        val theme = (rawTheme ?: "").lowercase(Locale.getDefault())
        val isDark = theme == "dark"
        val bgColor = if (isDark) Color.BLACK else Color.WHITE

        window.statusBarColor = bgColor
        window.navigationBarColor = bgColor
        WindowCompat.getInsetsController(window, window.decorView)?.let { controller ->
            controller.isAppearanceLightStatusBars = !isDark
            controller.isAppearanceLightNavigationBars = !isDark
        }
    }

    private fun injectThemeObserver() {
        val script = """
            (function() {
              function readTheme() {
                var t = document.documentElement.getAttribute('data-theme')
                    || document.body.getAttribute('data-theme')
                    || localStorage.getItem('agents_ui_theme')
                    || 'claude';
                return String(t).toLowerCase();
              }
              function notify() {
                if (window.AndroidThemeBridge && window.AndroidThemeBridge.onThemeChanged) {
                  window.AndroidThemeBridge.onThemeChanged(readTheme());
                }
              }
              notify();
              if (!window.__androidThemeObserverInstalled) {
                window.__androidThemeObserverInstalled = true;
                var ob = new MutationObserver(function() { notify(); });
                ob.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
                if (document.body) {
                  ob.observe(document.body, { attributes: true, attributeFilter: ['data-theme'] });
                }
                window.addEventListener('storage', function(e){
                  if (e && e.key === 'agents_ui_theme') notify();
                });
              }
            })();
        """.trimIndent()
        webView.evaluateJavascript(script, null)
    }

    private fun injectMobileOverlayWidthPatch() {
        val script = """
            (function() {
              var styleId = '__android_mobile_overlay_width_patch';
              var css = [
                '.mobile-panel-sheet.mobile-panel-sheet--conversation {',
                '  width: min(420px, 65vw) !important;',
                '  max-width: 65vw !important;',
                '}',
                '.mobile-panel-sheet.mobile-panel-sheet--workspace {',
                '  width: fit-content !important;',
                '  min-width: min(420px, 60vw) !important;',
                '  max-width: 100vw !important;',
                '}'
              ].join('\n');
              var existing = document.getElementById(styleId);
              if (existing) {
                existing.textContent = css;
                return;
              }
              var style = document.createElement('style');
              style.id = styleId;
              style.type = 'text/css';
              style.textContent = css;
              (document.head || document.documentElement).appendChild(style);
            })();
        """.trimIndent()
        webView.evaluateJavascript(script, null)
    }

    private fun injectNoPageScrollPatch() {
        val script = """
            (function() {
              var styleId = '__android_no_page_scroll_patch';
              var css = [
                'html, body {',
                '  overflow: hidden !important;',
                '  height: 100% !important;',
                '  max-height: 100% !important;',
                '}',
                'body {',
                '  position: fixed !important;',
                '  width: 100% !important;',
                '  inset: 0 !important;',
                '}',
                '* {',
                '  scrollbar-width: none !important;',
                '}',
                '*::-webkit-scrollbar {',
                '  width: 0 !important;',
                '  height: 0 !important;',
                '  display: none !important;',
                '}',
                '#app, .app-root, .chat-container {',
                '  max-height: 100% !important;',
                '  overflow: hidden !important;',
                '}'
              ].join('\n');
              var existing = document.getElementById(styleId);
              if (existing) {
                existing.textContent = css;
                return;
              }
              var style = document.createElement('style');
              style.id = styleId;
              style.type = 'text/css';
              style.textContent = css;
              (document.head || document.documentElement).appendChild(style);
            })();
        """.trimIndent()
        webView.evaluateJavascript(script, null)
    }

    inner class ThemeBridge {
        @JavascriptInterface
        fun onThemeChanged(theme: String?) {
            runOnUiThread {
                applySystemBarTheme(theme)
            }
        }

        @JavascriptInterface
        fun getAppVersionCode(): String {
            return getInstalledVersionCode().toString()
        }

        @JavascriptInterface
        fun getAppVersionName(): String {
            return getInstalledVersionName()
        }
    }

    companion object {
        private const val HOME_URL = "https://agent.cyjai.com"
        private const val WEB_ASSET_VERSION = "20260406_4"
        private const val FILE_CHOOSER_REQUEST_CODE = 9001
    }

    private fun buildHomeUrl(): String {
        val vc = getInstalledVersionCode()
        val vn = Uri.encode(getInstalledVersionName())
        return "$HOME_URL/?app_shell=$WEB_ASSET_VERSION&app_vc=$vc&app_vn=$vn"
    }

    private fun getInstalledVersionCode(): Long {
        val pkgInfo = packageManager.getPackageInfo(packageName, 0)
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) pkgInfo.longVersionCode else @Suppress("DEPRECATION") pkgInfo.versionCode.toLong()
    }

    private fun getInstalledVersionName(): String {
        val pkgInfo = packageManager.getPackageInfo(packageName, 0)
        return pkgInfo.versionName ?: "unknown"
    }

    private fun isApkUrl(url: String): Boolean {
        return url.lowercase(Locale.getDefault()).endsWith(".apk") || url.contains("/api/app/apk/latest")
    }
}
