# 📄 PDF Uploader Component & Service

## 🎯 Visão Geral

O **PDF Uploader System** é composto por dois elementos principais:
- `PdfUploaderComponent` - Componente de interface para upload de documentos PDF
- `PdfUploadService` - Serviço para comunicação com APIs de upload

Baseado no `ImageUploaderComponent` existente, mas otimizado especificamente para documentos PDF com funcionalidades avançadas e integração completa com backend.

## ✨ Funcionalidades

### 🔧 PdfUploaderComponent
- ✅ **Upload de PDFs** - Suporte nativo para arquivos PDF
- ✅ **Drag & Drop** - Interface intuitiva para arrastar arquivos
- ✅ **Lista de Documentos Pendentes** - Controle de documentos obrigatórios
- ✅ **Reordenação** - Arrastar e soltar para reordenar documentos
- ✅ **Visualização** - Abrir PDFs em nova aba
- ✅ **Validação** - Controle de tamanho e tipo de arquivo
- ✅ **Responsivo** - Design adaptável para mobile e desktop
- ✅ **Dark Mode** - Suporte completo ao tema escuro

### 🚀 PdfUploadService
- ✅ **Upload Real** - Integração com APIs de backend
- ✅ **Gerenciamento de Arquivos** - CRUD completo de documentos
- ✅ **Metadados** - Atualização de nome, descrição, etc.
- ✅ **Download URLs** - Geração de URLs seguras para download
- ✅ **Batch Operations** - Operações em lote para múltiplos arquivos

### 📋 Lista de Documentos Pendentes
- Exibe documentos que ainda precisam ser enviados
- Diferencia documentos obrigatórios dos opcionais
- Status visual (Pendente/Enviado)
- Ícones contextuais para cada estado

## 🚀 Como Usar

### 1. Importar o Componente

```typescript
import { PdfUploaderComponent, PdfDocument, PendingDocument } from "../../shared/components/pdf-uploader/pdf-uploader.component";

@Component({
  selector: 'app-contract',
  standalone: true,
  imports: [CommonModule, TabSystemComponent, PdfUploaderComponent],
  // ...
})
export class ContractComponent {
  // Propriedades
  contractDocuments: PdfDocument[] = [];
  pendingDocuments: PendingDocument[] = [
    {
      name: 'Laudo de Vistoria',
      description: 'Documento obrigatório para finalizar o cadastro',
      required: true,
      status: 'pending'
    }
  ];
}
```

### 2. Usar no Template

```html
<app-pdf-uploader
  title="Upload de Documentos do Contrato"
  subtitle="Faça o upload dos documentos assinados do contrato"
  [documents]="contractDocuments"
  [pendingDocuments]="pendingDocuments"
  [maxDocuments]="5"
  [maxSizeMb]="10"
  [showPendingList]="true"
  (documentsChange)="onDocumentsChange($event)"
  (filesChange)="onFilesChange($event)"
  (error)="onDocumentError($event)">
</app-pdf-uploader>
```

### 3. Implementar Event Handlers

```typescript
onDocumentsChange(documents: PdfDocument[]) {
  this.contractDocuments = documents;
  console.log('Documentos atualizados:', documents);
}

onFilesChange(files: File[]) {
  console.log('Arquivos selecionados:', files);
  this.uploadDocuments(files);
}

onDocumentError(error: string) {
  console.error('Erro no upload:', error);
  // Exibir erro para o usuário
}
```

## 📝 Interfaces

### PdfDocument
```typescript
interface PdfDocument {
  id?: string;
  name: string;
  file?: File;
  url?: string;
  size?: number;
  uploadDate?: Date;
  status?: 'pending' | 'uploaded' | 'error';
  description?: string;
}
```

### PendingDocument
```typescript
interface PendingDocument {
  name: string;
  description: string;
  required: boolean;
  status: 'pending' | 'uploaded';
}
```

## ⚙️ Propriedades de Entrada (@Input)

| Propriedade | Tipo | Padrão | Descrição |
|-------------|------|--------|-----------|
| `documents` | `PdfDocument[]` | `[]` | Lista de documentos anexados |
| `pendingDocuments` | `PendingDocument[]` | `[]` | Lista de documentos pendentes |
| `title` | `string` | `'Upload de Documentos'` | Título do componente |
| `subtitle` | `string` | `'Faça o upload dos documentos...'` | Subtítulo explicativo |
| `maxDocuments` | `number` | `10` | Máximo de documentos permitidos |
| `maxSizeMb` | `number` | `10` | Tamanho máximo por arquivo (MB) |
| `allowedTypes` | `string[]` | `['application/pdf']` | Tipos de arquivo aceitos |
| `acceptMultiple` | `boolean` | `true` | Permitir seleção múltipla |
| `showPendingList` | `boolean` | `true` | Exibir lista de pendentes |

## 📤 Eventos de Saída (@Output)

| Evento | Tipo | Descrição |
|--------|------|-----------|
| `documentsChange` | `PdfDocument[]` | Emitido quando a lista de documentos muda |
| `filesChange` | `File[]` | Emitido quando arquivos são selecionados |
| `error` | `string` | Emitido quando ocorre um erro |
| `documentUploaded` | `PdfDocument` | Emitido quando um documento é enviado |

