/**
 * HomeFragment.kt
 * SkyLink Android - 首页片段
 *
 * 显示视频、GPS 和统计信息
 *
 * @author flowzl
 * @date 2026-01-19
 */

package com.skylink.app.ui

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import android.widget.EditText
import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.skylink.app.R
import com.skylink.app.network.DecodedFrame
import com.skylink.app.network.UdpReceiver
import com.skylink.app.network.UdpReceiverListener
import com.skylink.app.utils.BitmapUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

class HomeFragment : Fragment(), UdpReceiverListener {

    companion object {
        private const val TAG = "HomeFragment"
    }

    // ========================================================================
    // UI 组件
    // ========================================================================

    private var videoImageView: ImageView? = null
    private var gpsTextView: TextView? = null
    private var statsTextView: TextView? = null
    private var statusTextView: TextView? = null
    private var saveButton: Button? = null
    private var recordButton: Button? = null
    private var triggerCaptureButton: Button? = null
    private var triggerCaptureOriginalButton: Button? = null
    private var triggerCaptureThumbnailButton: Button? = null
    
    // HTTP客户端（用于调用ROS2服务）
    private val httpClient = OkHttpClient()
    
    // ROS2节点配置
    private var ros2NodeIp = "192.168.1.100"  // 默认IP，需要配置
    private var ros2HttpPort = 8080

    // ========================================================================
    // 业务逻辑
    // ========================================================================

    private var udpReceiver: UdpReceiver? = null
    private var currentFrame: DecodedFrame? = null
    private var isRecording = false
    private var totalPhotosReceived = 0  // 接收到的总照片数

