/**
 * CustomFieldRenderer tests — renders custom fields based on field_type.
 */

import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { CustomFieldRenderer } from '@/components/contacts/CustomFieldRenderer';
import type { CustomFieldDefinition } from '@/api/customFields';

// Mock i18n
vi.mock('react-i18next', () => ({
  useTranslation: () => ({ t: (key: string) => key }),
}));

// Mock UI components
vi.mock('@/components/ui/Input', () => ({
  Input: ({ value, onChange, type, id, ...props }: any) => (
    <input
      data-testid={props['data-testid'] || `input-${id}`}
      type={type || 'text'}
      value={value || ''}
      onChange={onChange}
    />
  ),
}));

vi.mock('@/components/ui/Select', () => ({
  Select: ({ value, onChange, id, options, children, ...props }: any) => (
    <select
      data-testid={props['data-testid'] || `select-${id}`}
      value={value || ''}
      onChange={onChange}
    >
      {options ? options.map((o: any) => <option key={o.value} value={o.value}>{o.label}</option>) : children}
    </select>
  ),
}));

const mockFields: CustomFieldDefinition[] = [
  {
    name: 'lead_source',
    label: 'Lead Source',
    label_key: 'custom.leadSource',
    field_type: 'select',
    options: ['website', 'referral', 'cold_call'],
    default_value: null,
    required: false,
    entity: 'contact',
    plugin: 'test_plugin',
    value: 'website',
  },
  {
    name: 'score',
    label: 'Score',
    label_key: 'custom.score',
    field_type: 'number',
    options: [],
    default_value: 0,
    required: false,
    entity: 'contact',
    plugin: 'test_plugin',
    value: 42,
  },
  {
    name: 'active',
    label: 'Active',
    label_key: 'custom.active',
    field_type: 'boolean',
    options: [],
    default_value: false,
    required: false,
    entity: 'contact',
    plugin: 'test_plugin',
    value: true,
  },
];

describe('CustomFieldRenderer', () => {
  it('renders read mode with field values', () => {
    render(<CustomFieldRenderer fields={mockFields} mode="read" />);
    expect(screen.getByTestId('custom-fields-read')).toBeInTheDocument();
    expect(screen.getByText('website')).toBeInTheDocument();
    expect(screen.getByText('42')).toBeInTheDocument();
    expect(screen.getByText('✓')).toBeInTheDocument();
  });

  it('renders edit mode with form controls', () => {
    render(
      <CustomFieldRenderer
        fields={mockFields}
        mode="edit"
        values={{ lead_source: 'website', score: 42, active: true }}
        onChange={vi.fn()}
      />
    );
    expect(screen.getByTestId('custom-fields-edit')).toBeInTheDocument();
    expect(screen.getByTestId('select-cf-lead_source')).toBeInTheDocument();
    expect(screen.getByTestId('input-cf-score')).toBeInTheDocument();
    expect(document.getElementById('cf-active')).toBeInTheDocument();
  });

  it('calls onChange when select value changes', () => {
    const onChange = vi.fn();
    render(
      <CustomFieldRenderer
        fields={[mockFields[0]]}
        mode="edit"
        values={{ lead_source: 'website' }}
        onChange={onChange}
      />
    );
    const select = screen.getByTestId('select-cf-lead_source');
    fireEvent.change(select, { target: { value: 'referral' } });
    expect(onChange).toHaveBeenCalledWith('lead_source', 'referral');
  });

  it('renders nothing when fields array is empty', () => {
    const { container } = render(<CustomFieldRenderer fields={[]} mode="read" />);
    expect(container.firstChild).toBeNull();
  });

  it('renders multiselect field with checkboxes', () => {
    const multiField: CustomFieldDefinition = {
      name: 'tags',
      label: 'Tags',
      label_key: 'custom.tags',
      field_type: 'multiselect',
      options: ['vip', 'customer', 'lead'],
      default_value: [],
      required: false,
      entity: 'contact',
      plugin: 'test_plugin',
      value: ['vip'],
    };
    render(
      <CustomFieldRenderer
        fields={[multiField]}
        mode="edit"
        values={{ tags: ['vip'] }}
        onChange={vi.fn()}
      />
    );
    const checkboxes = screen.getAllByRole('checkbox');
    expect(checkboxes).toHaveLength(3);
    expect(checkboxes[0]).toBeChecked();
  });
});
