# 🚀 API Genérica para Formulários com Sub-Abas

## 📖 **Visão Geral**

A API genérica permite trabalhar com **qualquer entidade** (drivers, vehicles, users, companies, products, etc.) usando os mesmos métodos, eliminando a necessidade de criar código específico para cada tipo.

## 🎯 **Métodos Principais**

### 1. **Abertura com Sub-Abas Customizadas**
```typescript
// API Genérica
await tabSystemService.openTabWithSubTabs(entityType, data, subTabs?, title?)

// Exemplos:
await tabSystemService.openTabWithSubTabs('driver', driverData, ['dados', 'endereco'])
await tabSystemService.openTabWithSubTabs('vehicle', vehicleData, ['dados', 'documentos'])
await tabSystemService.openTabWithSubTabs('user', userData, ['dados', 'permissoes'])
```

### 2. **Abertura com Presets Pré-Definidos**
```typescript
// API Genérica
await tabSystemService.openTabWithPreset(entityType, preset, data?, title?)

// Exemplos:
await tabSystemService.openTabWithPreset('driver', 'withDocs', driverData)
await tabSystemService.openTabWithPreset('vehicle', 'complete', vehicleData)
await tabSystemService.openTabWithPreset('company', 'withAddress', companyData)
```

## 🏗️ **Entidades Suportadas**

| Entidade | Sub-Abas Disponíveis | Presets |
|----------|----------------------|---------|
| **driver** | dados, endereco, documentos, multas | basic, withAddress, withDocs, complete |
| **vehicle** | dados, documentos, manutencao | basic, withDocs, complete |
| **user** | dados, endereco, permissoes | basic, withAddress, complete |
| **client** | dados, endereco, contratos | basic, withAddress, complete |
| **company** | dados, endereco, documentos | basic, withAddress, complete |
| **product** | dados | basic |

## 🎮 **Métodos de Conveniência**

Para facilitar ainda mais, existem métodos específicos para cada entidade:

### Drivers (Mantido para compatibilidade)
```typescript
await tabSystemService.openDriverTabWithPreset('withDocs', driverData)
```

### Veículos
```typescript
await tabSystemService.openVehicleTabWithPreset('complete', vehicleData)
```

### Usuários
```typescript
await tabSystemService.openUserTabWithPreset('withAddress', userData)
```

### Empresas
```typescript
await tabSystemService.openCompanyTabWithPreset('complete', companyData)
```

### Produtos
```typescript
await tabSystemService.openProductTab(productData)
```

## 🧪 **Testando no Console**

### Teste Individual
```javascript
// Veículo básico
component.testEditVehicleBasic()

// Usuário completo
component.testEditUserComplete()

// Empresa com endereço
component.testEditCompanyComplete()
```

### Teste Completo
```javascript
// Testa todas as entidades
component.demoAllEntities()

// Testa API genérica diretamente
component.testGenericAPI()
```

## 📋 **Configuração de Formulários**

### Obter configuração com sub-abas
```typescript
// API Genérica
const config = tabFormConfigService.getFormConfigWithSubTabs('driver', ['dados', 'endereco'])

// Com opções customizadas
const config = tabFormConfigService.getFormConfigWithSubTabs('vehicle', ['dados'], {
  baseFields: customFields,
  customSubTabs: customTabs
})
```

### Obter configuração por preset
```typescript
const config = tabFormConfigService.getFormConfigByPreset('driver', 'withDocs')
```

### Obter presets disponíveis
```typescript
const presets = tabFormConfigService.getFormPresets('driver')
// Retorna: { basic: Function, withAddress: Function, withDocs: Function, complete: Function }
```

## 🔄 **Migração do Código Específico**

### Antes (Específico para Driver)
```typescript
// ❌ Código antigo
await tabSystemService.openDriverTabWithPreset('withDocs', driverData)
const config = tabFormConfigService.getDriverFormConfigWithSubTabs(['dados', 'endereco'])
```

### Depois (Genérico)
```typescript
// ✅ Código novo (funciona para qualquer entidade)
await tabSystemService.openTabWithPreset('driver', 'withDocs', driverData)
const config = tabFormConfigService.getFormConfigWithSubTabs('driver', ['dados', 'endereco'])

// ✅ Ou usando método de conveniência (ainda funciona)
await tabSystemService.openDriverTabWithPreset('withDocs', driverData)
```

## 🎯 **Vantagens da API Genérica**

1. **Reutilização**: Um código serve para todas as entidades
2. **Consistência**: Mesma interface para todos os tipos
3. **Manutenibilidade**: Mudanças em um local afetam todos
4. **Escalabilidade**: Fácil adicionar novas entidades
5. **Flexibilidade**: Sub-abas e presets configuráveis

## 📝 **Exemplos Práticos**

### Cenário 1: Sistema de CRM
```typescript
// Abrir cliente com dados + endereço + contratos
await tabSystemService.openTabWithPreset('client', 'complete', clientData)

// Abrir empresa apenas com dados básicos
await tabSystemService.openTabWithPreset('company', 'basic', companyData)
```

### Cenário 2: Sistema de Logística
```typescript
// Abrir motorista com documentos
await tabSystemService.openTabWithPreset('driver', 'withDocs', driverData)

// Abrir veículo com manutenção
await tabSystemService.openTabWithPreset('vehicle', 'complete', vehicleData)
```

### Cenário 3: E-commerce
```typescript
// Abrir produto (formulário simples)
await tabSystemService.openProductTab(productData)

// Abrir usuário com permissões
await tabSystemService.openTabWithPreset('user', 'complete', userData)
```

