/**
 * 自然写互动课堂电视端应用软件 V1.0
 * 多学生同屏对比视图 - 选取学生笔迹并排大屏展示
 *
 * 功能说明：
 * 1. 多学生笔迹同屏对比展示（2/4/6/9宫格布局）
 * 2. 学生选择器（从在线学生列表中选取展示对象）
 * 3. 实时笔迹同步更新（选中学生的笔迹实时追加）
 * 4. 笔迹回放对比（多学生同步回放书写过程）
 * 5. 学生信息叠加显示（姓名、座号、书写进度）
 * 6. 遥控器操作适配（D-Pad选择学生、切换布局）
 * 7. 范字参考叠加（可选显示标准字帖做对比参照）
 */

package com.writech.tv.renderer

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.os.Handler
import android.os.Looper
import android.util.Log
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt

/**
 * 展示布局模式
 */
enum class DisplayLayout(val columns: Int, val rows: Int) {
    SINGLE(1, 1),      // 单人全屏
    DUAL(2, 1),         // 双人并排
    QUAD(2, 2),         // 四宫格
    SIX(3, 2),          // 六宫格
    NINE(3, 3);         // 九宫格

    val cellCount: Int get() = columns * rows
}

/**
 * 学生展示信息
 */
data class StudentDisplayInfo(
    val studentId: String,
    val studentName: String,
    val seatNumber: Int,
    val color: Int,                 // 分配的标识颜色
    var strokeCount: Int = 0,       // 已书写笔画数
    var isWriting: Boolean = false, // 是否正在书写
    var lastUpdateTime: Long = 0    // 最后更新时间
)

/**
 * 多学生同屏对比视图管理器
 * 管理宫格布局中每个单元格的笔迹渲染
 */
class MultiStudentView {

    companion object {
        private const val TAG = "MultiStudentView"

        /** 单元格间距（像素） */
        private const val CELL_PADDING = 8

        /** 标签栏高度（像素） */
        private const val LABEL_HEIGHT = 48

        /** 标签文字大小（像素） */
        private const val LABEL_TEXT_SIZE = 24f

        /** 边框宽度（像素） */
        private const val BORDER_WIDTH = 3f

        /** 正在书写的边框闪烁间隔（毫秒） */
        private const val BLINK_INTERVAL = 500L
    }

    /** 当前布局模式 */
    var layout: DisplayLayout = DisplayLayout.QUAD
        private set

    /** 展示的学生列表（按单元格位置排列） */
    private val displayStudents = CopyOnWriteArrayList<StudentDisplayInfo>()

    /** 每个学生对应的笔迹数据 */
    private val studentStrokes = ConcurrentHashMap<String, MutableList<Stroke>>()

    /** 主线程Handler */
    private val mainHandler = Handler(Looper.getMainLooper())

    /** 绘制用Paint对象 */
    private val borderPaint = Paint().apply {
        style = Paint.Style.STROKE
        strokeWidth = BORDER_WIDTH
        isAntiAlias = true
    }

    private val labelBgPaint = Paint().apply {
        style = Paint.Style.FILL
        color = Color.parseColor("#E0E0E0")
    }

    private val labelTextPaint = Paint().apply {
        color = Color.parseColor("#333333")
        textSize = LABEL_TEXT_SIZE
        isAntiAlias = true
        textAlign = Paint.Align.LEFT
    }

    private val writingIndicatorPaint = Paint().apply {
        color = Color.parseColor("#4CAF50")
        style = Paint.Style.FILL
    }

    private val strokePaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    /** 是否显示范字参考 */
    var showReference: Boolean = false

    /** 范字图片路径 */
    var referencePath: String = ""

    /** 当前选中的单元格索引（遥控器焦点） */
    var selectedCellIndex: Int = -1

    /**
     * 切换布局模式
     */
    fun setLayout(newLayout: DisplayLayout) {
        layout = newLayout
        // 如果学生数超过新布局的容量，截断显示
        while (displayStudents.size > layout.cellCount) {
            val removed = displayStudents.removeAt(displayStudents.size - 1)
            studentStrokes.remove(removed.studentId)
        }
        Log.i(TAG, "布局切换为: ${newLayout.name} (${newLayout.columns}x${newLayout.rows})")
    }

    /**
     * 添加学生到展示区
     * @return 分配的单元格索引，-1表示已满
     */
    fun addStudent(info: StudentDisplayInfo): Int {
        if (displayStudents.size >= layout.cellCount) {
            Log.w(TAG, "展示区已满 (${layout.cellCount}个)")
            return -1
        }

        // 分配颜色
        val coloredInfo = info.copy(
            color = StudentColorPalette.getColor(displayStudents.size)
        )
        displayStudents.add(coloredInfo)
        studentStrokes[info.studentId] = mutableListOf()

        val index = displayStudents.size - 1
        Log.i(TAG, "添加学生: ${info.studentName} -> 单元格$index")
        return index
    }

    /**
     * 移除学生
     */
    fun removeStudent(studentId: String) {
        displayStudents.removeAll { it.studentId == studentId }
        studentStrokes.remove(studentId)
        Log.i(TAG, "移除学生: $studentId")
    }

    /**
     * 添加笔迹数据到指定学生
     */
    fun addStroke(studentId: String, stroke: Stroke) {
        studentStrokes[studentId]?.add(stroke)
        displayStudents.find { it.studentId == studentId }?.let {
            it.strokeCount++
            it.lastUpdateTime = System.currentTimeMillis()
        }
    }

    /**
     * 更新学生书写状态
     */
    fun updateWritingState(studentId: String, isWriting: Boolean) {
        displayStudents.find { it.studentId == studentId }?.isWriting = isWriting
    }

