/**
 * Servicio para interactuar con el API de PDFs desde el frontend
 *
 * @example
 * import { pdfService } from '@/services/pdfService';
 *
 * const result = await pdfService.fillPdfForm('contrato.pdf', {
 *   nombre_cliente: 'Juan Pérez',
 *   dni: '12345678A'
 * });
 *
 * if (result.success) {
 *   window.open(result.url, '_blank');
 * }
 */

import axios, { AxiosResponse } from 'axios';

interface PdfFormData {
    [key: string]: string | number | boolean;
}

interface PdfResponse {
    success: boolean;
    path?: string;
    url?: string;
    filename?: string;
    message: string;
    error?: string;
}

interface PdfFieldsResponse {
    success: boolean;
    fields: string[];
    full_data?: any[];
    message: string;
}

interface PdfStatusResponse {
    available: boolean;
    binary?: string;
    message: string;
    note?: string;
}

class PdfService {
    private baseUrl: string = '/api/pdf';

    /**
     * Rellena un formulario PDF y obtiene la URL de descarga
     *
     * @param template - Nombre del archivo plantilla (ej: 'contrato.pdf')
     * @param data - Objeto con los datos del formulario
     * @param filename - Nombre personalizado para el archivo (opcional)
     * @param flatten - Si debe aplanar el PDF (campos no editables)
     * @returns Promesa con la respuesta del servidor
     */
    async fillPdfForm(
        template: string,
        data: PdfFormData,
        filename?: string,
        flatten: boolean = true
    ): Promise<PdfResponse> {
        try {
            const response: AxiosResponse<PdfResponse> = await axios.post(
                `${this.baseUrl}/fill`,
                {
                    template,
                    data,
                    filename,
                    flatten
                }
            );

            return response.data;
        } catch (error: any) {
            return {
                success: false,
                message: error.response?.data?.message || 'Error al generar el PDF',
                error: error.message
            };
        }
    }

    /**
     * Descarga un PDF directamente (inicia la descarga en el navegador)
     *
     * @param template - Nombre del archivo plantilla
     * @param data - Objeto con los datos del formulario
     * @param filename - Nombre para el archivo descargado
     */
    async downloadPdfForm(
        template: string,
        data: PdfFormData,
        filename: string = 'documento.pdf'
    ): Promise<void> {
        try {
            const response = await axios.post(
                `${this.baseUrl}/download`,
                {
                    template,
                    data,
                    filename
                },
                {
                    responseType: 'blob'
                }
            );

            // Crear un enlace temporal para descargar el archivo
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();
            link.remove();
            window.URL.revokeObjectURL(url);
        } catch (error) {
            console.error('Error al descargar el PDF:', error);
            throw error;
        }
    }

    /**
     * Abre el PDF en una nueva pestaña del navegador
     *
     * @param template - Nombre del archivo plantilla
     * @param data - Objeto con los datos del formulario
     */
    async viewPdfForm(
        template: string,
        data: PdfFormData
    ): Promise<void> {
        try {
            const response = await axios.post(
                `${this.baseUrl}/view`,
                {
                    template,
                    data
                },
                {
                    responseType: 'blob'
                }
            );

            const url = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' }));
            window.open(url, '_blank');

            // Limpiar después de un tiempo
            setTimeout(() => window.URL.revokeObjectURL(url), 60000);
        } catch (error) {
            console.error('Error al visualizar el PDF:', error);
            throw error;
        }
    }

    /**
     * Obtiene la lista de campos disponibles en un PDF
     *
     * @param template - Nombre del archivo plantilla
     * @returns Lista de nombres de campos
     */
    async getPdfFields(template: string): Promise<PdfFieldsResponse> {
        try {
            const response: AxiosResponse<PdfFieldsResponse> = await axios.get(
                `${this.baseUrl}/fields`,
                {
                    params: { template }
                }
            );

            return response.data;
        } catch (error: any) {
            return {
                success: false,
                fields: [],
                message: error.response?.data?.message || 'Error al obtener los campos'
            };
        }
    }

    /**
     * Elimina un PDF generado
     *
     * @param path - Ruta del archivo a eliminar
     * @returns Confirmación de eliminación
     */
    async deletePdf(path: string): Promise<{ success: boolean; message: string }> {
        try {
            const response = await axios.delete(`${this.baseUrl}/delete`, {
                data: { path }
            });

            return response.data;
        } catch (error: any) {
            return {
                success: false,
                message: error.response?.data?.message || 'Error al eliminar el PDF'
            };
        }
    }

    /**
     * Verifica el estado de PDFtk en el servidor
     *
     * @returns Estado de disponibilidad de PDFtk
     */
    async checkPdftkStatus(): Promise<PdfStatusResponse> {
        try {
            const response: AxiosResponse<PdfStatusResponse> = await axios.get(
                `${this.baseUrl}/status`
            );

            return response.data;
        } catch (error: any) {
            return {
                available: false,
                message: error.response?.data?.message || 'Error al verificar PDFtk'
            };
        }
    }

    /**
     * Genera un contrato y lo abre en una nueva pestaña
     *
     * @param contratoData - Datos del contrato
     * @returns URL del PDF generado
     */
    async generarYAbrirContrato(contratoData: PdfFormData): Promise<string | null> {
        const result = await this.fillPdfForm('contrato.pdf', contratoData);

        if (result.success && result.url) {
            window.open(result.url, '_blank');
            return result.url;
        }

        return null;
    }
}

// Exportar instancia única del servicio
export const pdfService = new PdfService();

// Exportar también la clase para casos especiales
export default PdfService;

