"use client"

import { memo } from "react"
import { Handle, Position, type NodeProps } from "@xyflow/react"
import { useTranslations } from "next-intl"
import { cn } from "@/shared/lib/utils"
import type { GraphNodeData, MasteryLevel, KpWithRelations } from "../types"
import { NODE_WIDTH } from "../graph-layout"

/** 根据掌握度计算色彩等级 */
function getMasteryLevel(mastery: number | null): MasteryLevel {
  if (mastery === null) return "unassessed"
  if (mastery < 60) return "low"
  if (mastery < 85) return "medium"
  return "high"
}

const MASTERY_COLORS: Record<MasteryLevel, string> = {
  low: "border-red-500 bg-red-50 dark:bg-red-950/30",
  medium: "border-yellow-500 bg-yellow-50 dark:bg-yellow-950/30",
  high: "border-green-500 bg-green-50 dark:bg-green-950/30",
  unassessed: "border-border bg-card",
}

const MASTERY_BAR_COLORS: Record<MasteryLevel, string> = {
  low: "bg-red-500",
  medium: "bg-yellow-500",
  high: "bg-green-500",
  unassessed: "bg-muted",
}

/**
 * 类型守卫：从 React Flow node.data（Record<string, unknown>）安全提取图谱节点数据。
 * 替代 as unknown as 双重断言，提供运行时安全。
 */
function extractNodeData(data: Record<string, unknown>): {
  kp: KpWithRelations
  graphData?: GraphNodeData
} {
  const kp = data.kp as KpWithRelations
  const graphData = data.graphData as GraphNodeData | undefined
  return { kp, graphData }
}

function GraphKpNodeComponent(props: NodeProps) {
  const t = useTranslations("textbooks")
  const { data, selected } = props
  const { kp, graphData } = extractNodeData(data)
  const mastery = graphData?.mastery ?? null
  const masteryLevel = getMasteryLevel(mastery?.masteryLevel ?? null)
  const showMastery = graphData?.viewMode === "student-mastery" || graphData?.viewMode === "class-mastery"

  return (
    <div
      className={cn(
        "rounded-lg border-2 px-3 py-2 shadow-sm transition-all",
        MASTERY_COLORS[masteryLevel],
        selected && "ring-2 ring-primary ring-offset-1",
        graphData?.isHighlighted && "ring-2 ring-primary",
        !graphData?.isHighlighted && graphData !== undefined && "opacity-40",
      )}
      style={{ width: NODE_WIDTH }}
    >
      <Handle type="target" position={Position.Top} className="opacity-0" />

      <div className="flex items-start justify-between gap-2 mb-1">
        <span className="text-xs font-medium line-clamp-2 flex-1">{kp.name}</span>
        {/* 任意值 text-[10px]：图谱节点空间受限，text-xs(12px) 过大 */}
        {kp.questionCount > 0 && (
          <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-primary/10 text-primary shrink-0">
            {kp.questionCount} {t("graph.node.questions")}
          </span>
        )}
      </div>

      {showMastery && (
        <div className="mt-2">
          <div className="flex items-center justify-between text-[10px] text-muted-foreground mb-1">
            <span>{t("graph.node.mastery")}</span>
            <span>
              {mastery ? `${Math.round(mastery.masteryLevel)}%` : t("graph.detail.masteryNotAssessed")}
            </span>
          </div>
          <div className="h-1.5 rounded-full bg-muted overflow-hidden">
            <div
              className={cn("h-full transition-all", MASTERY_BAR_COLORS[masteryLevel])}
              style={{ width: `${mastery?.masteryLevel ?? 0}%` }}
            />
          </div>
        </div>
      )}

      {kp.chapterTitle && (
        <div className="mt-1 text-[10px] text-muted-foreground truncate">
          {kp.chapterTitle}
        </div>
      )}

      <Handle type="source" position={Position.Bottom} className="opacity-0" />
    </div>
  )
}

export const GraphKpNode = memo(GraphKpNodeComponent)
