# 🎭 SFI Facial - Integración con Frameworks

Esta documentación muestra cómo integrar el componente SFI Facial en diferentes frameworks frontend.

## 📋 Índice

- [Instalación](#instalación)
- [HTML Vanilla](#html-vanilla)
- [React](#react)
- [Vue](#vue)
- [Configuración](#configuración)
- [Eventos](#eventos)
- [API Reference](#api-reference)

## 🚀 Instalación

### Opción 1: Archivo Compilado
```html
<script src="./dist/index.js"></script>
```

### Opción 2: ES Modules
```javascript
import './dist/index.esm.js';
```

### Opción 3: NPM (futuro)
```bash
npm install sfi-facial
```

## 🌐 HTML Vanilla

### Uso Básico
```html
<!DOCTYPE html>
<html>
<head>
    <title>SFI Facial Demo</title>
</head>
<body>
    <!-- Componente básico -->
    <sfi-facial mode="register"></sfi-facial>
    
    <!-- Componente con configuración -->
    <sfi-facial 
        mode="validate"
        api-url="https://mi-api.com"
        api-timeout="15000"
        blink-threshold="0.15"
        smile-threshold="0.07"
        head-threshold="0.4">
    </sfi-facial>

    <!-- Cargar la librería -->
    <script src="./dist/index.js"></script>
    
    <script>
        // Escuchar eventos
        const component = document.querySelector('sfi-facial');
        
        component.addEventListener('register-success', (event) => {
            console.log('Registro exitoso:', event.detail);
        });
        
        component.addEventListener('validate-success', (event) => {
            console.log('Validación exitosa:', event.detail);
        });
    </script>
</body>
</html>
```

## ⚛️ React

### Configuración TypeScript
```typescript
// types/sfi-facial.d.ts
declare global {
  namespace JSX {
    interface IntrinsicElements {
      'sfi-facial': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
        mode?: 'register' | 'validate';
        'api-url'?: string;
        'api-timeout'?: string;
        'blink-threshold'?: string;
        'smile-threshold'?: string;
        'head-threshold'?: string;
        disabled?: boolean;
      };
    }
  }
}
```

### Componente React
```tsx
import React, { useEffect, useRef, useState } from 'react';
import '../dist/index.js';

const SfiFacialDemo: React.FC = () => {
  const componentRef = useRef<HTMLElement>(null);
  const [result, setResult] = useState<any>(null);

  useEffect(() => {
    const component = componentRef.current;
    if (!component) return;

    const handleSuccess = (event: any) => {
      setResult(event.detail);
    };

    component.addEventListener('register-success', handleSuccess);
    component.addEventListener('validate-success', handleSuccess);

    return () => {
      component.removeEventListener('register-success', handleSuccess);
      component.removeEventListener('validate-success', handleSuccess);
    };
  }, []);

  return (
    <div>
      <sfi-facial
        ref={componentRef}
        mode="register"
        api-url="https://mi-api.com"
        blink-threshold="0.15"
        smile-threshold="0.07"
        head-threshold="0.4"
      />
      
      {result && (
        <div>Resultado: {JSON.stringify(result)}</div>
      )}
    </div>
  );
};
```

## 🔷 Vue

### Composición API (Vue 3)
```vue
<template>
  <div>
    <sfi-facial
      ref="componentRef"
      mode="register"
      :api-url="config.apiUrl"
      :blink-threshold="config.blink"
      :smile-threshold="config.smile"
      :head-threshold="config.head"
      @register-success="handleSuccess"
      @validate-success="handleSuccess"
    />
    
    <div v-if="result">
      Resultado: {{ result }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import '../dist/index.js'

const componentRef = ref<HTMLElement>()
const result = ref<any>(null)

const config = ref({
  apiUrl: 'https://mi-api.com',
  blink: 0.15,
  smile: 0.07,
  head: 0.4
})

const handleSuccess = (event: CustomEvent) => {
  result.value = event.detail
}
</script>
```

### Options API (Vue 2)
```vue
<template>
  <div>
    <sfi-facial
      ref="component"
      mode="register"
      :api-url="apiUrl"
      @register-success="handleSuccess"
    />
  </div>
</template>

<script>
import '../dist/index.js'

export default {
  data() {
    return {
      apiUrl: 'https://mi-api.com',
      result: null
    }
  },
  
  mounted() {
    this.$refs.component.addEventListener('register-success', this.handleSuccess)
  },
  
  beforeDestroy() {
    this.$refs.component.removeEventListener('register-success', this.handleSuccess)
  },
  
  methods: {
    handleSuccess(event) {
      this.result = event.detail
    }
  }
}
</script>
```

## ⚙️ Configuración

### Atributos Disponibles

| Atributo | Tipo | Default | Descripción |
|----------|------|---------|-------------|
| `mode` | `'register' \| 'validate'` | `'register'` | Modo de operación |
| `api-url` | `string` | `'http://localhost:8000'` | URL base de la API |
| `api-timeout` | `number` | `10000` | Timeout en ms |
| `blink-threshold` | `number` | `0.15` | Sensibilidad para parpadeo |
| `smile-threshold` | `number` | `0.07` | Sensibilidad para sonrisa |
| `head-threshold` | `number` | `0.4` | Sensibilidad para cabeza |
| `disabled` | `boolean` | `false` | Deshabilitar componente |

### Ejemplos de Configuración

#### Desarrollo Local
```html
<sfi-facial 
    mode="register"
    api-url="http://localhost:3000"
    api-timeout="5000"
    blink-threshold="0.2"
    smile-threshold="0.1"
    head-threshold="0.5">
</sfi-facial>
```

#### Producción
```html
<sfi-facial 
    mode="validate"
    api-url="https://api.miempresa.com"
    api-timeout="30000"
    blink-threshold="0.12"
    smile-threshold="0.05"
    head-threshold="0.3">
</sfi-facial>
```

## 📡 Eventos

### Eventos de Registro

#### `register-start`
Se emite cuando se inicia el proceso de registro.
```javascript
component.addEventListener('register-start', () => {
    console.log('Iniciando registro...');
});
```

#### `register-success`
Se emite cuando el registro es exitoso.
```javascript
component.addEventListener('register-success', (event) => {
    const data = event.detail;
    console.log('Usuario registrado:', data.userData.name);
});
```

**Estructura del evento:**
```typescript
{
  userData: {
    name: string;
    id: string;
    email?: string;
  };
  faceData: {
    image: string; // base64
    photos: Array<{
      index: number;
      data: string;
      timestamp: number;
    }>;
    timestamp: number;
    livenessScore: number;
  };
}
```

#### `register-error`
Se emite cuando hay un error en el registro.
```javascript
component.addEventListener('register-error', (event) => {
    const error = event.detail;
    console.error('Error:', error.message);
});
```

### Eventos de Validación

#### `validate-start`
Se emite cuando se inicia el proceso de validación.

#### `validate-success`
Se emite cuando la validación es exitosa.
```javascript
component.addEventListener('validate-success', (event) => {
    const data = event.detail;
    console.log('Validación exitosa:', data.person_name);
    console.log('Confianza:', data.confidence);
});
```

**Estructura del evento:**
```typescript
{
  is_match: boolean;
  confidence: number;
  person_name: string;
  message?: string;
}
```

#### `validate-failed`
Se emite cuando la validación falla (persona no reconocida).

#### `validate-error`
Se emite cuando hay un error en la validación.

### Eventos Generales

#### `error`
Se emite cuando hay errores generales.
```javascript
component.addEventListener('error', (event) => {
    const error = event.detail;
    console.error('Error general:', error.code, error.message);
});
```

## 🔧 API Reference

### Métodos Públicos

#### `startRegistration()`
Inicia el proceso de registro programáticamente.
```javascript
const component = document.querySelector('sfi-facial');
component.startRegistration();
```

#### `startValidation()`
Inicia el proceso de validación programáticamente.
```javascript
component.startValidation();
```

#### `getCapturedPhotos()`
Obtiene las fotos capturadas durante el proceso.
```javascript
const photos = component.getCapturedPhotos();
console.log('Fotos capturadas:', photos.length);
```

### Propiedades

#### `mode`
```javascript
component.mode = 'validate';
```

#### `apiUrl`
```javascript
component.apiUrl = 'https://nueva-api.com';
```

## 🚨 Manejo de Errores

### Errores de API
```javascript
component.addEventListener('register-error', (event) => {
    const { code, message } = event.detail;
    
    switch (code) {
        case 'API_ERROR':
            if (message.includes('timeout')) {
                console.log('La API no responde, verifica la conexión');
            } else if (message.includes('404')) {
                console.log('Endpoint no encontrado, verifica la URL');
            } else if (message.includes('500')) {
                console.log('Error del servidor');
            }
            break;
            
        case 'CAMERA_ERROR':
            console.log('No se puede acceder a la cámara');
            break;
            
        default:
            console.log('Error desconocido:', message);
    }
});
```

### Validación de Configuración
```javascript
// Verificar si el componente está configurado correctamente
const component = document.querySelector('sfi-facial');

if (!component.apiUrl) {
    console.warn('URL de API no configurada');
}

if (component.getAttribute('blink-threshold') < 0.05) {
    console.warn('Umbral de parpadeo muy bajo');
}
```

## 📱 Responsive y Mobile

El componente es completamente responsive y funciona en dispositivos móviles:

```css
/* CSS para mobile */
@media (max-width: 768px) {
    sfi-facial {
        width: 100%;
        height: auto;
    }
}
```

## 🔒 Seguridad

### Recomendaciones
- Nunca hardcodear URLs de producción en el código
- Usar HTTPS en producción
- Validar respuestas de la API
- Implementar rate limiting en el backend

### Ejemplo con Variables de Entorno
```javascript
// React
const apiUrl = process.env.REACT_APP_SFI_API_URL || 'http://localhost:8000';

// Vue
const apiUrl = import.meta.env.VITE_SFI_API_URL || 'http://localhost:8000';
```

## 🐛 Debugging

### Logs de Desarrollo
```javascript
// Habilitar logs detallados
localStorage.setItem('sfi-debug', 'true');

// Ver logs en la consola
component.addEventListener('debug', (event) => {
    console.log('Debug:', event.detail);
});
```

### Inspección del Estado
```javascript
// Verificar estado del componente
console.log('Estado actual:', {
    mode: component.mode,
    processing: component._processing,
    apiUrl: component.apiUrl
});
```

## 🤝 Soporte

Para reportar bugs o solicitar funcionalidades:
- Crear un issue en el repositorio
- Incluir logs de la consola
- Especificar framework y versión
- Adjuntar código de ejemplo