const nocodbService = require('../services/nocodb');
const logger = require('../utils/logger');
const config = require('../config');
const { validateUrl, extractId, extractWalkSheetConfig } = require('../utils/helpers');

class SettingsController {
    // Default settings values
    static defaultSettings = {
        walk_sheet_title: 'Campaign Walk Sheet',
        walk_sheet_subtitle: 'Door-to-Door Canvassing Form',
        walk_sheet_footer: 'Thank you for your support!',
        qr_code_1_url: '',
        qr_code_1_label: '',
        qr_code_2_url: '',
        qr_code_2_label: '',
        qr_code_3_url: '',
        qr_code_3_label: ''
    };
    
    async getStartLocation(req, res) {
        try {
            const settings = await nocodbService.getLatestSettings();
            
            if (settings) {
                let lat, lng, zoom;
                
                if (settings['Geo-Location']) {
                    const parts = settings['Geo-Location'].split(';');
                    if (parts.length === 2) {
                        lat = parseFloat(parts[0]);
                        lng = parseFloat(parts[1]);
                    }
                } else if (settings.latitude && settings.longitude) {
                    lat = parseFloat(settings.latitude);
                    lng = parseFloat(settings.longitude);
                }
                
                zoom = parseInt(settings.zoom) || config.map.defaultZoom;
                
                if (lat && lng && !isNaN(lat) && !isNaN(lng)) {
                    return res.json({
                        success: true,
                        location: {
                            latitude: lat,
                            longitude: lng,
                            zoom: zoom
                        },
                        source: 'database',
                        settingsId: extractId(settings),
                        lastUpdated: settings.created_at
                    });
                }
            }
            
            // Return defaults
            res.json({
                success: true,
                location: {
                    latitude: config.map.defaultLat,
                    longitude: config.map.defaultLng,
                    zoom: config.map.defaultZoom
                },
                source: 'defaults'
            });
            
        } catch (error) {
            logger.error('Error fetching start location:', error);
            
            // Return defaults on error
            res.json({
                success: true,
                location: {
                    latitude: config.map.defaultLat,
                    longitude: config.map.defaultLng,
                    zoom: config.map.defaultZoom
                },
                source: 'defaults'
            });
        }
    }
    
    async updateStartLocation(req, res) {
        try {
            const { latitude, longitude, zoom } = req.body;
            
            // Validate input
            if (!latitude || !longitude) {
                return res.status(400).json({
                    success: false,
                    error: 'Latitude and longitude are required'
                });
            }
            
            const lat = parseFloat(latitude);
            const lng = parseFloat(longitude);
            const mapZoom = parseInt(zoom) || 11;
            
            if (isNaN(lat) || isNaN(lng) || lat < -90 || lat > 90 || lng < -180 || lng > 180) {
                return res.status(400).json({
                    success: false,
                    error: 'Invalid coordinates'
                });
            }
            
            if (!config.nocodb.settingsSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Settings sheet not configured'
                });
            }
            
            // Get current settings to preserve other fields
            let currentConfig = {};
            try {
                currentConfig = await nocodbService.getLatestSettings() || {};
                
                // Debug logging to see what we're getting
                logger.info('Retrieved current config:', {
                    id: currentConfig.Id || currentConfig.ID || currentConfig.id,
                    walk_sheet_title: currentConfig.walk_sheet_title,
                    walk_sheet_subtitle: currentConfig.walk_sheet_subtitle,
                    walk_sheet_footer: currentConfig.walk_sheet_footer,
                    hasFooter: !!currentConfig.walk_sheet_footer,
                    footerType: typeof currentConfig.walk_sheet_footer,
                    allKeys: Object.keys(currentConfig)
                });
            } catch (error) {
                logger.warn('Could not retrieve current settings for preservation, using defaults:', error.message);
                currentConfig = {};
            }
            