    // ========================================================================
    // 生命周期方法
    // ========================================================================

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initUI(view)
        startUdpReceiver()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        stopUdpReceiver()
    }

    // ========================================================================
    // UI 初始化
    // ========================================================================

    private fun initUI(view: View) {
        videoImageView = view.findViewById(R.id.video_image)
        gpsTextView = view.findViewById(R.id.gps_text)
        statsTextView = view.findViewById(R.id.stats_text)
        statusTextView = view.findViewById(R.id.status_text)
        saveButton = view.findViewById(R.id.save_button)
        recordButton = view.findViewById(R.id.record_button)
        triggerCaptureButton = view.findViewById(R.id.trigger_capture_button)
        triggerCaptureOriginalButton = view.findViewById(R.id.trigger_capture_original_button)
        triggerCaptureThumbnailButton = view.findViewById(R.id.trigger_capture_thumbnail_button)

        // 设置按钮点击监听
        saveButton?.setOnClickListener {
            onSaveFrameClicked()
        }

        recordButton?.setOnClickListener {
            onRecordToggled()
        }
        
        triggerCaptureButton?.setOnClickListener {
            showTriggerCaptureDialog()
        }
        
        triggerCaptureOriginalButton?.setOnClickListener {
            triggerCapture(0) // 原图模式
        }
        
        triggerCaptureThumbnailButton?.setOnClickListener {
            triggerCapture(1) // 缩略图模式
        }
    }

    // ========================================================================
    // UDP 接收器管理
    // ========================================================================

    private fun startUdpReceiver() {
        if (udpReceiver == null) {
            udpReceiver = UdpReceiver(listenPort = 9999, listener = this)
            udpReceiver?.start()
            updateStatus("接收器已启动，等待数据...")
        }
    }

    private fun stopUdpReceiver() {
        udpReceiver?.stop()
        udpReceiver = null
    }

    // ========================================================================
    // UDP 接收器回调
    // ========================================================================

    override fun onFrameDecoded(frame: DecodedFrame) {
        currentFrame = frame
        
        // 更新照片计数
        if (frame.photoNumber > 0) {
            totalPhotosReceived++
        }

        // 移到后台线程执行解码，避免阻塞 UI 线程，进而影响 UDP 接收协程（如果是单核或高负载）
        lifecycleScope.launch(Dispatchers.Default) {
             val bitmap = BitmapUtils.decodeBitmap(frame.imageData)
             if (bitmap != null) {
                 withContext(Dispatchers.Main) {
                     view?.let {
                         // 在图像上叠加显示照片编号
                         val bitmapWithText = if (frame.photoNumber > 0) {
                             addPhotoNumberToBitmap(bitmap, frame.photoNumber)
                         } else {
                             bitmap
                         }
                         videoImageView?.setImageBitmap(bitmapWithText)
                         updateGpsInfo(frame)
                     }
                 }
             }
        }
    }

    override fun onStatsUpdated(fps: Int, kbps: Int, packetLoss: Double) {
        val statsText = StringBuilder()
        statsText.append(String.format("FPS: %d\nSpeed: %d KB/s\nPacket Loss: %.1f%%", fps, kbps, packetLoss))
        if (totalPhotosReceived > 0) {
            statsText.append(String.format("\nTotal Photos: %d", totalPhotosReceived))
        }
        statsTextView?.text = statsText.toString()
    }

    override fun onError(message: String, exception: Exception?) {
        view?.let {
            Toast.makeText(context, "错误: $message", Toast.LENGTH_SHORT).show()
            updateStatus("❌ $message")
        }
    }

    // ========================================================================
    // UI 事件处理
    // ========================================================================

    private fun onSaveFrameClicked() {
        val frame = currentFrame
        if (frame != null) {
            val bitmap = BitmapUtils.decodeBitmap(frame.imageData)
            if (bitmap != null) {
                // 这里可以保存到文件系统
                Toast.makeText(context, "帧已保存", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(context, "还没有接收到图像", Toast.LENGTH_SHORT).show()
        }
    }

    private fun onRecordToggled() {
        isRecording = !isRecording
        recordButton?.text = if (isRecording) "⏹ 停止录制" else "⏺ 开始录制"
        updateStatus(if (isRecording) "正在录制..." else "录制已停止")
    }

    // ========================================================================
    // 信息更新
    // ========================================================================

    private fun updateGpsInfo(frame: DecodedFrame) {
        gpsTextView?.text = String.format(
            "Latitude: %.6f°\nLongitude: %.6f°\nAltitude: %.1f m\nTime: %s",
            frame.lat,
            frame.lon,
            frame.alt,
            getTimeString(frame.timestamp)
        )
    }

    private fun updateStatus(message: String) {
        statusTextView?.text = message
    }

    private fun getTimeString(timestamp: Double): String {
        val millis = timestamp.toLong() * 1000
        val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
        return formatter.format(Date(millis))
    }
    
    /**
     * 在图像上叠加显示照片编号
     */
    private fun addPhotoNumberToBitmap(bitmap: Bitmap, photoNumber: Int): Bitmap {
        val mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)
        val canvas = Canvas(mutableBitmap)
        
        val text = "Photo #$photoNumber"
        val paint = Paint().apply {
            color = Color.WHITE
            textSize = 48f
            isAntiAlias = true
            style = Paint.Style.FILL
        }
        
        val textPaint = Paint(paint)
        val textBounds = android.graphics.Rect()
        textPaint.getTextBounds(text, 0, text.length, textBounds)
        
        // 绘制半透明背景
        val bgPaint = Paint().apply {
            color = Color.argb(180, 0, 0, 0)
            style = Paint.Style.FILL
        }
        val padding = 10
        canvas.drawRect(
            10f, 10f,
            (textBounds.width() + padding * 2).toFloat(),
            (textBounds.height() + padding * 2).toFloat(),
            bgPaint
        )
        
        // 绘制文字
        canvas.drawText(text, (10 + padding).toFloat(), (10 + padding + textBounds.height()).toFloat(), textPaint)
        
        return mutableBitmap
    }
    
    /**
     * 显示触发拍照参数输入对话框
     */
    private fun showTriggerCaptureDialog() {
        val view = layoutInflater.inflate(R.layout.dialog_trigger_capture, null)
        val durationEdit = view.findViewById<EditText>(R.id.duration_edit)
        val countEdit = view.findViewById<EditText>(R.id.count_edit)
        val intervalEdit = view.findViewById<EditText>(R.id.interval_edit)
        val modeSpinner = view.findViewById<android.widget.Spinner>(R.id.mode_spinner)
        
        // 设置Spinner适配器
        val modes = arrayOf("原图", "缩略图")
        val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, modes)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        modeSpinner.adapter = adapter
        
        // 设置默认值
        durationEdit.setText("5.0")
        countEdit.setText("10")
        intervalEdit.setText("0.5")
        
        AlertDialog.Builder(requireContext())
            .setTitle("触发拍照")
            .setView(view)
            .setPositiveButton("确定") { _, _ ->
                val duration = durationEdit.text.toString().toDoubleOrNull() ?: 5.0
                val count = countEdit.text.toString().toIntOrNull() ?: 10
                val interval = intervalEdit.text.toString().toDoubleOrNull() ?: 0.5
                val mode = modeSpinner.selectedItemPosition // 0=原图, 1=缩略图
                
                triggerCaptureWithParams(duration, count, interval, mode)
            }
            .setNegativeButton("取消", null)
            .setNeutralButton("设置") { _, _ ->
                // 显示IP和端口配置对话框
                showConfigDialog()
            }
            .show()
    }
    
    /**
     * 显示配置对话框（IP和端口）
     */
    private fun showConfigDialog() {
        val view = layoutInflater.inflate(android.R.layout.simple_list_item_2, null)
        val ipEdit = EditText(requireContext())
        ipEdit.hint = "ROS2节点IP地址"
        ipEdit.setText(ros2NodeIp)
        
        val portEdit = EditText(requireContext())
        portEdit.hint = "HTTP端口"
        portEdit.inputType = android.text.InputType.TYPE_CLASS_NUMBER
        portEdit.setText(ros2HttpPort.toString())
        
        val layout = android.widget.LinearLayout(requireContext()).apply {
            orientation = android.widget.LinearLayout.VERTICAL
            setPadding(50, 40, 50, 10)
            addView(ipEdit)
            addView(portEdit)
        }
        
        AlertDialog.Builder(requireContext())
            .setTitle("ROS2节点配置")
            .setView(layout)
            .setPositiveButton("确定") { _, _ ->
                ros2NodeIp = ipEdit.text.toString().ifEmpty { "192.168.1.100" }
                ros2HttpPort = portEdit.text.toString().toIntOrNull() ?: 8080
                Toast.makeText(context, "配置已保存: $ros2NodeIp:$ros2HttpPort", Toast.LENGTH_SHORT).show()
            }
            .setNegativeButton("取消", null)
            .show()
    }
    
    /**
     * 快速触发拍照（使用默认参数）
     */
    private fun triggerCapture(mode: Int) {
        triggerCaptureWithParams(5.0, 10, 0.5, mode)
    }
    
    /**
     * 使用参数触发拍照
     */
    private fun triggerCaptureWithParams(duration: Double, count: Int, interval: Double, mode: Int) {
        val modeStr = if (mode == 0) "原图" else "缩略图"
        
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                // 构建JSON请求
                val json = JSONObject().apply {
                    put("duration", duration)
                    put("count", count)
                    put("interval", interval)
                    put("transmission_mode", mode)
                }
                
                val requestBody = json.toString().toRequestBody("application/json".toMediaType())
                val url = "http://$ros2NodeIp:$ros2HttpPort/api/v1/trigger_capture"
                
                val request = Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .addHeader("User-Agent", "SkyLink-Android/1.0")
                    .build()
                
                val response = httpClient.newCall(request).execute()
                
                withContext(Dispatchers.Main) {
                    if (response.isSuccessful) {
                        val responseBody = response.body?.string()
                        if (responseBody != null) {
                            try {
                                val responseJson = JSONObject(responseBody)
                                val success = responseJson.optBoolean("success", false)
                                val message = responseJson.optString("message", "")
                                val totalPhotos = responseJson.optInt("total_photos", 0)
                                
                                if (success) {
                                    Toast.makeText(context, 
                                        "拍照任务已启动！\n$message\n总照片数: $totalPhotos", 
                                        Toast.LENGTH_LONG).show()
                                    updateStatus("拍照任务已启动 ($modeStr)")
                                } else {
                                    Toast.makeText(context, 
                                        "请求失败: $message", 
                                        Toast.LENGTH_LONG).show()
                                    updateStatus("请求失败: $message")
                                }
                            } catch (e: Exception) {
                                Toast.makeText(context, 
                                    "响应解析失败: ${e.message}", 
                                    Toast.LENGTH_SHORT).show()
                                updateStatus("响应解析失败")
                            }
                        } else {
                            Toast.makeText(context, "服务器返回空响应", Toast.LENGTH_SHORT).show()
                            updateStatus("服务器返回空响应")
                        }
                    } else {
                        val errorMsg = when (response.code) {
                            400 -> "请求参数错误"
                            404 -> "API端点不存在"
                            500 -> "服务器内部错误"
                            else -> "HTTP错误: ${response.code}"
                        }
                        Toast.makeText(context, errorMsg, Toast.LENGTH_LONG).show()
                        updateStatus(errorMsg)
                    }
                }
                
            } catch (e: java.net.SocketTimeoutException) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(context, 
                        "请求超时，请检查网络连接和ROS2节点IP地址 ($ros2NodeIp:$ros2HttpPort)", 
                        Toast.LENGTH_LONG).show()
                    updateStatus("请求超时")
                }
            } catch (e: java.net.ConnectException) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(context, 
                        "无法连接到ROS2节点 ($ros2NodeIp:$ros2HttpPort)\n请确认HTTP服务器正在运行", 
                        Toast.LENGTH_LONG).show()
                    updateStatus("连接失败")
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(context, 
                        "调用失败: ${e.message}", 
                        Toast.LENGTH_LONG).show()
                    updateStatus("调用失败: ${e.message}")
                }
            }
        }
    }
}
