# 🎯 RemoteSelect Component - Documentação Completa

## 📖 Visão Geral

O `RemoteSelectComponent` é um componente universal de busca dinâmica que permite autocomplete e seleção de registros de qualquer domínio da aplicação PraFrota.

### ✨ Funcionalidades Principais

- 🔍 **Autocomplete inteligente** com debounce configurável
- ⌨️ **Navegação por teclado** (setas, Enter, Escape)
- 🔑 **Tecla F2** para abrir modal de seleção completa
- 📱 **Responsivo** e acessível (WCAG 2.1)
- 🔄 **Reactive Forms** - implementa `ControlValueAccessor`
- 💾 **Cache automático** de resultados
- 🎨 **Material Design** + PraFrota Design System
- ⚡ **Performance otimizada** para grandes datasets

## 🚀 Instalação e Setup

### 1. Importar o Componente

```typescript
import { RemoteSelectComponent } from './shared/components/remote-select/remote-select.component';

@Component({
  // ...
  imports: [RemoteSelectComponent]
})
```

### 2. Configuração Básica

```typescript
import { RemoteSelectConfig } from './shared/components/remote-select/interfaces/remote-select.interface';

export class YourComponent {
  driversConfig: RemoteSelectConfig = {
    service: this.driversService,
    searchField: 'name',
    displayField: 'name',
    valueField: 'id',
    modalTitle: 'Selecionar Motorista',
    placeholder: 'Digite o nome do motorista...'
  };
  
  constructor(private driversService: DriversService) {}
}
```

### 3. Uso no Template

```html
<app-remote-select
  [config]="driversConfig"
  label="Motorista"
  [required]="true"
  (selectionChange)="onDriverSelected($event)"
></app-remote-select>
```

## 🎛️ API do Componente

### Inputs

| Propriedade | Tipo | Padrão | Descrição |
|-------------|------|--------|-----------|
| `config` | `RemoteSelectConfig` | - | **Obrigatório.** Configuração do componente |
| `label` | `string` | `''` | Label exibido acima do campo |
| `disabled` | `boolean` | `false` | Desabilita o componente |
| `required` | `boolean` | `false` | Marca o campo como obrigatório |
| `hideLabel` | `boolean` | `false` | Oculta o label |

### Outputs

| Evento | Tipo | Descrição |
|--------|------|-----------|
| `selectionChange` | `RemoteSelectEvent` | Emitido quando item é selecionado/limpo |
| `searchQuery` | `string` | Emitido durante a busca (para debug) |
| `modalToggle` | `boolean` | Emitido quando modal F2 abre/fecha |

### RemoteSelectConfig

```typescript
interface RemoteSelectConfig {
  service: any;                    // Service com método getEntities()
  searchField: string;             // Campo usado na busca
  displayField: string;            // Campo mostrado na UI
  valueField: string;              // Campo do valor retornado
  modalTitle?: string;             // Título do modal F2
  placeholder?: string;            // Placeholder do input
  additionalFields?: string[];     // Campos extras para busca
  minLength?: number;              // Min. caracteres (padrão: 3)
  debounceTime?: number;           // Debounce em ms (padrão: 300)
  multiple?: boolean;              // Seleção múltipla (padrão: false)
  maxResults?: number;             // Max. resultados (padrão: 10)
}
```

### RemoteSelectEvent

```typescript
interface RemoteSelectEvent {
  value: any | any[];              // Valor(es) selecionado(s)
  item: RemoteSelectItem | RemoteSelectItem[]; // Item(s) completo(s)
  source: 'dropdown' | 'modal' | 'clear';     // Origem da seleção
}
```

## 🎯 Exemplos de Uso

### 1. Busca Simples de Motoristas

