"use client";

/**
 * 그리드 표시 모드
 *
 * CSS Grid로 셀 배치 (엑셀형 분할/병합 결과 반영)
 * 각 셀에 @container 적용하여 내부 아이템 반응형
 *
 * 반응형 자동 조정:
 * - containerWidth에 따라 열 수를 자동 축소
 * - 설정된 열 수가 최대값이고, 공간이 부족하면 줄어듦
 * - 셀당 최소 너비(MIN_CELL_WIDTH) 기준으로 판단
 */

import React, { useMemo } from "react";
import type { DashboardCell } from "../../types";

// ===== 상수 =====

/** 셀 하나의 최소 너비 (px). 이보다 좁아지면 열 수 축소 */
const MIN_CELL_WIDTH = 80;

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

export interface GridModeProps {
  /** 셀 배치 정보 */
  cells: DashboardCell[];
  /** 설정된 열 수 (최대값) */
  columns: number;
  /** 설정된 행 수 */
  rows: number;
  /** 아이템 간 간격 (px) */
  gap?: number;
  /** 컨테이너 너비 (px, 반응형 자동 조정용) */
  containerWidth?: number;
  /** 셀의 아이템 렌더링. itemId가 null이면 빈 셀 */
  renderItem: (itemId: string) => React.ReactNode;
}

// ===== 반응형 열 수 계산 =====

/**
 * 컨테이너 너비에 맞는 실제 열 수를 계산
 *
 * 설정된 columns가 최대값이고, 공간이 부족하면 축소.
 * gap도 고려하여 계산.
 *
 * 예: columns=3, containerWidth=400, gap=8, MIN_CELL_WIDTH=160
 *     사용 가능 너비 = 400 - (3-1)*8 = 384
 *     셀당 너비 = 384/3 = 128 < 160  -> 열 축소
 *     columns=2: 사용 가능 = 400 - (2-1)*8 = 392, 셀당 = 196 >= 160 -> OK
 */
function computeResponsiveColumns(
  configColumns: number,
  containerWidth: number,
  gap: number
): number {
  if (containerWidth <= 0) return configColumns;

  for (let cols = configColumns; cols >= 1; cols--) {
    const totalGap = (cols - 1) * gap;
    const cellWidth = (containerWidth - totalGap) / cols;
    if (cellWidth >= MIN_CELL_WIDTH) return cols;
  }

  return 1;
}

/**
 * 열 수가 줄어들 때 셀 배치를 자동 재배열
 *
 * 원본 gridColumn/gridRow를 actualColumns에 맞게 재매핑
 * 셀이 원래 위치를 유지하려고 시도하되, 넘치면 아래로 이동
 */
function remapCells(
  cells: DashboardCell[],
  configColumns: number,
  actualColumns: number,
  configRows: number
): { remappedCells: DashboardCell[]; actualRows: number } {
  // 열 수가 같으면 원본 그대로
  if (actualColumns >= configColumns) {
    return { remappedCells: cells, actualRows: configRows };
  }

  // 셀을 원래 위치 순서대로 정렬 (행 우선)
  const sorted = [...cells].sort((a, b) => {
    const aRow = parseInt(a.gridRow.split(" / ")[0]) || 0;
    const bRow = parseInt(b.gridRow.split(" / ")[0]) || 0;
    if (aRow !== bRow) return aRow - bRow;
    const aCol = parseInt(a.gridColumn.split(" / ")[0]) || 0;
    const bCol = parseInt(b.gridColumn.split(" / ")[0]) || 0;
    return aCol - bCol;
  });

  // 순서대로 새 위치에 배치
  let maxRow = 0;
  const remapped = sorted.map((cell, index) => {
    const newCol = (index % actualColumns) + 1;
    const newRow = Math.floor(index / actualColumns) + 1;
    maxRow = Math.max(maxRow, newRow);
    return {
      ...cell,
      gridColumn: `${newCol} / ${newCol + 1}`,
      gridRow: `${newRow} / ${newRow + 1}`,
    };
  });

  return { remappedCells: remapped, actualRows: maxRow };
}

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

export function GridModeComponent({
  cells,
  columns,
  rows,
  gap = 8,
  containerWidth,
  renderItem,
}: GridModeProps) {
  // 반응형 열 수 계산
  const actualColumns = useMemo(
    () =>
      containerWidth
        ? computeResponsiveColumns(columns, containerWidth, gap)
        : columns,
    [columns, containerWidth, gap]
  );

  // 열 수가 줄었으면 셀 재배열
  const { remappedCells, actualRows } = useMemo(
    () => remapCells(cells, columns, actualColumns, rows),
    [cells, columns, actualColumns, rows]
  );

  if (!remappedCells.length) {
    return (
      <div className="flex h-full w-full items-center justify-center">
        <span className="text-xs text-muted-foreground">셀 없음</span>
      </div>
    );
  }

  return (
    <div
      className="h-full w-full"
      style={{
        display: "grid",
        gridTemplateColumns: `repeat(${actualColumns}, 1fr)`,
        gridTemplateRows: `repeat(${actualRows}, 1fr)`,
        gap: `${gap}px`,
      }}
    >
      {remappedCells.map((cell) => (
        <div
          key={cell.id}
          className="@container min-h-0 min-w-0 overflow-hidden rounded-md border border-border/50 bg-card"
          style={{
            gridColumn: cell.gridColumn,
            gridRow: cell.gridRow,
          }}
        >
          {cell.itemId ? (
            renderItem(cell.itemId)
          ) : (
            <div className="flex h-full w-full items-center justify-center">
              <span className="text-[10px] text-muted-foreground/50">
                빈 셀
              </span>
            </div>
          )}
        </div>
      ))}
    </div>
  );
}
