'use client';

/**
 * 템플릿 카드용 작은 wireframe 썸네일.
 *
 * 실제 DB 의 views 포맷(스튜디오 어댑터, templateAdapter.saveTemplate):
 *   {
 *     list:  [ { id, url, position:{x,y}, size:{width,height}, ... }, ... ]
 *     create:[...], edit:[...],
 *     screenResolution: { width, height },   // 절대 px 정규화 기준
 *     ...
 *   }
 *
 * v2.1 레이어 구조면 list.layers[].components, 옛 v1 모델이면
 * list.components(order/row), 또 다른 v2 변형이면 list.blocks(xPct).
 * 어떤 모양이든 비어있으면 placeholder 만 보여준다.
 *
 * 컴포넌트 종류는 url/id substring 매칭으로 분류해 색상만 다르게 줌.
 */

interface TemplateThumbnailProps {
  views?: any;
}

interface MiniBlock {
  x: number;
  y: number;
  w: number;
  h: number;
  kind: string;
}

/** 종류별 RGB 트리플 — 테두리/배경 알파를 다르게 적용하기 위해 raw 값을 보관. */
const KIND_RGB: Record<string, string> = {
  table: 'var(--v5-primary-rgb)',
  form: 'var(--v5-cyan-rgb)',
  search: 'var(--v5-cyan-rgb)',
  button: '253, 121, 168',
  'button-bar': '253, 121, 168',
  stats: 'var(--v5-primary-rgb)',
  tabs: 'var(--v5-primary-rgb)',
  title: '140, 140, 160',
  divider: '140, 140, 160',
  pagination: '140, 140, 160',
};

function kindRgb(kind: string): string {
  const lower = (kind || '').toLowerCase();
  for (const key of Object.keys(KIND_RGB)) {
    if (lower.includes(key)) return KIND_RGB[key];
  }
  return 'var(--v5-primary-rgb)';
}

function inferKind(componentId: string): string {
  const id = (componentId || '').toLowerCase();
  if (id.includes('table') || id.includes('grid') || id.includes('list')) return 'table';
  if (id.includes('form') || id.includes('input')) return 'form';
  if (id.includes('search') || id.includes('filter')) return 'search';
  if (id.includes('button')) return 'button';
  if (id.includes('stat') || id.includes('kpi') || id.includes('chart')) return 'stats';
  if (id.includes('tab')) return 'tabs';
  if (id.includes('title') || id.includes('label') || id.includes('text')) return 'title';
  if (id.includes('divider')) return 'divider';
  if (id.includes('pag')) return 'pagination';
  return id || 'unknown';
}

function collectStudioComponents(viewNode: any): any[] {
  if (!viewNode) return [];
  if (Array.isArray(viewNode)) return viewNode;
  if (Array.isArray(viewNode.layers)) {
    return viewNode.layers.flatMap((l: any) => Array.isArray(l.components) ? l.components : []);
  }
  if (Array.isArray(viewNode.components)) return viewNode.components;
  return [];
}

/** 스튜디오 어댑터가 저장한 실제 포맷: list 가 컴포넌트 배열, screenResolution 으로 정규화. */
function fromStudio(views: any): MiniBlock[] | null {
  const comps = collectStudioComponents(views?.list);
  if (comps.length === 0) return null;

  // 좌표/사이즈가 하나라도 있어야 의미 있음 (없으면 다른 변환기에 양보)
  const hasGeom = comps.some(
    (c: any) => c?.position || c?.size,
  );
  if (!hasGeom) return null;

  const sr = views?.screenResolution;
  let canvasW = sr?.width ?? 0;
  let canvasH = sr?.height ?? 0;

  if (!canvasW || !canvasH) {
    let maxX = 0;
    let maxY = 0;
    for (const c of comps) {
      const x = c?.position?.x ?? 0;
      const y = c?.position?.y ?? 0;
      const w = c?.size?.width ?? 100;
      const h = c?.size?.height ?? 100;
      if (x + w > maxX) maxX = x + w;
      if (y + h > maxY) maxY = y + h;
    }
    canvasW = maxX || 1920;
    canvasH = maxY || 1080;
  }

  return comps.map((c: any) => {
    const x = c?.position?.x ?? 0;
    const y = c?.position?.y ?? 0;
    const w = c?.size?.width ?? 100;
    const h = c?.size?.height ?? 100;
    const kindKey =
      c?.url ?? c?.componentType ?? c?.widgetType ?? c?.componentId ?? '';
    return {
      x: clamp01(x / canvasW),
      y: clamp01(y / canvasH),
      w: clamp01(w / canvasW),
      h: clamp01(h / canvasH),
      kind: inferKind(kindKey),
    };
  });
}

function fromV2(views: any): MiniBlock[] | null {
  const blocks = views?.list?.blocks;
  if (!Array.isArray(blocks) || blocks.length === 0) return null;
  return blocks.map((b: any) => ({
    x: clamp01(b.xPct ?? 0),
    y: clamp01(b.yPct ?? 0),
    w: clamp01(b.wPct ?? 0.2),
    h: clamp01(b.hPct ?? 0.1),
    kind: inferKind(b.componentId),
  }));
}

function fromV1(views: any): MiniBlock[] | null {
  const components = views?.list?.components;
  if (!Array.isArray(components) || components.length === 0) return null;

  const sorted = [...components].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
  const rowsMap = new Map<string, any[]>();
  let nextRowId = 0;
  for (const c of sorted) {
    const key = c.row != null ? `r${c.row}` : `s${nextRowId++}`;
    if (!rowsMap.has(key)) rowsMap.set(key, []);
    rowsMap.get(key)!.push(c);
  }

  const rows = Array.from(rowsMap.values());
  const totalRows = rows.length;
  const blocks: MiniBlock[] = [];
  rows.forEach((rowComps, rowIdx) => {
    const cols = rowComps.length;
    rowComps.forEach((c, colIdx) => {
      blocks.push({
        x: colIdx / cols,
        y: rowIdx / totalRows,
        w: 1 / cols,
        h: 1 / totalRows,
        kind: inferKind(c.componentId),
      });
    });
  });
  return blocks;
}

function clamp01(v: number): number {
  if (typeof v !== 'number' || isNaN(v)) return 0;
  if (v < 0) return 0;
  if (v > 1) return 1;
  return v;
}

export function TemplateThumbnail({ views }: TemplateThumbnailProps) {
  const blocks = fromStudio(views) ?? fromV2(views) ?? fromV1(views);

  if (!blocks || blocks.length === 0) {
    return (
      <div className="dash-lib-card-thumb dash-lib-card-thumb--empty" aria-hidden="true">
        <span style={{ fontSize: '.95rem', opacity: .6 }}>📋</span>
      </div>
    );
  }

  return (
    <div className="dash-lib-card-thumb" aria-hidden="true">
      <div className="dash-lib-card-thumb-canvas">
        {blocks.map((b, i) => {
          const rgb = kindRgb(b.kind);
          return (
            <span
              key={i}
              className="dash-lib-card-thumb-block"
              style={{
                left: `${b.x * 100}%`,
                top: `${b.y * 100}%`,
                width: `${Math.max(b.w * 100, 3)}%`,
                height: `${Math.max(b.h * 100, 6)}%`,
                background: `rgba(${rgb}, .14)`,
                borderColor: `rgba(${rgb}, .55)`,
              }}
            />
          );
        })}
      </div>
    </div>
  );
}
