/**
 * TrafficLight API JavaScript SDK
 * Easy integration with the TrafficLight API
 * @version 1.0.0
 */
class TrafficLightAPI {
    /**
     * Initialize the TrafficLight API client
     * @param {string} apiKey - Your API key
     * @param {string} baseUrl - API base URL (optional)
     */
    constructor(apiKey, baseUrl = 'https://imators.systems/traffic/api.php') {
        if (!apiKey) {
            throw new Error('API key is required');
        }
        
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
    }
    
    /**
     * Make an API request
     * @param {string} endpoint - API endpoint
     * @param {object} params - Additional query parameters
     * @param {string} method - HTTP method (GET or POST)
     * @param {object} body - Request body for POST requests
     * @returns {Promise<object>} - API response
     * @private
     */
    async _request(endpoint, params = {}, method = 'GET', body = null) {
        const url = new URL(this.baseUrl);
        
        // Add endpoint and API key
        url.searchParams.append('endpoint', endpoint);
        url.searchParams.append('api_key', this.apiKey);
        
        // Add additional parameters
        Object.keys(params).forEach(key => {
            if (params[key] !== null && params[key] !== undefined) {
                url.searchParams.append(key, params[key]);
            }
        });
        
        const options = {
            method,
            headers: {
                'Accept': 'application/json'
            }
        };
        
        if (body && method === 'POST') {
            options.headers['Content-Type'] = 'application/json';
            options.body = JSON.stringify(body);
        }
        
        try {
            const response = await fetch(url, options);
            const data = await response.json();
            
            if (!response.ok) {
                throw new Error(data.message || `HTTP error ${response.status}`);
            }
            
            if (data.status === 'error') {
                throw new Error(data.message || 'API error');
            }
            
            return data.data;
        } catch (error) {
            throw error;
        }
    }
    
    /**
     * Get all traffic lights
     * @returns {Promise<Array>} - List of traffic lights
     */
    async getAllLights() {
        return this._request('lights');
    }
    
    /**
     * Get a traffic light by ID
     * @param {number} id - Traffic light ID
     * @returns {Promise<object>} - Traffic light details
     */
    async getLightById(id) {
        if (!id) {
            throw new Error('ID is required');
        }
        
        return this._request('light', { id });
    }
    
    /**
     * Get nearby traffic lights
     * @param {number} lat - Latitude
     * @param {number} lng - Longitude
     * @param {number} radius - Radius in kilometers (default: 1)
     * @returns {Promise<Array>} - List of nearby traffic lights
     */
    async getNearbyLights(lat, lng, radius = 1) {
        if (!lat || !lng) {
            throw new Error('Latitude and longitude are required');
        }
        
        return this._request('nearby', { lat, lng, radius });
    }
    
    /**
     * Add a new traffic light
     * @param {object} lightData - Traffic light data
     * @returns {Promise<object>} - Added traffic light
     */
    async addLight(lightData) {
        if (!lightData) {
            throw new Error('Light data is required');
        }
        
        const requiredFields = ['name', 'latitude', 'longitude', 'direction', 'red_duration', 'green_duration'];
        for (const field of requiredFields) {
            if (!lightData[field]) {
                throw new Error(`${field} is required`);
            }
        }
        
        return this._request('light', {}, 'POST', lightData);
    }
    
    /**
     * Update an existing traffic light
     * @param {number} id - Traffic light ID
     * @param {object} lightData - Updated traffic light data
     * @returns {Promise<object>} - Updated traffic light
     */
    async updateLight(id, lightData) {
        if (!id) {
            throw new Error('ID is required');
        }
        
        if (!lightData || Object.keys(lightData).length === 0) {
            throw new Error('Update data is required');
        }
        
        const data = { id, ...lightData };
        return this._request('update', {}, 'POST', data);
    }
    
    /**
     * Calculate the status of a traffic light
     * @param {object} light - Traffic light object
     * @returns {object} - Status information
     */
    calculateStatus(light) {
        const totalCycle = parseInt(light.red_duration) + parseInt(light.green_duration);
        const currentTime = Math.floor(Date.now() / 1000);
        const timeInCycle = currentTime % totalCycle;
        
        if (timeInCycle < light.red_duration) {
            return {
                current: 'RED',
                nextChange: light.red_duration - timeInCycle,
                nextState: 'GREEN',
                cyclePosition: (timeInCycle / totalCycle) * 100
            };
        } else {
            return {
                current: 'GREEN',
                nextChange: totalCycle - timeInCycle,
                nextState: 'RED',
                cyclePosition: (timeInCycle / totalCycle) * 100
            };
        }
    }
    
    /**
     * Create a map marker for a traffic light (for use with Leaflet)
     * @param {object} light - Traffic light object
     * @param {object} L - Leaflet library object
     * @returns {object} - Leaflet marker
     */
    createLeafletMarker(light, L) {
        if (!L || typeof L.marker !== 'function' || typeof L.divIcon !== 'function') {
            throw new Error('Valid Leaflet library is required');
        }
        
        const status = light.status || this.calculateStatus(light);
        const color = status.current === 'RED' ? '#ef4444' : '#10b981';
        
        const icon = L.divIcon({
            className: '',
            html: `<div style="width: 20px; height: 20px; background-color: ${color}; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 5px rgba(0,0,0,0.3);"></div>`,
            iconSize: [20, 20],
            iconAnchor: [10, 10]
        });
        
        const marker = L.marker([light.latitude, light.longitude], { icon });
        
        marker.bindPopup(`
            <div style="min-width: 200px;">
                <h3 style="font-weight: bold; margin-bottom: 5px;">${light.name}</h3>
                <p>Direction: ${light.direction}</p>
                <div style="display: flex; align-items: center; margin-top: 8px;">
                    <div style="width: 12px; height: 12px; background-color: ${color}; border-radius: 50%; margin-right: 5px;"></div>
                    <span><b>${status.current}</b> - Changes in ${status.nextChange} seconds</span>
                </div>
                <div style="margin-top: 8px; background-color: #f3f4f6; height: 4px; border-radius: 2px; overflow: hidden;">
                    <div style="background-color: ${color}; height: 100%; width: ${status.cyclePosition}%;"></div>
                </div>
                <div style="display: flex; justify-content: space-between; font-size: 12px; margin-top: 2px;">
                    <span>0s</span>
                    <span>${parseInt(light.red_duration) + parseInt(light.green_duration)}s</span>
                </div>
            </div>
        `);
        
        return marker;
    }
}

// Export for Node.js environments
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = TrafficLightAPI;
}