            // Create new settings row - use values directly without || operator
            const walkSheetConfig = extractWalkSheetConfig(currentConfig, SettingsController.defaultSettings);
            
            const settingData = {
                created_at: new Date().toISOString(),
                created_by: req.session.userEmail,
                // Map location fields (what we're updating)
                'Geo-Location': `${lat};${lng}`,
                latitude: lat,
                longitude: lng,
                zoom: mapZoom,
                // Preserve walk sheet fields using helper function
                ...walkSheetConfig
            };
            
            logger.info('Creating settings row with data:', {
                walk_sheet_footer: settingData.walk_sheet_footer,
                footerLength: settingData.walk_sheet_footer?.length
            });
            
            const response = await nocodbService.create(
                config.nocodb.settingsSheetId,
                settingData
            );
            
            logger.info('Created new settings row with start location');
            
            res.json({
                success: true,
                message: 'Start location saved successfully',
                location: { latitude: lat, longitude: lng, zoom: mapZoom },
                settingsId: extractId(response)
            });
            
        } catch (error) {
            logger.error('Error updating start location:', error);
            res.status(500).json({
                success: false,
                error: error.message || 'Failed to update start location'
            });
        }
    }
     async getWalkSheetConfig(req, res) {
        try {
            if (!config.nocodb.settingsSheetId) {
                logger.warn('SETTINGS_SHEET_ID not configured, returning defaults');
                return res.json({
                    success: true,
                    config: SettingsController.defaultSettings,
                    source: 'defaults',
                    message: 'Settings sheet not configured, using defaults'
                });
            }

            const settings = await nocodbService.getLatestSettings();
            
            if (!settings) {
                logger.info('No settings found in database, returning defaults');
                return res.json({
                    success: true,
                    config: SettingsController.defaultSettings,
                    source: 'defaults',
                    message: 'No settings found in database'
                });
            }

            const walkSheetConfig = extractWalkSheetConfig(settings, SettingsController.defaultSettings);

            logger.info(`Retrieved walk sheet config from database (ID: ${extractId(settings)})`);
            res.json({
                success: true,
                config: walkSheetConfig,
                source: 'database',
                settingsId: extractId(settings),
                lastUpdated: settings.created_at || settings.updated_at
            });
            
        } catch (error) {
            logger.error('Failed to get walk sheet config:', error);
            
            // Return defaults if there's an error
            res.json({
                success: true,
                config: SettingsController.defaultSettings,
                source: 'defaults',
                message: 'Error retrieving from database, using defaults',
                error: error.message
            });
        }
    }
    
    async updateWalkSheetConfig(req, res) {
        try {
            if (!config.nocodb.settingsSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Settings sheet not configured'
                });
            }
            
            const configData = req.body;
            logger.info('Received walk sheet config:', JSON.stringify(configData, null, 2));
            
            // Validate input
            if (!configData || typeof configData !== 'object') {
                return res.status(400).json({
                    success: false,
                    error: 'Invalid configuration data'
                });
            }
            
            // Get current settings to preserve other fields
            let currentConfig = {};
            try {
                currentConfig = await nocodbService.getLatestSettings() || {};
            } catch (error) {
                logger.warn('Could not retrieve current settings for preservation, using defaults:', error.message);
                currentConfig = {};
            }
            
            const userEmail = req.session.userEmail;
            const timestamp = new Date().toISOString();
            
            // Prepare data for saving
            const walkSheetData = {
                created_at: timestamp,
                created_by: userEmail,
                // Preserve map location fields with consistent fallbacks
                'Geo-Location': currentConfig['Geo-Location'] || currentConfig.geodata || `${config.map.defaultLat};${config.map.defaultLng}`,
                latitude: currentConfig.latitude || config.map.defaultLat,
                longitude: currentConfig.longitude || config.map.defaultLng,
                zoom: currentConfig.zoom || config.map.defaultZoom,
                // Walk sheet fields (what we're updating)
                walk_sheet_title: (configData.walk_sheet_title || '').toString().trim(),
                walk_sheet_subtitle: (configData.walk_sheet_subtitle || '').toString().trim(),
                walk_sheet_footer: (configData.walk_sheet_footer || '').toString().trim(),
                'Walk Sheet Title': (configData.walk_sheet_title || '').toString().trim(),
                'Walk Sheet Subtitle': (configData.walk_sheet_subtitle || '').toString().trim(),
                'Walk Sheet Footer': (configData.walk_sheet_footer || '').toString().trim(),
                qr_code_1_url: validateUrl(configData.qr_code_1_url),
                qr_code_1_label: (configData.qr_code_1_label || '').toString().trim(),
                qr_code_2_url: validateUrl(configData.qr_code_2_url),
                qr_code_2_label: (configData.qr_code_2_label || '').toString().trim(),
                qr_code_3_url: validateUrl(configData.qr_code_3_url),
                qr_code_3_label: (configData.qr_code_3_label || '').toString().trim(),
                'QR Code 1 URL': validateUrl(configData.qr_code_1_url),
                'QR Code 1 Label': (configData.qr_code_1_label || '').toString().trim(),
                'QR Code 2 URL': validateUrl(configData.qr_code_2_url),
                'QR Code 2 Label': (configData.qr_code_2_label || '').toString().trim(),
                'QR Code 3 URL': validateUrl(configData.qr_code_3_url),
                'QR Code 3 Label': (configData.qr_code_3_label || '').toString().trim()
            };
            
            const response = await nocodbService.create(
                config.nocodb.settingsSheetId,
                walkSheetData
            );
            
            const newId = extractId(response);
            
            res.json({
                success: true,
                message: 'Walk sheet configuration saved successfully',
                config: walkSheetData,
                settingsId: newId,
                timestamp: timestamp
            });
            
        } catch (error) {
            logger.error('Failed to save walk sheet config:', error);
            logger.error('Error response:', error.response?.data);
            
            let errorMessage = 'Failed to save walk sheet configuration';
            let errorDetails = null;
            
            if (error.response?.data) {
                if (error.response.data.message) {
                    errorMessage = error.response.data.message;
                }
                if (error.response.data.errors) {
                    errorDetails = error.response.data.errors;
                }
            }
            
            res.status(500).json({
                success: false,
                error: errorMessage,
                details: errorDetails,
                timestamp: new Date().toISOString()
            });
        }
    }
    
    // Public endpoint for start location (no auth required)
    async getPublicStartLocation(req, res) {
        try {
            const settings = await nocodbService.getLatestSettings();
            
            if (settings) {
                let lat, lng, zoom;
                
                if (settings['Geo-Location']) {
                    const parts = settings['Geo-Location'].split(';');
                    if (parts.length === 2) {
                        lat = parseFloat(parts[0]);
                        lng = parseFloat(parts[1]);
                    }
                } else if (settings.latitude && settings.longitude) {
                    lat = parseFloat(settings.latitude);
                    lng = parseFloat(settings.longitude);
                }
                
                zoom = parseInt(settings.zoom) || config.map.defaultZoom;
                
                if (lat && lng && !isNaN(lat) && !isNaN(lng)) {
                    logger.info(`Returning location from database: ${lat}, ${lng}, zoom: ${zoom}`);
                    return res.json({
                        latitude: lat,
                        longitude: lng,
                        zoom: zoom
                    });
                }
            }
        } catch (error) {
            logger.error('Error fetching config start location:', error);
        }
        
        // Return defaults
        logger.info(`Using default start location: ${config.map.defaultLat}, ${config.map.defaultLng}, zoom: ${config.map.defaultZoom}`);
        
        res.json({
            latitude: config.map.defaultLat,
            longitude: config.map.defaultLng,
            zoom: config.map.defaultZoom
        });
    }
}

module.exports = new SettingsController();