## 🎨 Customização Visual

### CSS Variables Utilizadas
```scss
--background
--surface
--text-primary
--text-secondary
--divider
--idt-primary-color
--idt-primary-shade
--idt-primary-rgb
--idt-danger
--idt-danger-rgb
--idt-success
--idt-success-rgb
--idt-warning
--idt-warning-rgb
--idt-info
--idt-info-rgb
```

### Estados Visuais
- **Hover**: Área de upload com destaque
- **Drag Over**: Feedback visual durante drag & drop
- **Required**: Documentos obrigatórios com borda amarela
- **Completed**: Documentos enviados com borda verde
- **Error**: Estados de erro com cor vermelha

## 🔧 Integração com APIs

### Exemplo de Upload para Servidor
```typescript
// Usando o componente com upload automático
@Component({...})
export class ContractComponent {
  
  onContractFilesChange(files: File[]) {
    // Upload automático usando o serviço
    this.pdfUploaderComponent.uploadFilesToServer(
      files, 
      'contract', 
      this.contractId
    );
  }
}
```

### Uso Direto do PdfUploadService
```typescript
import { PdfUploadService } from '../../shared/components/pdf-uploader/pdf-uploader.service';

@Injectable()
export class ContractService {
  constructor(private pdfUploadService: PdfUploadService) {}
  
  async uploadContractDocument(file: File, contractId: string) {
    try {
      // Upload direto
      const response = await this.pdfUploadService.uploadPdfDirect(
        file, 
        'contract', 
        contractId
      ).toPromise();
      
      console.log('Upload concluído:', response);
      return response;
      
    } catch (error) {
      console.error('Erro no upload:', error);
      throw error;
    }
  }
  
  async loadContractDocuments(fileIds: number[]) {
    try {
      const documents = await this.pdfUploadService.getPdfsByIds(fileIds).toPromise();
      return documents;
    } catch (error) {
      console.error('Erro ao carregar documentos:', error);
      return [];
    }
  }
}
```

### Métodos Disponíveis no PdfUploadService

| Método | Descrição | Parâmetros | Retorno |
|--------|-----------|------------|---------|
| `uploadPdfDirect()` | Upload direto de arquivo | `File, entityType?, entityId?` | `PdfUploadResponse` |
| `uploadPdfUrl()` | Solicita URL para upload | `filename: string` | `DataUrlFile` |
| `uploadPdfConfirm()` | Confirma upload após S3 | `fileUrl: string` | `PdfUploadResponse` |
| `getPdfById()` | Obtém URL de download | `id: number` | `PdfApiResponse` |
| `getPdfsByIds()` | Obtém múltiplos PDFs | `ids: number[]` | `PdfUploadResponse[]` |
| `deletePdf()` | Deleta PDF do servidor | `id: number` | `void` |
| `updatePdfMetadata()` | Atualiza metadados | `id, metadata` | `PdfUploadResponse` |

## 📱 Responsividade

O componente é totalmente responsivo e se adapta para:
- **Desktop**: Layout completo com todas as funcionalidades
- **Tablet**: Interface otimizada para toque
- **Mobile**: Layout compacto e touch-friendly

## 🌙 Dark Mode

Suporte completo ao dark mode através das CSS variables do sistema de tema da aplicação.

## 🔄 Integração com BaseDomainComponent

Para usar dentro de abas do `GenericTabFormComponent`:

```typescript
getFormConfig(): TabFormConfig {
  return {
    // ... outras configurações
    subTabs: [
      {
        id: 'documentos',
        label: 'Documentos',
        icon: 'fa-file-pdf',
        templateType: 'custom',
        customTemplate: 'pdf-uploader',
        // ...
      }
    ]
  };
}
```

## 🚨 Tratamento de Erros

O componente valida:
- ✅ Tipos de arquivo permitidos
- ✅ Tamanho máximo por arquivo
- ✅ Número máximo de documentos
- ✅ Arquivos duplicados

Erros são emitidos através do evento `error` para tratamento personalizado.

## 📊 Casos de Uso

### 1. Contratos
- Upload de contratos assinados
- Documentos complementares
- Anexos legais

### 2. Veículos
- Documentação do veículo
- Laudos de vistoria
- Comprovantes de pagamento

### 3. Motoristas
- CNH e documentos pessoais
- Certificados e cursos
- Comprovantes de endereço

### 4. Fornecedores
- Contratos de prestação de serviço
- Certificações
- Documentos fiscais

## 🎯 Próximos Passos

1. **Integração com API**: Implementar upload real para servidor
2. **Preview de PDF**: Adicionar visualização inline de PDFs
3. **Assinatura Digital**: Integração com ferramentas de assinatura
4. **Histórico**: Controle de versões de documentos
5. **Notificações**: Alertas para documentos vencidos

---

**Criado por**: Equipe de Desenvolvimento PraFrota  
**Data**: Outubro 2024  
**Versão**: 1.0.0
