'use client';

import { Check, X, FileText } from 'lucide-react';
import type { FieldConfig, FieldOption } from '@/types/invyone-component';

interface CellRendererProps {
  field: FieldConfig;
  value: any;
}

/**
 * FieldType에 따라 셀 내용을 포맷팅한다.
 * 렌더링 계약(spec Section 2.2) 테이블 렌더 컬럼 기준.
 */
export function CellRenderer({ field, value }: CellRendererProps) {
  if (value === null || value === undefined) {
    return <span className="text-[var(--v5-text-muted)]">-</span>;
  }

  switch (field.type) {
    case 'number':
      return <span>{formatNumber(value, field.format)}</span>;

    case 'date':
      return <span>{formatDate(value)}</span>;

    case 'datetime':
      return <span>{formatDateTime(value)}</span>;

    case 'time':
      return <span>{formatTime(value)}</span>;

    case 'daterange':
      return <span>{formatDateRange(value)}</span>;

    case 'checkbox':
      return value === true || value === 'true' || value === 't'
        ? <Check className="h-3.5 w-3.5 text-[var(--v5-green)]" />
        : <X className="h-3.5 w-3.5 text-[var(--v5-text-muted)]" />;

    case 'textarea':
      // 40자 말줄임
      return <span title={String(value)}>
        {String(value).length > 40 ? String(value).slice(0, 40) + '...' : String(value)}
      </span>;

    case 'file':
      return (
        <span className="inline-flex items-center gap-1 text-[var(--v5-primary)] cursor-pointer">
          <FileText className="h-3 w-3" />
          <span className="truncate max-w-[120px]">{String(value)}</span>
        </span>
      );

    case 'entity':
      // ref.displayColumn 값은 조인된 데이터에서 오므로 그대로 표시
      return <span>{String(value)}</span>;

    case 'select':
      // ★ select: value→label 변환하여 표시
      return <span>{resolveOptionLabel(field.options, value)}</span>;

    default:
      // text, code: 텍스트 그대로
      return <span>{String(value)}</span>;
  }
}

/** select value → label 변환. 못 찾으면 value 그대로 표시 */
function resolveOptionLabel(options: FieldOption[] | undefined, value: any): string {
  if (!options || !value) return String(value ?? '');
  const strVal = String(value);
  for (const opt of options) {
    if (typeof opt === 'string') {
      if (opt === strVal) return opt;
    } else {
      if (opt.value === strVal) return opt.label;
    }
  }
  return strVal;
}

function formatNumber(value: any, format?: string): string {
  const num = Number(value);
  if (isNaN(num)) return String(value);
  // #,##0 포맷 — 천 단위 콤마
  if (format === '#,##0' || !format) {
    return num.toLocaleString('ko-KR', { maximumFractionDigits: 0 });
  }
  // #,##0.00 등 소수점
  const match = format.match(/\.(\d+)/);
  if (match) {
    const decimals = match[1].length;
    return num.toLocaleString('ko-KR', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
  }
  return num.toLocaleString('ko-KR');
}

function formatDate(value: any): string {
  if (!value) return '';
  try {
    const d = new Date(value);
    if (isNaN(d.getTime())) return String(value);
    const y = d.getFullYear();
    const m = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    return `${y}-${m}-${day}`;
  } catch {
    return String(value);
  }
}

function formatDateTime(value: any): string {
  if (!value) return '';
  try {
    const d = new Date(value);
    if (isNaN(d.getTime())) return String(value);
    const date = formatDate(value);
    const h = String(d.getHours()).padStart(2, '0');
    const min = String(d.getMinutes()).padStart(2, '0');
    return `${date} ${h}:${min}`;
  } catch {
    return String(value);
  }
}

function formatTime(value: any): string {
  if (!value) return '';
  // value 가 "HH:mm" 또는 "HH:mm:ss" 또는 ISO datetime 일 수 있음
  const s = String(value);
  if (/^\d{2}:\d{2}(:\d{2})?$/.test(s)) return s;
  try {
    const d = new Date(value);
    if (isNaN(d.getTime())) return s;
    const h = String(d.getHours()).padStart(2, '0');
    const min = String(d.getMinutes()).padStart(2, '0');
    return `${h}:${min}`;
  } catch {
    return s;
  }
}

function formatDateRange(value: any): string {
  if (!value || typeof value !== 'object') return '';
  const from = value.from ? formatDate(value.from) : '';
  const to = value.to ? formatDate(value.to) : '';
  if (!from && !to) return '';
  return `${from} ~ ${to}`;
}
