"use client";

/**
 * KPI 카드 서브타입 컴포넌트
 *
 * 큰 숫자 + 단위 + 증감 표시
 * ResizeObserver로 컨테이너 크기를 감지하여 글자 크기를 비례적으로 조절
 * itemStyle.valueFontSize 로 배율 조절 가능
 */

import React, { useRef, useEffect, useState } from "react";
import type { DashboardItem, FontSize } from "../../types";
import { TEXT_ALIGN_CLASSES } from "../../types";
import { abbreviateNumber } from "../utils/formula";

// ===== Props =====

export interface KpiCardProps {
  item: DashboardItem;
  data: number | null;
  /** 이전 기간 대비 증감 퍼센트 (선택) */
  trendValue?: number | null;
  /** 수식 결과 표시 문자열 (formula가 있을 때) */
  formulaDisplay?: string | null;
}

// ===== valueFontSize → 크기 배율 =====

const FONT_SIZE_SCALE: Record<FontSize, number> = {
  xs: 0.65,
  sm: 0.80,
  base: 1.0,
  lg: 1.25,
  xl: 1.55,
};

// ===== 색상 구간 판정 =====

function getColorForValue(
  value: number,
  ranges?: { min: number; max: number; color: string }[]
): string | undefined {
  if (!ranges?.length) return undefined;
  const match = ranges.find((r) => value >= r.min && value <= r.max);
  return match?.color;
}

// ===== 메인 컴포넌트 =====

export function KpiCardComponent({
  item,
  data,
  trendValue,
  formulaDisplay,
}: KpiCardProps) {
  const { visibility, kpiConfig, itemStyle } = item;
  const displayValue = data ?? 0;
  const valueColor = getColorForValue(displayValue, kpiConfig?.colorRanges);

  // valueFontSize 배율 (기본: base = 1.0)
  const valueFontSize: FontSize = itemStyle?.valueFontSize ?? "base";
  const scale = FONT_SIZE_SCALE[valueFontSize];

  // 라벨 정렬
  const labelAlignClass = TEXT_ALIGN_CLASSES[itemStyle?.labelAlign ?? "center"];

  // 단위: kpiConfig.unit 우선, fallback으로 item.unit (레거시)
  const unit = kpiConfig?.unit ?? item.unit;

  // ===== 컨테이너 크기 감지 =====
  const containerRef = useRef<HTMLDivElement>(null);
  const [containerSize, setContainerSize] = useState({ w: 200, h: 100 });

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;

    const observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        const { width, height } = entry.contentRect;
        setContainerSize({ w: width, h: height });
      }
    });
    observer.observe(el);
    return () => observer.disconnect();
  }, []);

  // ===== 비례 폰트 크기 계산 =====
  // 숫자: 컨테이너 높이의 50% (라벨·단위가 없으면 60%)
  // 라벨: 컨테이너 높이의 13%
  // 단위: 숫자 크기의 40%
  // 추세: 고정 최소값 (너무 작으면 읽기 어려움)

  const hasLabel = visibility.showLabel && !!item.label;
  const hasTrend = visibility.showTrend && trendValue != null;
  const hasSubLabel = visibility.showSubLabel && !!formulaDisplay;

  // 수직 공간을 차지하는 요소 수에 따라 숫자 비율 조정
  const occupiedLines = (hasLabel ? 1 : 0) + (hasTrend ? 1 : 0) + (hasSubLabel ? 1 : 0);
  const valueRatio = occupiedLines === 0 ? 0.62 : occupiedLines === 1 ? 0.52 : 0.42;

  // 너비 기준으로도 제한 (너무 넓은 셀에서 지나치게 커지지 않도록)
  const baseFromHeight = containerSize.h * valueRatio;
  const baseFromWidth = containerSize.w * 0.35;
  const baseSize = Math.min(baseFromHeight, baseFromWidth);

  const valueFontPx = Math.max(16, Math.round(baseSize * scale));
  const labelFontPx = Math.max(11, Math.round(containerSize.h * 0.13 * scale));
  const unitFontPx  = Math.max(12, Math.round(valueFontPx * 0.40));
  const trendFontPx = Math.max(10, Math.round(containerSize.h * 0.09 * scale));

  return (
    <div
      ref={containerRef}
      className="pop-neu-card flex h-full w-full flex-col items-center justify-center p-4"
    >
      {/* 라벨 */}
      {hasLabel && (
        <p
          className={`kpi-dynamic-font w-full text-muted-foreground ${labelAlignClass}`}
          style={{ fontSize: `${labelFontPx}px`, lineHeight: 1.2 }}
        >
          {item.label}
        </p>
      )}

      {/* 메인 값 */}
      {visibility.showValue && (
        <div className="flex items-baseline gap-[0.15em]">
          <span
            className="kpi-dynamic-font font-bold leading-none"
            style={{
              fontSize: `${valueFontPx}px`,
              ...(valueColor ? { color: valueColor } : {}),
            }}
          >
            {formulaDisplay ?? abbreviateNumber(displayValue)}
          </span>

          {/* 단위 */}
          {visibility.showUnit && unit && (
            <span
              className="kpi-dynamic-font text-muted-foreground font-medium"
              style={{ fontSize: `${unitFontPx}px` }}
            >
              {unit}
            </span>
          )}
        </div>
      )}

      {/* 증감율 */}
      {hasTrend && trendValue != null && (
        <span
          className="inline-flex items-center gap-0.5 font-medium"
          style={{
            fontSize: `${trendFontPx}px`,
            color: trendValue > 0 ? "var(--color-emerald-600)" : trendValue === 0 ? "var(--muted-foreground)" : "var(--color-rose-600)",
          }}
        >
          <span>{trendValue > 0 ? "↑" : trendValue === 0 ? "→" : "↓"}</span>
          <span>{Math.abs(trendValue).toFixed(1)}%</span>
        </span>
      )}

      {/* 보조 라벨 (수식 표시 등) */}
      {hasSubLabel && (
        <p
          className="text-muted-foreground"
          style={{ fontSize: `${Math.max(10, Math.round(labelFontPx * 0.85))}px` }}
        >
          {item.formula?.values.map((v) => v.label).join(" / ")}
        </p>
      )}
    </div>
  );
}
