"""色域图（Gamut）绘制。

Step 2 重构：从 pqAutomationApp.PQAutomationApp.plot_gamut 整体搬迁，
实现与原方法完全一致；原方法仅保留为一行转发。
"""

import matplotlib.image as mpimg

import algorithm.pq_algorithm as pq_algorithm
from app.resources import get_resource_path


def plot_gamut(self, results, coverage, test_type):
    """绘制色域图 - 根据用户选择的参考标准动态计算覆盖率"""
    # 实现从原 PQAutomationApp 方法体原样搬迁，为减少修改面
    # 范围、保持行为一致，给 self 赋值为传入的 app 实例。

    self.gamut_ax_xy.clear()
    self.gamut_ax_uv.clear()

    # ==================== XY 图校准参数 ====================
    XY_ORIGIN_X = 20.55
    XY_ORIGIN_Y = 378.00
    XY_PIXELS_PER_X = 510.6818
    XY_PIXELS_PER_Y = 429.8844

    # ==================== UV 图校准参数 ====================
    UV_ORIGIN_U = 26.91
    UV_ORIGIN_V = 377.16
    UV_PIXELS_PER_U = 615.7260
    UV_PIXELS_PER_V = 599.8432

    # ========== 读取用户选择的参考标准 ==========
    if test_type == "screen_module":
        current_ref = self.screen_gamut_ref_var.get()
    elif test_type == "sdr_movie":
        current_ref = self.sdr_gamut_ref_var.get()
    elif test_type == "hdr_movie":
        current_ref = self.hdr_gamut_ref_var.get()
    else:
        current_ref = "DCI-P3"

    # ========== ✅✅根据参考标准重新计算覆盖率（XY 空间）==========
    xy_coverage = coverage  # 默认使用传入的值
    uv_coverage = 0.0

    try:
        # 提取前 3 个 RGB 点的 xy 坐标
        if len(results) >= 3:
            xy_points = [[result[0], result[1]] for result in results[:3]]

            # 根据参考标准计算 XY 覆盖率
            if current_ref == "BT.2020":
                _, xy_coverage = pq_algorithm.calculate_gamut_coverage_BT2020(
                    xy_points
                )
            elif current_ref == "BT.709":
                _, xy_coverage = pq_algorithm.calculate_gamut_coverage_BT709(
                    xy_points
                )
            elif current_ref == "DCI-P3":
                _, xy_coverage = pq_algorithm.calculate_gamut_coverage_DCIP3(
                    xy_points
                )
            elif current_ref == "BT.601":
                _, xy_coverage = pq_algorithm.calculate_gamut_coverage_BT601(
                    xy_points
                )
            else:
                self.log_gui.log(f"未知参考标准 '{current_ref}'，使用 DCI-P3", level="error")
                _, xy_coverage = pq_algorithm.calculate_gamut_coverage_DCIP3(
                    xy_points
                )
                current_ref = "DCI-P3"

            self.log_gui.log(
                f"XY 空间覆盖率（{current_ref}）: {xy_coverage:.1f}%"
            , level="success")

    except Exception as e:
        self.log_gui.log(f"重新计算 XY 覆盖率失败: {str(e)}", level="error")
        xy_coverage = coverage  # 回退到传入值
    # =================================================

    # ========== 左图：CIE 1931 xy ==========
    try:
        img_xy = mpimg.imread(get_resource_path("assets/cie.png"))
        h_xy, w_xy = img_xy.shape[:2]

        self.log_gui.log(f"加载 XY 色域图: {w_xy}x{h_xy}", level="info")

        self.gamut_ax_xy.imshow(img_xy, extent=[0, w_xy, h_xy, 0], aspect="equal")
        self.gamut_ax_xy.set_xlim(0, w_xy)
        self.gamut_ax_xy.set_ylim(h_xy, 0)
        self.gamut_ax_xy.axis("off")
        self.gamut_ax_xy.set_clip_on(False)

        def cie_xy_to_pixel(x, y):
            """CIE xy → 像素坐标"""
            px = XY_ORIGIN_X + x * XY_PIXELS_PER_X
            py = XY_ORIGIN_Y - y * XY_PIXELS_PER_Y
            return px, py

        if len(results) >= 3:
            red_x, red_y = results[0][0], results[0][1]
            green_x, green_y = results[1][0], results[1][1]
            blue_x, blue_y = results[2][0], results[2][1]

            self.log_gui.log(
                f"测量色域: R({red_x:.4f},{red_y:.4f}) "
                f"G({green_x:.4f},{green_y:.4f}) B({blue_x:.4f},{blue_y:.4f})"
            , level="info")

            # ========== 绘制测量三角形 ==========
            points = [
                cie_xy_to_pixel(red_x, red_y),
                cie_xy_to_pixel(green_x, green_y),
                cie_xy_to_pixel(blue_x, blue_y),
                cie_xy_to_pixel(red_x, red_y),
            ]

            xs = [p[0] for p in points]
            ys = [p[1] for p in points]

            self.gamut_ax_xy.plot(
                xs,
                ys,
                color="red",
                linewidth=2.5,
                marker="o",
                markersize=10,
                markerfacecolor="red",
                markeredgecolor="white",
                markeredgewidth=2,
                label="测量色域",
                zorder=10,
            )

            # ========== 标注 RGB 点 ==========
            labels = ["R", "G", "B"]
            coords = [(red_x, red_y), (green_x, green_y), (blue_x, blue_y)]

            for (x_cie, y_cie), label in zip(coords, labels):
                px, py = cie_xy_to_pixel(x_cie, y_cie)

                # 自适应偏移
                if label == "R":
                    offset = (-60, -40) if x_cie > 0.6 else (0, -60)
                elif label == "G":
                    offset = (0, -60)
                else:  # B
                    offset = (60, 40)

                self.gamut_ax_xy.annotate(
                    f"{label}\n({x_cie:.3f},{y_cie:.3f})",
                    xy=(px, py),
                    xytext=offset,
                    textcoords="offset points",
                    fontsize=9,
                    color="white",
                    fontweight="bold",
                    bbox=dict(
                        boxstyle="round,pad=0.5",
                        facecolor="red",
                        alpha=0.9,
                        edgecolor="white",
                        linewidth=2,
                    ),
                    arrowprops=dict(arrowstyle="->", color="red", lw=2),
                    zorder=11,
                    clip_on=False,
                )

            # ========== 绘制所有参考标准 ==========
            # DCI-P3
            dcip3 = [
                (0.6800, 0.3200),
                (0.2650, 0.6900),
                (0.1500, 0.0600),
                (0.6800, 0.3200),
            ]
            dcip3_px = [cie_xy_to_pixel(x, y) for x, y in dcip3]
            self.gamut_ax_xy.plot(
                [p[0] for p in dcip3_px],
                [p[1] for p in dcip3_px],
                color="blue",
                linewidth=1.5,
                linestyle="--",
                marker="s",
                markersize=6,
                alpha=0.7,
                label="DCI-P3",
                zorder=5,
            )

            # BT.2020
            bt2020 = [
                (0.7080, 0.2920),
                (0.1700, 0.7970),
                (0.1310, 0.0460),
                (0.7080, 0.2920),
            ]
            bt2020_px = [cie_xy_to_pixel(x, y) for x, y in bt2020]
            self.gamut_ax_xy.plot(
                [p[0] for p in bt2020_px],
                [p[1] for p in bt2020_px],
                color="green",
                linewidth=1.5,
                linestyle="-.",
                marker="D",
                markersize=5,
                alpha=0.7,
                label="BT.2020",
                zorder=4,
            )

            # BT.709
            bt709 = [
                (0.6400, 0.3300),
                (0.3000, 0.6000),
                (0.1500, 0.0600),
                (0.6400, 0.3300),
            ]
            bt709_px = [cie_xy_to_pixel(x, y) for x, y in bt709]
            self.gamut_ax_xy.plot(
                [p[0] for p in bt709_px],
                [p[1] for p in bt709_px],
                color="gray",
                linewidth=1.2,
                linestyle=":",
                marker="^",
                markersize=5,
                alpha=0.6,
                label="BT.709",
                zorder=3,
            )

            # BT.601（仅 SDR 测试）
            if test_type == "sdr_movie":
                bt601 = [
                    (0.6300, 0.3400),
                    (0.3100, 0.5950),
                    (0.1550, 0.0700),
                    (0.6300, 0.3400),
                ]
                bt601_px = [cie_xy_to_pixel(x, y) for x, y in bt601]
                self.gamut_ax_xy.plot(
                    [p[0] for p in bt601_px],
                    [p[1] for p in bt601_px],
                    color="purple",
                    linewidth=1.2,
                    linestyle="-",
                    marker="o",
                    markersize=5,
                    alpha=0.6,
                    label="BT.601",
                    zorder=3,
                )

            # ========== XY 覆盖率标注（使用重新计算的值）==========
            self.gamut_ax_xy.text(
                w_xy * 0.85,
                h_xy * 0.92,
                f"参考: {current_ref}\n覆盖率: {xy_coverage:.1f}%",
                ha="right",
                va="bottom",
                fontsize=11,
                fontweight="bold",
                color="red",
                bbox=dict(
                    boxstyle="round,pad=0.5",
                    facecolor="white",
                    alpha=0.95,
                    edgecolor="red",
                    linewidth=2,
                ),
                zorder=12,
            )

            # 图例
            self.gamut_ax_xy.legend(
                loc="upper right",
                fontsize=7,
                framealpha=0.95,
                edgecolor="black",
                fancybox=True,
            )

    except Exception as e:
        self.log_gui.log(f"XY 图绘制失败: {str(e)}", level="error")
        import traceback

        self.log_gui.log(traceback.format_exc(), level="error")

    # ========== 右图：CIE 1976 u'v' ==========
    try:
        img_uv = mpimg.imread(get_resource_path("assets/cie_uv.png"))
        h_uv, w_uv = img_uv.shape[:2]

        self.log_gui.log(f"加载 UV 色域图: {w_uv}x{h_uv}", level="info")

        self.gamut_ax_uv.imshow(img_uv, extent=[0, w_uv, h_uv, 0], aspect="equal")
        self.gamut_ax_uv.set_xlim(0, w_uv)
        self.gamut_ax_uv.set_ylim(h_uv, 0)
        self.gamut_ax_uv.axis("off")
        self.gamut_ax_uv.set_clip_on(False)

        def cie_uv_to_pixel(u, v):
            """CIE u'v' → 像素坐标"""
            px = UV_ORIGIN_U + u * UV_PIXELS_PER_U
            py = UV_ORIGIN_V - v * UV_PIXELS_PER_V
            return px, py

        if len(results) >= 3:
            # 只取前 3 个 RGB 点
            rgb_results = results[:3]

            # 转换为 u'v' 坐标
            def xy_to_uv(x, y):
                """xy → u'v' 转换"""
                denom = -2 * x + 12 * y + 3
                if abs(denom) < 1e-10:
                    return 0, 0
                u = (4 * x) / denom
                v = (9 * y) / denom
                return u, v

            uv_coords = [
                [u, v] for u, v in [xy_to_uv(r[0], r[1]) for r in rgb_results]
            ]

            self.log_gui.log(f"UV 坐标: {uv_coords}", level="info")

            # ========== ✅✅计算 u'v' 覆盖率（使用参考标准）==========
            try:
                uv_coverage = pq_algorithm.calculate_uv_gamut_coverage(
                    uv_coords, reference=current_ref
                )
                self.log_gui.log(
                    f"UV 空间覆盖率（{current_ref}）: {uv_coverage:.1f}%"
                , level="success")
            except Exception as e:
                self.log_gui.log(f"计算 UV 覆盖率失败: {str(e)}", level="error")
                uv_coverage = 0.0
            # =================================================

            # ========== 绘制测量三角形 ==========
            uv_coords_plot = uv_coords + [uv_coords[0]]
            points_uv = [cie_uv_to_pixel(u, v) for u, v in uv_coords_plot]
            xs_uv = [p[0] for p in points_uv]
            ys_uv = [p[1] for p in points_uv]

            self.gamut_ax_uv.plot(
                xs_uv,
                ys_uv,
                color="red",
                linewidth=2.5,
                marker="o",
                markersize=10,
                markerfacecolor="red",
                markeredgecolor="white",
                markeredgewidth=2,
                label="测量色域",
                zorder=10,
            )

            # ========== 标注 RGB 点 ==========
            labels = ["R", "G", "B"]
            for (u, v), label in zip(uv_coords, labels):
                px, py = cie_uv_to_pixel(u, v)

                # 自适应偏移
                if label == "R":
                    if u > 0.42 and v > 0.50:
                        offset = (-70, 20)
                    elif u > 0.45:
                        offset = (30, 50)
                    else:
                        offset = (50, 45)
                elif label == "G":
                    offset = (0, -60)
                else:  # B
                    offset = (60, 40)

                self.gamut_ax_uv.annotate(
                    f"{label}\n({u:.3f},{v:.3f})",
                    xy=(px, py),
                    xytext=offset,
                    textcoords="offset points",
                    fontsize=9,
                    color="white",
                    fontweight="bold",
                    bbox=dict(
                        boxstyle="round,pad=0.5",
                        facecolor="red",
                        alpha=0.9,
                        edgecolor="white",
                        linewidth=2,
                    ),
                    arrowprops=dict(arrowstyle="->", color="red", lw=2),
                    zorder=11,
                    clip_on=False,
                )

            # ========== DCI-P3 参考（蓝色）==========
            dcip3_uv = [
                [0.4970, 0.5260],
                [0.0999, 0.5780],
                [0.1754, 0.1576],
                [0.4970, 0.5260],
            ]
            dcip3_uv_px = [cie_uv_to_pixel(u, v) for u, v in dcip3_uv]

            self.gamut_ax_uv.plot(
                [p[0] for p in dcip3_uv_px],
                [p[1] for p in dcip3_uv_px],
                color="blue",
                linewidth=1.5,
                linestyle="--",
                marker="s",
                markersize=6,
                alpha=0.7,
                label="DCI-P3",
                zorder=5,
            )

            # ========== BT.2020 参考（绿色）==========
            bt2020_uv = [
                [0.5566, 0.5165],
                [0.0556, 0.5868],
                [0.1593, 0.1258],
                [0.5566, 0.5165],
            ]
            bt2020_uv_px = [cie_uv_to_pixel(u, v) for u, v in bt2020_uv]

            self.gamut_ax_uv.plot(
                [p[0] for p in bt2020_uv_px],
                [p[1] for p in bt2020_uv_px],
                color="green",
                linewidth=1.5,
                linestyle="-.",
                marker="D",
                markersize=5,
                alpha=0.7,
                label="BT.2020",
                zorder=4,
            )

            # ========== BT.709 参考（灰色）==========
            bt709_uv = [
                [0.4507, 0.5229],
                [0.1250, 0.5625],
                [0.1754, 0.1576],
                [0.4507, 0.5229],
            ]
            bt709_uv_px = [cie_uv_to_pixel(u, v) for u, v in bt709_uv]

            self.gamut_ax_uv.plot(
                [p[0] for p in bt709_uv_px],
                [p[1] for p in bt709_uv_px],
                color="gray",
                linewidth=1.2,
                linestyle=":",
                marker="^",
                markersize=5,
                alpha=0.6,
                label="BT.709",
                zorder=3,
            )

            # ========== BT.601 参考（紫色）- 仅 SDR 测试显示 ==========
            if test_type == "sdr_movie":
                bt601_uv = [
                    [0.4510, 0.5236],
                    [0.1291, 0.5606],
                    [0.1787, 0.1610],
                    [0.4510, 0.5236],
                ]
                bt601_uv_px = [cie_uv_to_pixel(u, v) for u, v in bt601_uv]

                self.gamut_ax_uv.plot(
                    [p[0] for p in bt601_uv_px],
                    [p[1] for p in bt601_uv_px],
                    color="purple",
                    linewidth=1.2,
                    linestyle="-",
                    marker="o",
                    markersize=5,
                    alpha=0.6,
                    label="BT.601",
                    zorder=3,
                )

            # ========== UV 覆盖率标注（使用动态计算的值）==========
            self.gamut_ax_uv.text(
                w_uv * 0.85,
                h_uv * 0.92,
                f"参考: {current_ref}\n覆盖率: {uv_coverage:.1f}%",
                ha="right",
                va="bottom",
                fontsize=11,
                fontweight="bold",
                color="red",
                bbox=dict(
                    boxstyle="round,pad=0.5",
                    facecolor="white",
                    alpha=0.95,
                    edgecolor="red",
                    linewidth=2,
                ),
                zorder=12,
            )

            # 图例
            self.gamut_ax_uv.legend(
                loc="upper right",
                fontsize=7,
                framealpha=0.95,
                edgecolor="black",
                fancybox=True,
            )

    except Exception as e:
        self.log_gui.log(f"UV 图绘制失败: {str(e)}", level="error")
        import traceback

        self.log_gui.log(traceback.format_exc(), level="error")

    # ========== 总标题 ==========
    test_type_name = self.get_test_type_name(test_type)
    self.gamut_fig.suptitle(
        f"{test_type_name} - 色域测试", fontsize=12, y=0.98, fontweight="bold"
    )

    self.gamut_canvas.draw()
    self.chart_notebook.select(self.gamut_chart_frame)

    self.log_gui.log("色域图绘制完成", level="success")
