const QRCode = require('qrcode');
const axios = require('axios');
const FormData = require('form-data');
const winston = require('winston');

// Configure logger
const logger = winston.createLogger({
    level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
    ),
    transports: [
        new winston.transports.Console({
            format: winston.format.simple()
        })
    ]
});

/**
 * Generate QR code as PNG buffer
 * @param {string} text - Text/URL to encode
 * @param {Object} options - QR code options
 * @returns {Promise<Buffer>} PNG buffer
 */
async function generateQRCode(text, options = {}) {
    const defaultOptions = {
        type: 'png',
        width: 256,
        margin: 1,
        color: {
            dark: '#000000',
            light: '#FFFFFF'
        },
        errorCorrectionLevel: 'M'
    };
    
    const qrOptions = { ...defaultOptions, ...options };
    
    try {
        const buffer = await QRCode.toBuffer(text, qrOptions);
        return buffer;
    } catch (error) {
        logger.error('Failed to generate QR code:', error);
        throw new Error('Failed to generate QR code');
    }
}

/**
 * Upload QR code to NocoDB storage
 * @param {Buffer} buffer - PNG buffer
 * @param {string} filename - Filename for the upload
 * @param {Object} config - NocoDB configuration
 * @returns {Promise<Object>} Upload response
 */
async function uploadQRCodeToNocoDB(buffer, filename, config) {
    const formData = new FormData();
    formData.append('file', buffer, {
        filename: filename,
        contentType: 'image/png'
    });
    
    try {
        // Use the base URL without /api/v1 for v2 endpoints
        const baseUrl = config.apiUrl.replace('/api/v1', '');
        const uploadUrl = `${baseUrl}/api/v2/storage/upload`;
        
        logger.info(`Uploading QR code to: ${uploadUrl}`);
        
        const response = await axios({
            url: uploadUrl,
            method: 'post',
            data: formData,
            headers: {
                ...formData.getHeaders(),
                'xc-token': config.apiToken
            },
            params: {
                path: 'qrcodes'
            }
        });
        
        logger.info('QR code upload successful:', response.data);
        return response.data;
    } catch (error) {
        logger.error('Failed to upload QR code to NocoDB:', error.response?.data || error.message);
        throw new Error('Failed to upload QR code');
    }
}

/**
 * Generate and upload QR code
 * @param {string} url - URL to encode
 * @param {string} label - Label for the QR code
 * @param {Object} config - NocoDB configuration
 * @returns {Promise<Object>} Upload result
 */
async function generateAndUploadQRCode(url, label, config) {
    if (!url) {
        return null;
    }
    
    try {
        // Generate QR code
        const buffer = await generateQRCode(url);
        
        // Create filename
        const timestamp = Date.now();
        const safeLabel = label.replace(/[^a-z0-9]/gi, '_').toLowerCase();
        const filename = `qr_${safeLabel}_${timestamp}.png`;
        
        // Upload to NocoDB
        const uploadResult = await uploadQRCodeToNocoDB(buffer, filename, config);
        
        return uploadResult;
    } catch (error) {
        logger.error('Failed to generate and upload QR code:', error);
        throw error;
    }
}

/**
 * Delete QR code from NocoDB storage
 * @param {string} fileUrl - File URL to delete
 * @param {Object} config - NocoDB configuration
 * @returns {Promise<boolean>} Success status
 */
async function deleteQRCodeFromNocoDB(fileUrl, config) {
    if (!fileUrl) {
        return true;
    }
    
    try {
        // Extract file path from URL
        const urlParts = fileUrl.split('/');
        const filePath = urlParts.slice(-2).join('/');
        
        await axios({
            url: `${config.apiUrl}/api/v2/storage/upload`,
            method: 'delete',
            headers: {
                'xc-token': config.apiToken
            },
            params: {
                path: filePath
            }
        });
        
        return true;
    } catch (error) {
        logger.error('Failed to delete QR code from NocoDB:', error);
        // Don't throw error for deletion failures
        return false;
    }
}

module.exports = {
    generateQRCode,
    uploadQRCodeToNocoDB,
    generateAndUploadQRCode,
    deleteQRCodeFromNocoDB
};