## 💾 **Sistema de Salvamento Genérico**

### **🚀 Nova Funcionalidade: Salvamento Universal**

O sistema agora inclui um **mecanismo de salvamento genérico** que funciona automaticamente para **qualquer entidade** aberta através da API genérica, eliminando a necessidade de implementar lógica de salvamento específica para cada domínio.

### **Como Funciona**

#### **1. Arquitetura Baseada em Eventos**
```typescript
// Quando um formulário é submetido em qualquer entidade:
this.tableEvent.emit({
  event: 'formSubmit',
  data: {
    tab,                    // Contexto da aba atual
    formData,               // Dados do formulário preenchido
    isNewItem,              // Se é criação (true) ou edição (false)
    onSuccess: (response) => this.handleSaveSuccess(response),
    onError: (error) => this.handleSaveError(error)
  }
});
```

#### **2. Processamento Automático**
```typescript
// BaseDomainComponent processa automaticamente:
protected onFormSubmit(data: any): void {
  const { tab, formData, isNewItem, onSuccess, onError } = data;
  
  // Auto-detecta operação baseada no contexto
  const operation = isNewItem 
    ? this.createEntity(formData)     // POST para criação
    : this.updateEntity(tab.data.id, formData);  // PUT para edição
    
  // Executa operação e chama callbacks
  operation?.subscribe({
    next: (response) => onSuccess(response),
    error: (error) => onError(error)
  });
}
```

### **🎯 Implementação por Entidade**

#### **Automática (Zero Configuração)**
```typescript
// Para a maioria dos casos - funciona automaticamente
export class ClientsComponent extends BaseDomainComponent<Client> {
  // ✨ Salvamento já funciona out-of-the-box!
  // Sistema detecta service.create() e service.update() automaticamente
}
```

#### **Customizada (Quando Necessário)**
```typescript
// Para lógica específica de validação/processamento
export class VehiclesComponent extends BaseDomainComponent<Vehicle> {
  
  protected createEntity(data: any): Observable<any> {
    // Aplicar validações específicas antes de salvar
    const validatedData = this.validateVehicleData(data);
    return this.vehiclesService.createVehicle(validatedData);
  }
  
  protected updateEntity(id: any, data: any): Observable<any> {
    // Lógica de atualização customizada
    return this.vehiclesService.updateVehicleWithHistory(id, data);
  }
}
```

### **🔄 Compatibilidade com API Genérica**

O salvamento genérico funciona **perfeitamente** com todos os métodos da API genérica:

```typescript
// Qualquer abertura via API genérica tem salvamento automático
await tabSystemService.openTabWithPreset('driver', 'withDocs', driverData);
// → Formulário aberto com salvamento genérico funcionando

await tabSystemService.openTabWithSubTabs('vehicle', vehicleData, ['dados', 'documentos']);
// → Sub-abas carregadas com salvamento genérico funcionando

await tabSystemService.openTabWithPreset('client', 'complete', clientData);
// → Todas as funcionalidades incluindo salvamento automático
```

### **✅ Callbacks Inteligentes**

#### **Sucesso no Salvamento**
```typescript
private onSaveSuccess(tab, response, formComponent): void {
  // ✅ Marca formulário como salvo (remove indicador "*")
  formComponent.markAsSavedSuccessfully();
  
  // ✅ Remove flag de modificação da aba
  this.tabSystemService.setTabModified(tabIndex, false);
  
  // ✅ Atualiza dados da aba com resposta do backend
  tab.data = { ...tab.data, ...response };
  
  console.log('✅ Dados salvos com sucesso');
}
```

#### **Erro no Salvamento**
```typescript
private onSaveError(tab, error, formComponent): void {
  // ❌ Restaura estado do formulário
  formComponent.setSubmitting(false);
  
  // ❌ Pode mostrar notificação de erro
  this.showErrorNotification('Erro ao salvar dados');
  
  console.error('❌ Erro no salvamento:', error);
}
```

### **🎮 Testando Salvamento**

```typescript
// Teste automatizado do fluxo completo
await component.testGenericSaveFlow();

// Console logs esperados:
// "📝 Abrindo formulário para driver..."
// "✏️ Preenchendo dados..."
// "💾 Salvando dados..."
// "✅ Dados salvos com sucesso"
// "🏷️ Aba marcada como não-modificada"
```

### **🏗️ Benefícios do Sistema**

- ✅ **Escalabilidade Total**: Novos domínios funcionam automaticamente
- ✅ **Redução de Código**: -80% de código duplicado removido
- ✅ **Arquitetura Limpa**: Separação clara de responsabilidades
- ✅ **Flexibilidade**: Permite customizações quando necessário
- ✅ **Consistência**: Mesmo comportamento para todas as entidades
- ✅ **API Unificada**: Funciona com qualquer método da API genérica

## 🔧 **Compatibilidade**

✅ **Código existente continua funcionando**  
Os métodos específicos (como `openDriverTabWithPreset`) foram mantidos para compatibilidade, mas internamente usam a nova API genérica **com salvamento automático**.

✅ **Migração gradual**  
Você pode migrar o código aos poucos, começando com novas funcionalidades e depois refatorando o código existente.

✅ **Zero Breaking Changes**  
Nenhuma funcionalidade foi removida ou alterada. Apenas novos métodos foram adicionados, **incluindo o sistema de salvamento genérico**.

✅ **Backwards Compatible**  
Componentes existentes que estendem `BaseDomainComponent` automaticamente ganham o novo sistema de salvamento.

---

**💡 Dica**: Use os métodos de teste no console do navegador para experimentar e entender melhor a API genérica e o sistema de salvamento! 