'use client';

/**
 * FieldRenderer - 필드 타입별 렌더링 컴포넌트
 */

import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Checkbox } from '@/components/ui/checkbox';
import { PhoneInput } from '@/components/ui/phone-input';
import { BusinessNumberInput } from '@/components/ui/business-number-input';
import { PersonalNumberInput } from '@/components/ui/personal-number-input';
import { CurrencyInput } from '@/components/ui/currency-input';
import { QuantityInput } from '@/components/ui/quantity-input';
import { DatePicker } from '@/components/ui/date-picker';
import { cn } from '@/lib/utils';
import { formatPhoneNumber, formatBusinessNumber, formatNumber } from '@/lib/formatters';
import type { FieldDefinition, DetailMode, FieldOption } from './types';
import type { ReactNode } from 'react';

interface FieldRendererProps {
  field: FieldDefinition;
  value: unknown;
  onChange: (value: unknown) => void;
  mode: DetailMode;
  error?: string;
  dynamicOptions?: FieldOption[];
}

export function FieldRenderer({
  field,
  value,
  onChange,
  mode,
  error,
  dynamicOptions,
}: FieldRendererProps) {
  const isViewMode = mode === 'view';
  const isDisabled =
    field.readonly ||
    (typeof field.disabled === 'function'
      ? field.disabled(mode)
      : field.disabled) || false;

  // 옵션 (동적 로드된 옵션 우선)
  const options = dynamicOptions || field.options || [];

  // View 모드: 값만 표시
  if (isViewMode) {
    return (
      <div className="space-y-1">
        <Label className="text-sm font-medium text-muted-foreground">
          {field.label}
        </Label>
        <div className="text-sm mt-1">
          {renderViewValue(field, value, options)}
        </div>
      </div>
    );
  }

  // Form 모드: 입력 필드
  return (
    <div className="space-y-2">
      <Label
        htmlFor={field.key}
        className={cn(field.required && "after:content-['*'] after:ml-0.5 after:text-red-500")}
      >
        {field.label}
      </Label>
      {renderFormField(field, value, onChange, isDisabled, options, error)}
      {field.helpText && (
        <p className="text-xs text-muted-foreground">{field.helpText}</p>
      )}
      {error && <p className="text-xs text-red-500">{error}</p>}
    </div>
  );
}

// View 모드 값 렌더링
function renderViewValue(
  field: FieldDefinition,
  value: unknown,
  options: FieldOption[]
): ReactNode {
  // custom 타입이면서 renderField가 있으면 view 모드로 렌더링
  if (field.type === 'custom' && field.renderField) {
    return field.renderField({
      value,
      onChange: () => {}, // view 모드에서는 사용 안됨
      mode: 'view',
      disabled: true,
    });
  }

  // 커스텀 포맷터가 있으면 사용
  if (field.formatValue) {
    return field.formatValue(value);
  }

  // 값이 없으면 '-' 표시
  if (value === null || value === undefined || value === '') {
    return '-';
  }

  switch (field.type) {
    case 'password':
      return '****';

    case 'select':
    case 'radio': {
      const option = options.find((opt) => opt.value === value);
      return option?.label || String(value);
    }

    case 'checkbox':
      return value ? '예' : '아니오';

    case 'date':
      if (typeof value === 'string') {
        try {
          return new Date(value).toLocaleDateString('ko-KR');
        } catch {
          return value;
        }
      }
      return String(value);

    case 'textarea':
      return (
        <div className="whitespace-pre-wrap">{String(value)}</div>
      );

    case 'phone':
      return formatPhoneNumber(String(value));

    case 'businessNumber':
      return formatBusinessNumber(String(value));

    case 'personalNumber': {
      const pn = String(value).replace(/\D/g, '');
      if (pn.length === 13) {
        return `${pn.slice(0, 6)}-${pn.slice(6, 7)}******`;
      }
      return pn;
    }

    case 'currency':
      return `₩ ${formatNumber(Number(value) || 0, { useComma: true })}`;

    case 'quantity':
      return formatNumber(Number(value) || 0, { useComma: true });

    default:
      return String(value);
  }
}