    /**
     * 在Canvas上绘制多学生对比视图
     * @param canvas 目标画布
     * @param width 画布总宽度
     * @param height 画布总高度
     */
    fun draw(canvas: Canvas, width: Int, height: Int) {
        val cols = layout.columns
        val rows = layout.rows

        // 计算每个单元格的尺寸
        val cellWidth = (width - CELL_PADDING * (cols + 1)) / cols
        val cellHeight = (height - CELL_PADDING * (rows + 1)) / rows

        for (index in 0 until min(displayStudents.size, layout.cellCount)) {
            val student = displayStudents[index]
            val col = index % cols
            val row = index / cols

            // 计算单元格位置
            val left = CELL_PADDING + col * (cellWidth + CELL_PADDING)
            val top = CELL_PADDING + row * (cellHeight + CELL_PADDING)
            val cellRect = RectF(
                left.toFloat(), top.toFloat(),
                (left + cellWidth).toFloat(), (top + cellHeight).toFloat()
            )

            // 绘制单元格内容
            drawCell(canvas, cellRect, student, index)
        }
    }

    /**
     * 绘制单个单元格
     */
    private fun drawCell(canvas: Canvas, rect: RectF, student: StudentDisplayInfo, index: Int) {
        // 绘制单元格背景
        val bgPaint = Paint().apply {
            color = Color.WHITE
            style = Paint.Style.FILL
        }
        canvas.drawRoundRect(rect, 8f, 8f, bgPaint)

        // 绘制边框（选中的单元格用高亮边框）
        borderPaint.color = if (index == selectedCellIndex) {
            Color.parseColor("#2196F3") // 选中态蓝色
        } else if (student.isWriting) {
            student.color // 书写中用学生颜色
        } else {
            Color.parseColor("#BDBDBD") // 默认灰色
        }
        borderPaint.strokeWidth = if (index == selectedCellIndex) 5f else BORDER_WIDTH
        canvas.drawRoundRect(rect, 8f, 8f, borderPaint)

        // 绘制标签栏（学生姓名 + 座号 + 书写状态）
        val labelRect = RectF(rect.left, rect.top, rect.right, rect.top + LABEL_HEIGHT)
        labelBgPaint.color = Color.argb(230, Color.red(student.color),
            Color.green(student.color), Color.blue(student.color))
        canvas.drawRoundRect(
            RectF(labelRect.left + 1, labelRect.top + 1, labelRect.right - 1, labelRect.bottom),
            8f, 0f, labelBgPaint
        )

        // 绘制学生姓名
        labelTextPaint.color = Color.WHITE
        labelTextPaint.textSize = LABEL_TEXT_SIZE
        canvas.drawText(
            "${student.seatNumber}号 ${student.studentName}",
            rect.left + 12f, rect.top + LABEL_HEIGHT - 14f,
            labelTextPaint
        )

        // 绘制书写状态指示点（绿色=正在书写）
        if (student.isWriting) {
            canvas.drawCircle(
                rect.right - 20f, rect.top + LABEL_HEIGHT / 2f,
                6f, writingIndicatorPaint
            )
        }

        // 绘制笔迹内容区域
        val contentRect = RectF(
            rect.left + 4f, rect.top + LABEL_HEIGHT + 4f,
            rect.right - 4f, rect.bottom - 4f
        )

        canvas.save()
        canvas.clipRect(contentRect)

        // 计算笔迹缩放（将点阵纸坐标映射到单元格内容区域）
        val scaleX = contentRect.width() / 200f  // 假设点阵纸宽200mm
        val scaleY = contentRect.height() / 280f  // 假设点阵纸高280mm
        val scale = min(scaleX, scaleY)

        canvas.translate(contentRect.left, contentRect.top)
        canvas.scale(scale, scale)

        // 绘制该学生的所有笔迹
        val strokes = studentStrokes[student.studentId] ?: emptyList()
        for (stroke in strokes) {
            drawStroke(canvas, stroke, student.color)
        }

        canvas.restore()

        // 绘制笔画计数
        val countText = "${student.strokeCount}笔"
        labelTextPaint.color = Color.GRAY
        labelTextPaint.textSize = 18f
        canvas.drawText(countText, rect.right - 60f, rect.bottom - 8f, labelTextPaint)
    }

    /**
     * 绘制单个笔画
     */
    private fun drawStroke(canvas: Canvas, stroke: Stroke, color: Int) {
        if (stroke.points.size < 2) return
        strokePaint.color = color
        strokePaint.strokeWidth = stroke.baseWidth

        for (i in 1 until stroke.points.size) {
            val prev = stroke.points[i - 1]
            val curr = stroke.points[i]
            canvas.drawLine(prev.x, prev.y, curr.x, curr.y, strokePaint)
        }
    }

    /**
     * 遥控器方向键导航（移动焦点到相邻单元格）
     */
    fun navigateFocus(direction: Int): Boolean {
        val cols = layout.columns
        val totalCells = min(displayStudents.size, layout.cellCount)

        if (totalCells == 0) return false

        when (direction) {
            0 -> selectedCellIndex = max(0, selectedCellIndex - cols) // 上
            1 -> selectedCellIndex = min(totalCells - 1, selectedCellIndex + cols) // 下
            2 -> selectedCellIndex = max(0, selectedCellIndex - 1) // 左
            3 -> selectedCellIndex = min(totalCells - 1, selectedCellIndex + 1) // 右
        }
        return true
    }

    /** 清除所有展示数据 */
    fun clearAll() {
        displayStudents.clear()
        studentStrokes.clear()
        selectedCellIndex = -1
    }

    /** 获取当前展示的学生数量 */
    fun getDisplayCount(): Int = displayStudents.size

    /** 释放资源 */
    fun release() {
        clearAll()
        Log.i(TAG, "多学生视图已释放")
    }
}