```typescript
// Component
driversConfig: RemoteSelectConfig = {
  service: this.driversService,
  searchField: 'name',
  displayField: 'name', 
  valueField: 'id',
  modalTitle: 'Selecionar Motorista'
};

onDriverSelected(event: RemoteSelectEvent) {
  console.log('Motorista:', event.item);
  console.log('ID:', event.value);
}
```

```html
<!-- Template -->
<app-remote-select
  [config]="driversConfig"
  label="Motorista Responsável"
  [required]="true"
  (selectionChange)="onDriverSelected($event)"
></app-remote-select>
```

### 2. Integração com Reactive Forms

```typescript
// Component
form = this.fb.group({
  driverId: [null, Validators.required],
  vehicleId: [null]
});

vehiclesConfig: RemoteSelectConfig = {
  service: this.vehiclesService,
  searchField: 'license_plate',
  displayField: 'license_plate',
  valueField: 'id',
  additionalFields: ['brand', 'model'], // Busca também em marca/modelo
  placeholder: 'Placa, marca ou modelo...'
};
```

```html
<!-- Template -->
<form [formGroup]="form">
  <app-remote-select
    [config]="vehiclesConfig"
    label="Veículo"
    formControlName="vehicleId"
  ></app-remote-select>
  
  <p>Veículo selecionado: {{ form.get('vehicleId')?.value }}</p>
</form>
```

### 3. Busca com Múltiplos Campos

```typescript
// Busca por nome, CPF ou email
usersConfig: RemoteSelectConfig = {
  service: this.usersService,
  searchField: 'name',
  displayField: 'name',
  valueField: 'id',
  additionalFields: ['cpf', 'email'],
  placeholder: 'Nome, CPF ou email...',
  minLength: 2
};
```

### 4. Configuração para Formulários de Domínio

```typescript
// vehicles.component.ts - Exemplo de integração
getFormConfig(): TabFormConfig {
  return {
    // ...
    fields: [
      {
        key: 'driver_id',
        label: 'Motorista Atual',
        type: 'remote-select',
        remoteConfig: {
          service: this.driversService,
          searchField: 'name',
          displayField: 'name',
          valueField: 'id',
          modalTitle: 'Selecionar Motorista',
          placeholder: 'Digite o nome...'
        }
      }
    ]
  };
}
```

## ⌨️ Navegação por Teclado

| Tecla | Ação |
|-------|------|
| `↓` | Navegar para próximo item |
| `↑` | Navegar para item anterior |
| `Enter` | Selecionar item destacado |
| `Escape` | Fechar dropdown |
| `F2` | Abrir modal de seleção completa |

## 🎨 Customização Visual

### Variáveis CSS Disponíveis

```scss
:root {
  --primary-color: #ffc82e;
  --text-primary: #333;
  --text-secondary: #666;
  --surface-hover: #f5f5f5;
  --divider: #e0e0e0;
  --error-color: #f44336;
  --success-color: #4caf50;
}
```

### Classes CSS Personalizáveis

```scss
.remote-select-container {
  // Container principal
  
  .remote-select-dropdown {
    // Dropdown de resultados
    
    .dropdown-item {
      // Itens individuais
      
      &.selected {
        // Item selecionado via teclado
      }
      
      &.highlighted {
        // Item já selecionado
      }
    }
  }
}
```

## 🔧 Requisitos do Service

O service configurado deve implementar o método `getEntities()`:

```typescript
interface DomainService<T> {
  getEntities(
    page: number,
    pageSize: number,
    filters?: any
  ): Observable<{
    data: T[];
    total: number;
    page: number;
    pageSize: number;
  }>;
}
```

### Exemplo de Service Compatível

```typescript
@Injectable({
  providedIn: 'root'
})
export class DriversService {
  
  getEntities(page: number, pageSize: number, filters?: any): Observable<any> {
    let params = new HttpParams()
      .set('page', page.toString())
      .set('pageSize', pageSize.toString());
    
    // Aplicar filtros de busca
    if (filters) {
      Object.keys(filters).forEach(key => {
        if (filters[key]) {
          params = params.set(key, filters[key]);
        }
      });
    }
    
    return this.http.get<any>(`${this.apiUrl}/drivers`, { params });
  }
}
```