// Form 모드 필드 렌더링
function renderFormField(
  field: FieldDefinition,
  value: unknown,
  onChange: (value: unknown) => void,
  disabled: boolean,
  options: FieldOption[],
  error?: string
): ReactNode {
  const stringValue = value !== null && value !== undefined ? String(value) : '';

  switch (field.type) {
    case 'text':
    case 'email':
    case 'tel':
      return (
        <Input
          id={field.key}
          type={field.type}
          value={stringValue}
          onChange={(e) => onChange(e.target.value)}
          placeholder={field.placeholder}
          disabled={disabled}
          className={cn(error && 'border-red-500')}
        />
      );

    case 'number':
      return (
        <Input
          id={field.key}
          type="number"
          value={stringValue}
          onChange={(e) => onChange(e.target.value ? Number(e.target.value) : '')}
          placeholder={field.placeholder}
          disabled={disabled}
          className={cn(error && 'border-red-500')}
        />
      );

    case 'password':
      return (
        <Input
          id={field.key}
          type="password"
          value={stringValue}
          onChange={(e) => onChange(e.target.value)}
          placeholder={field.placeholder || '****'}
          disabled={disabled}
          className={cn(error && 'border-red-500')}
        />
      );

    case 'textarea':
      return (
        <Textarea
          id={field.key}
          value={stringValue}
          onChange={(e) => onChange(e.target.value)}
          placeholder={field.placeholder}
          disabled={disabled}
          className={cn(error && 'border-red-500')}
          rows={4}
        />
      );

    case 'select':
      return (
        <Select
          key={`${field.key}-${stringValue}`}
          value={stringValue}
          onValueChange={onChange}
          disabled={disabled}
        >
          <SelectTrigger className={cn(error && 'border-red-500')}>
            <SelectValue placeholder={field.placeholder || '선택하세요'} />
          </SelectTrigger>
          <SelectContent>
            {options.map((option) => (
              <SelectItem
                key={option.value}
                value={option.value}
                disabled={option.disabled}
              >
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      );

    case 'radio':
      return (
        <RadioGroup
          value={stringValue}
          onValueChange={onChange}
          disabled={disabled}
          className="flex flex-wrap gap-4"
        >
          {options.map((option) => (
            <div key={option.value} className="flex items-center space-x-2">
              <RadioGroupItem value={option.value} id={`${field.key}-${option.value}`} />
              <Label
                htmlFor={`${field.key}-${option.value}`}
                className="font-normal cursor-pointer"
              >
                {option.label}
              </Label>
            </div>
          ))}
        </RadioGroup>
      );

    case 'checkbox':
      return (
        <div className="flex items-center space-x-2">
          <Checkbox
            id={field.key}
            checked={!!value}
            onCheckedChange={onChange}
            disabled={disabled}
          />
          <Label
            htmlFor={field.key}
            className="font-normal cursor-pointer"
          >
            {field.placeholder || '동의'}
          </Label>
        </div>
      );

    case 'date':
      return (
        <DatePicker
          value={stringValue}
          onChange={(date) => onChange(date)}
          disabled={disabled}
          className={cn(error && 'border-red-500')}
        />
      );

    case 'phone':
      return (
        <PhoneInput
          value={stringValue}
          onChange={(v) => onChange(v)}
          placeholder={field.placeholder}
          disabled={disabled}
          error={!!error}
        />
      );

    case 'businessNumber':
      return (
        <BusinessNumberInput
          value={stringValue}
          onChange={(v) => onChange(v)}
          placeholder={field.placeholder}
          disabled={disabled}
          error={!!error}
          showValidation
        />
      );

    case 'personalNumber':
      return (
        <PersonalNumberInput
          value={stringValue}
          onChange={(v) => onChange(v)}
          placeholder={field.placeholder}
          disabled={disabled}
          error={!!error}
          maskBack
        />
      );

    case 'currency':
      return (
        <CurrencyInput
          value={value as number | undefined}
          onChange={(v) => onChange(v)}
          placeholder={field.placeholder}
          disabled={disabled}
          error={!!error}
        />
      );

    case 'quantity':
      return (
        <QuantityInput
          value={value as number | undefined}
          onChange={(v) => onChange(v)}
          placeholder={field.placeholder}
          disabled={disabled}
          error={!!error}
          min={0}
        />
      );

    case 'custom':
      if (field.renderField) {
        return field.renderField({
          value,
          onChange,
          mode: 'edit',
          disabled,
        });
      }
      return <div className="text-muted-foreground">커스텀 렌더러가 필요합니다</div>;

    default:
      return (
        <Input
          id={field.key}
          value={stringValue}
          onChange={(e) => onChange(e.target.value)}
          placeholder={field.placeholder}
          disabled={disabled}
        />
      );
  }
}
