//
//  ProxyWebViewController.swift
//  DNSResolverSwiftDemo
//
//  Created by issuser on 2025/9/2.
//

import UIKit
import WebKit

class ProxyWebViewController: UIViewController {
    
    private var webView: WKWebView!
    private var statusLabel: UILabel!
    private var urlTextField: UITextField!
    private var goButton: UIButton!
    private var targetURL: URL
    private var navigationStartTime: Date?

    init(url: URL) {
        self.targetURL = url
        super.init(nibName: nil, bundle: nil)
        title = "WKWebView 本地代理场景"
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - DNS Resolution

    private func resolveHostnameWithPDNS(_ hostname: String) -> [String]? {
        if let cachedIPs = DNSResolver.share()?.getIpv4ByCache(withDomain: hostname, andExpiredIPEnabled: true), !cachedIPs.isEmpty {
            print("DNS resolved getIpv4ByCacheWithDomain: \(hostname) to IPs: \(cachedIPs)")
            return cachedIPs
        }

        let semaphore = DispatchSemaphore(value: 0)
        var resolvedIPs: [String] = []

        DNSResolver.share()?.getIpv4Data(withDomain: hostname) { dataArray in
            if let dataArray = dataArray, !dataArray.isEmpty {
                resolvedIPs.append(contentsOf: dataArray)
            }
            semaphore.signal()
        }

        _ = semaphore.wait(timeout: .distantFuture)

        if !resolvedIPs.isEmpty {
            print("DNS resolved getIpv4DataWithDomain: \(hostname) to IPs: \(resolvedIPs)")
            return resolvedIPs
        } else {
            print("DNS resolution failed for domain: \(hostname)")
            return nil
        }
    }

    // MARK: - Proxy Configuration

    @available(iOS 17.0, *)
    private func configureWithLocalProxy(_ configuration: WKWebViewConfiguration) -> Bool {
        guard PDNSLocalHttpProxy.isProxyReady() else {
            print("PDNSLocalHttpProxy service is not ready yet")
            return false
        }

        PDNSLocalHttpProxy.setDNSResolverBlock { [weak self] hostname in
            return self?.resolveHostnameWithPDNS(hostname) ?? []
        }

        PDNSLocalHttpProxy.setLogLevel(.info)
        let success = PDNSLocalHttpProxy.install(into: configuration)

        if success {
            print("PDNSHttpLocalProxy configured successfully for WebView")
        } else {
            print("PDNSHttpLocalProxy configuration failed, using default networking")
        }

        return success
    }

    // MARK: - View Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // Navigation bar reload button
        navigationItem.rightBarButtonItem = UIBarButtonItem(
            barButtonSystemItem: .refresh,
            target: self,
            action: #selector(reloadWebView)
        )

        // Status Label
        statusLabel = UILabel()
        statusLabel.font = UIFont.systemFont(ofSize: 14)
        statusLabel.textAlignment = .center
        statusLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(statusLabel)

        // URL TextField
        urlTextField = UITextField()
        print("加载的url为：\(targetURL.absoluteString)")
        urlTextField.placeholder = "Enter URL (e.g., \(targetURL.absoluteString))"
        urlTextField.text = targetURL.absoluteString
        urlTextField.borderStyle = .roundedRect
        urlTextField.font = UIFont.systemFont(ofSize: 14)
        urlTextField.delegate = self
        urlTextField.keyboardType = .URL
        urlTextField.autocapitalizationType = .none
        urlTextField.autocorrectionType = .no
        urlTextField.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(urlTextField)

        // Go Button
        goButton = UIButton(type: .system)
        goButton.setTitle("Go", for: .normal)
        goButton.translatesAutoresizingMaskIntoConstraints = false
        goButton.addTarget(self, action: #selector(goButtonTapped), for: .touchUpInside)
        view.addSubview(goButton)

        let configuration = WKWebViewConfiguration()

        var proxyConfigured = false

        if #available(iOS 17.0, *) {
            proxyConfigured = configureWithLocalProxy(configuration)
        } else {
            print("iOS < 17.0: Using standard WebView without proxy")
        }

        // Update status label
        if #available(iOS 17.0, *) {
            if proxyConfigured {
                statusLabel.text = "LocalProxy: Installed ✓"
                statusLabel.textColor = .systemGreen
            } else {
                statusLabel.text = "LocalProxy: Installation Failed"
                statusLabel.textColor = .systemRed
            }
        } else {
            statusLabel.text = "LocalProxy: Not Available (iOS < 17.0)"
            statusLabel.textColor = .systemGray
        }

        webView = WKWebView(frame: view.bounds, configuration: configuration)
        webView.navigationDelegate = self
        view.addSubview(webView)

        // Constraints
        NSLayoutConstraint.activate([
            // Status Label
            statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
            statusLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            statusLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            statusLabel.heightAnchor.constraint(equalToConstant: 20),

            // URL TextField
            urlTextField.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 8),
            urlTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            urlTextField.heightAnchor.constraint(equalToConstant: 36),

            // Go Button
            goButton.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 8),
            goButton.leadingAnchor.constraint(equalTo: urlTextField.trailingAnchor, constant: 8),
            goButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            goButton.heightAnchor.constraint(equalToConstant: 36),
            goButton.widthAnchor.constraint(equalToConstant: 50)
        ])

        let request = URLRequest(url: targetURL)
        navigationStartTime = Date()
        webView.load(request)
    }

    @objc private func reloadWebView() {
        webView.reload()
    }

    @objc private func goButtonTapped() {
        loadURLFromTextField()
    }

    private func loadURLFromTextField() {
        guard var urlString = urlTextField.text, !urlString.isEmpty else { return }

        if !urlString.hasPrefix("http://") && !urlString.hasPrefix("https://") {
            urlString = "https://" + urlString
        }

        guard let url = URL(string: urlString) else { return }

        targetURL = url
        print("加载的url为：\(targetURL.absoluteString)")
        let request = URLRequest(url: url)
        navigationStartTime = Date()
        webView.load(request)
        urlTextField.resignFirstResponder()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let safeArea = view.safeAreaLayoutGuide.layoutFrame
        let topControlsHeight: CGFloat = 20 + 8 + 36 + 8 // status + padding + field + padding
        webView.frame = CGRect(
            x: safeArea.origin.x,
            y: safeArea.origin.y + topControlsHeight,
            width: safeArea.width,
            height: safeArea.height - topControlsHeight
        )
    }
}

// MARK: - UITextFieldDelegate

extension ProxyWebViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        loadURLFromTextField()
        return true
    }
}

// MARK: - WKNavigationDelegate

extension ProxyWebViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if let startTime = navigationStartTime {
            let totalTime = Date().timeIntervalSince(startTime)
            print("✅ WKWebView + 本地代理方案加载\(targetURL.absoluteString)--资源总加载时间: \(String(format: "%.3f", totalTime)) 秒")
        }
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("❌ WKWebView + 本地代理方案加载\(targetURL.absoluteString)--加载失败: \(error.localizedDescription)")
    }
}