## 📱 Responsividade

### Desktop (≥768px)
- Botão F2 visível
- Dropdown completo
- Tooltips habilitados

### Mobile (<768px)
- Botão F2 oculto
- Dropdown otimizado
- Touch-friendly

## 🎯 Integração com GenericTabFormComponent

Para usar em formulários de domínio, adicione o tipo `remote-select`:

```typescript
// generic-tab-form.component.html
<div *ngIf="field.type === 'remote-select'" class="form-field">
  <app-remote-select
    [config]="field.remoteConfig"
    [label]="field.label"
    [required]="field.required"
    [disabled]="isFieldDisabled(field)"
    [formControlName]="field.key"
  ></app-remote-select>
</div>
```

## 🔮 Funcionalidades Futuras

### 🚧 Em Desenvolvimento

1. **Modal F2 Completo**
   - Integração com DataTableComponent
   - Seleção múltipla com checkboxes
   - Filtros avançados

2. **Cache Inteligente**
   - Invalidação automática
   - Armazenamento local
   - Sincronização offline

3. **Validações Avançadas**
   - Validação de dependências
   - Regras de negócio customizáveis

## ⚡ Performance

### Otimizações Implementadas

- **Debounce**: Evita requisições excessivas
- **Cache**: Resultados armazenados automaticamente
- **Virtual Scrolling**: Para listas grandes (futuro)
- **Change Detection**: OnPush strategy

### Métricas Esperadas

- Tempo de resposta: <200ms
- Cache hit rate: >80%
- Memória utilizada: <10MB

## 🧪 Testing

### Exemplo de Teste

```typescript
describe('RemoteSelectComponent', () => {
  let component: RemoteSelectComponent;
  let fixture: ComponentFixture<RemoteSelectComponent>;
  let mockService: jasmine.SpyObj<any>;

  beforeEach(() => {
    const spy = jasmine.createSpyObj('MockService', ['getEntities']);
    
    TestBed.configureTestingModule({
      imports: [RemoteSelectComponent],
      providers: [
        { provide: 'service', useValue: spy }
      ]
    });
    
    mockService = TestBed.inject('service');
  });

  it('should search on input', fakeAsync(() => {
    component.config = {
      service: mockService,
      searchField: 'name',
      displayField: 'name',
      valueField: 'id'
    };
    
    mockService.getEntities.and.returnValue(of({
      data: [{ id: 1, name: 'João' }],
      total: 1
    }));
    
    component.onSearchInput({ target: { value: 'João' } } as any);
    tick(300);
    
    expect(mockService.getEntities).toHaveBeenCalled();
    expect(component.state.items.length).toBe(1);
  }));
});
```

## 🔍 Debugging

### Console Logs Disponíveis

```typescript
// Busca executada
console.log('RemoteSelect: Busca por "joão" executada');

// Cache hit
console.log('RemoteSelect: Cache hit para "joão"');

// Erro na busca
console.error('RemoteSelect: Erro na busca', error);
```

### Debug Template

```html
<!-- Ativar debug temporário -->
<app-remote-select
  [config]="config"
  #debugRef
></app-remote-select>

<!-- Mostrar estado -->
<pre>{{ debugRef.state | json }}</pre>
```

## 📚 Referências

- [Material Design - Text Fields](https://material.io/components/text-fields)
- [WCAG 2.1 - Combobox Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)
- [Angular - ControlValueAccessor](https://angular.io/api/forms/ControlValueAccessor)

---

## 📝 Changelog

### v1.0.0 (2024-01-XX)
- ✨ Implementação inicial
- 🔍 Autocomplete com debounce
- ⌨️ Navegação por teclado
- 📱 Design responsivo
- 🔄 Integração com Reactive Forms 