/**
 * 계산 필드 (읽기전용)
 * 다른 필드 값 기반 자동 계산, formula 평가
 *
 * properties: { formula, dependsOn, format, precision }
 * 저장값: 계산 결과 number (자동 업데이트)
 */

'use client';

import { useEffect, useRef } from 'react';
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import type { DynamicFieldRendererProps, ComputedConfig } from '../types';

/**
 * 안전한 수식 평가기
 * 지원 연산: +, -, *, /, (, )
 * 변수: field_key 이름으로 참조
 */
function evaluateFormula(
  formula: string,
  variables: Record<string, number>
): number | null {
  try {
    // 변수를 숫자로 치환 (긴 키부터 치환하여 부분 매칭 방지)
    let expression = formula;
    const sortedKeys = Object.keys(variables).sort((a, b) => b.length - a.length);
    for (const key of sortedKeys) {
      expression = expression.replace(
        new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
        String(variables[key])
      );
    }

    // 숫자, 연산자, 괄호, 공백만 허용 (안전성 검사)
    if (!/^[\d\s+\-*/().]+$/.test(expression)) {
      return null;
    }

    // Function 생성자로 안전하게 평가
    const result = new Function(`"use strict"; return (${expression})`)();
    if (typeof result !== 'number' || !isFinite(result)) {
      return null;
    }
    return result;
  } catch {
    return null;
  }
}

function formatResult(
  value: number,
  format?: string,
  precision?: number
): string {
  const p = precision ?? 2;

  switch (format) {
    case 'currency': {
      const formatted = value.toFixed(p);
      const [intPart, decPart] = formatted.split('.');
      const withCommas = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
      return decPart ? `\u20A9${withCommas}.${decPart}` : `\u20A9${withCommas}`;
    }
    case 'percent':
      return `${value.toFixed(p)}%`;
    case 'number':
    default:
      return value.toFixed(p);
  }
}

export function ComputedField({
  field,
  value,
  onChange,
  error,
  disabled: _disabled,
  formData,
}: DynamicFieldRendererProps) {
  const fieldKey = field.field_key || `field_${field.id}`;
  const config = (field.properties || {}) as ComputedConfig;
  const { formula, dependsOn, format, precision } = config;

  const prevResultRef = useRef<number | null>(null);

  // dependsOn 필드 값이 변경될 때마다 재계산
  useEffect(() => {
    if (!formula || !dependsOn || !formData) return;

    // 의존 필드 값 수집
    const variables: Record<string, number> = {};
    for (const dep of dependsOn) {
      const depValue = formData[dep];
      variables[dep] = depValue !== null && depValue !== undefined ? Number(depValue) || 0 : 0;
    }

    const result = evaluateFormula(formula, variables);

    // 이전 결과와 다를 때만 업데이트 (무한 루프 방지)
    if (result !== null && result !== prevResultRef.current) {
      prevResultRef.current = result;
      onChange(result);
    }
  }, [formula, dependsOn, formData, onChange]);

  const displayValue = value !== null && value !== undefined
    ? formatResult(Number(value), format, precision)
    : '-';

  return (
    <div>
      <Label htmlFor={fieldKey}>
        {field.field_name}
        {field.is_required && <span className="text-red-500"> *</span>}
      </Label>
      <Input
        id={fieldKey}
        value={displayValue}
        readOnly
        disabled
        className="bg-muted text-muted-foreground cursor-default"
      />
      {error && (
        <p className="text-xs text-red-500 mt-1">{error}</p>
      )}
      {!error && field.description && (
        <p className="text-xs text-muted-foreground mt-1">
          * {field.description}
        </p>
      )}
    </div>
  );
}
