const axios = require('axios');
const logger = require('../utils/logger');

const SOCRATA_DOMAIN = 'https://data.edmonton.ca';

class SocrataService {
    constructor() {
        this.client = axios.create({
            baseURL: SOCRATA_DOMAIN,
            timeout: 30000 // 30 seconds for potentially large datasets
        });

        this.client.interceptors.response.use(
            response => response,
            error => {
                logger.error('Socrata API Error:', {
                    message: error.message,
                    url: error.config?.url,
                    status: error.response?.status,
                    data: error.response?.data
                });
                throw error;
            }
        );
    }

    /**
     * Fetches data from a Socrata dataset.
     * @param {string} datasetId - The ID of the dataset (e.g., 'nggt-rwac').
     * @param {object} params - SoQL query parameters.
     * @returns {Promise<Array>} A promise that resolves to an array of records.
     */
    async get(datasetId, params = {}) {
        try {
            logger.info(`Fetching Socrata dataset ${datasetId} with params:`, params);
            
            // Socrata uses an app token for higher rate limits, but it's not required for public data.
            // We can add an X-App-Token header here if one is obtained.
            const response = await this.client.get(`/resource/${datasetId}.json`, { params });
            
            logger.info(`Successfully fetched ${response.data.length} records from Socrata dataset ${datasetId}`);
            return response.data;
        } catch (error) {
            logger.error(`Failed to fetch Socrata dataset ${datasetId}`, {
                message: error.message,
                status: error.response?.status,
                statusText: error.response?.statusText,
                data: error.response?.data,
                url: error.config?.url,
                params: params
            });
            
            // Provide more specific error messages
            if (error.response?.status === 404) {
                throw new Error(`Dataset ${datasetId} not found on Socrata API`);
            } else if (error.response?.status === 400) {
                throw new Error(`Invalid query parameters for dataset ${datasetId}`);
            } else if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
                throw new Error('Unable to connect to Edmonton Open Data Portal');
            }
            
            throw new Error('Could not retrieve data from the external source.');
        }
    }
}

module.exports = new SocrataService();
