/**
 * ApiClient - Handle communication with content API
 */
export class ApiClient {
    constructor(options = {}) {
        // Smart server detection based on environment
        const isDevelopment = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
        const defaultEndpoint = isDevelopment 
            ? 'http://localhost:8080/api/content'  // Development: separate API server
            : '/api/content';                      // Production: same-origin API
            
        this.baseUrl = options.apiEndpoint || defaultEndpoint;
        this.siteId = options.siteId || this.handleMissingSiteId();
        
        // Log API configuration in development
        if (isDevelopment && !options.apiEndpoint) {
            console.log(`🔌 API Client: Using development server at ${this.baseUrl}`);
        }
    }
    
    async getContent(contentId) {
        try {
            const response = await fetch(`${this.baseUrl}/${contentId}?site_id=${this.siteId}`);
            return response.ok ? await response.json() : null;
        } catch (error) {
            console.warn('Failed to fetch content:', contentId, error);
            return null;
        }
    }
    

    async createContent(content, type, htmlMarkup) {
        try {
            const payload = {
                html_markup: htmlMarkup,  // Always send HTML markup - server extracts ID or generates new one
                value: content,
                type: type,
                file_path: this.getCurrentFilePath()  // Always include file path for consistent ID generation
            };
            
            const response = await fetch(`${this.baseUrl}?site_id=${this.siteId}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${this.getAuthToken()}`
                },
                body: JSON.stringify(payload)
            });
            
            if (response.ok) {
                const result = await response.json();
                console.log(`✅ Content created: ${result.id} (${result.type})`);
                return result;
            } else {
                console.warn(`⚠️ Create failed (${response.status}): server will generate ID`);
                return null;
            }
        } catch (error) {
            if (error.name === 'TypeError' && error.message.includes('fetch')) {
                console.warn(`🔌 API Server not reachable at ${this.baseUrl}`);
                console.warn('💡 Start full-stack development: just dev');
            } else {
                console.error('Failed to create content:', error);
            }
            return false;
        }
    }

    async getContentVersions(contentId) {
        try {
            const response = await fetch(`${this.baseUrl}/${contentId}/versions?site_id=${this.siteId}`);
            if (response.ok) {
                const result = await response.json();
                return result.versions || [];
            } else {
                console.warn(`⚠️ Failed to fetch versions (${response.status}): ${contentId}`);
                return [];
            }
        } catch (error) {
            console.error('Failed to fetch version history:', contentId, error);
            return [];
        }
    }

    async rollbackContent(contentId, versionId) {
        try {
            const response = await fetch(`${this.baseUrl}/${contentId}/rollback?site_id=${this.siteId}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${this.getAuthToken()}`
                },
                body: JSON.stringify({ 
                    version_id: versionId 
                })
            });
            
            if (response.ok) {
                console.log(`✅ Content rolled back: ${contentId} to version ${versionId}`);
                return await response.json();
            } else {
                console.warn(`⚠️ Rollback failed (${response.status}): ${contentId}`);
                return false;
            }
        } catch (error) {
            console.error('Failed to rollback content:', contentId, error);
            return false;
        }
    }

    /**
     * Get authentication token for API requests
     * @returns {string} JWT token or mock token for development
     */
    getAuthToken() {
        // Check if we have a real JWT token from OAuth
        const realToken = this.getStoredToken();
        if (realToken && !this.isTokenExpired(realToken)) {
            return realToken;
        }
        
        // Development/mock token for when no real auth is present
        return this.getMockToken();
    }
    
    /**
     * Get current user information from token
     * @returns {string} User identifier
     */
    getCurrentUser() {
        const token = this.getAuthToken();
        
        // If it's a mock token, return mock user
        if (token.startsWith('mock-')) {
            return 'anonymous';
        }
        
        // Parse real JWT token for user info
        try {
            const payload = this.parseJWT(token);
            return payload.sub || payload.user_id || payload.email || 'anonymous';
        } catch (error) {
            console.warn('Failed to parse JWT token:', error);
            return 'anonymous';
        }
    }
    
    /**
     * Get stored JWT token from localStorage/sessionStorage
     * @returns {string|null} Stored JWT token
     */
    getStoredToken() {
        // Try localStorage first (persistent), then sessionStorage (session-only)
        return localStorage.getItem('insertr_auth_token') || 
               sessionStorage.getItem('insertr_auth_token') ||
               null;
    }
    
    /**
     * Store JWT token for future requests
     * @param {string} token - JWT token from OAuth provider
     * @param {boolean} persistent - Whether to use localStorage (true) or sessionStorage (false)
     */
    setStoredToken(token, persistent = true) {
        const storage = persistent ? localStorage : sessionStorage;
        storage.setItem('insertr_auth_token', token);
        
        // Clear the other storage to avoid conflicts
        const otherStorage = persistent ? sessionStorage : localStorage;
        otherStorage.removeItem('insertr_auth_token');
    }
    
    /**
     * Clear stored authentication token
     */
    clearStoredToken() {
        localStorage.removeItem('insertr_auth_token');
        sessionStorage.removeItem('insertr_auth_token');
    }
    
    /**
     * Generate mock JWT token for development/testing
     * @returns {string} Mock JWT token
     */
    getMockToken() {
        // Create a mock JWT-like token for development
        // Format: mock-{user}-{timestamp}-{random}
        const user = 'anonymous';
        const timestamp = Date.now();
        const random = Math.random().toString(36).substr(2, 9);
        return `mock-${user}-${timestamp}-${random}`;
    }
    
    /**
     * Parse JWT token payload
     * @param {string} token - JWT token
     * @returns {object} Parsed payload
     */
    parseJWT(token) {
        if (token.startsWith('mock-')) {
            // Return mock payload for development tokens
            return {
                sub: 'anonymous',
                user_id: 'anonymous',
                email: 'anonymous@localhost',
                iss: 'insertr-dev',
                exp: Date.now() + 24 * 60 * 60 * 1000 // 24 hours from now
            };
        }
        
        try {
            // Parse real JWT token
            const parts = token.split('.');
            if (parts.length !== 3) {
                throw new Error('Invalid JWT format');
            }
            
            const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));
            return payload;
        } catch (error) {
            throw new Error(`Failed to parse JWT token: ${error.message}`);
        }
    }
    
    /**
     * Check if JWT token is expired
     * @param {string} token - JWT token
     * @returns {boolean} True if token is expired
     */
    isTokenExpired(token) {
        try {
            const payload = this.parseJWT(token);
            const now = Math.floor(Date.now() / 1000);
            return payload.exp && payload.exp < now;
        } catch (error) {
            // If we can't parse the token, consider it expired
            return true;
        }
    }
    
    /**
     * Initialize OAuth flow with provider (Google, GitHub, etc.)
     * @param {string} provider - OAuth provider ('google', 'github', etc.)
     * @returns {Promise<boolean>} Success status
     */
    async initiateOAuth(provider = 'google') {
        // This will be implemented when we add real OAuth integration
        console.log(`🔐 OAuth flow with ${provider} not yet implemented`);
        console.log('💡 For now, using mock authentication in development');
        
        // Store a mock token for development
        const mockToken = this.getMockToken();
        this.setStoredToken(mockToken, true);
        
        return true;
    }
    
    /**
     * Handle OAuth callback after user returns from provider
     * @param {URLSearchParams} urlParams - URL parameters from OAuth callback
     * @returns {Promise<boolean>} Success status
     */
    async handleOAuthCallback(urlParams) {
        // This will be implemented when we add real OAuth integration
        const code = urlParams.get('code');
        const state = urlParams.get('state');
        
        if (code) {
            console.log('🔐 OAuth callback received, exchanging code for token...');
            // TODO: Exchange authorization code for JWT token
            // const token = await this.exchangeCodeForToken(code, state);
            // this.setStoredToken(token, true);
            return true;
        }
        
        return false;
    }
    
    /**
     * Handle missing site_id configuration
     * @returns {string} Site ID or throws error
     */
    handleMissingSiteId() {
        console.error('❌ No site_id configured for Insertr.');
        console.log('💡 Add data-site-id attribute to your script tag:');
        console.log('   <script src="insertr.js" data-site-id="mysite"></script>');
        console.log('');
        console.log('🚀 For demos under demos/, site_id is auto-derived from directory name.');
        console.log('🏭 For production sites, you must explicitly set your site_id.');
        
        // Return a placeholder that will cause API calls to fail gracefully
        return '__MISSING_SITE_ID__';
    }

    /**
     * Get current file path from URL for consistent ID generation
     * @returns {string} File path like "index.html", "about.html"
     */
    getCurrentFilePath() {
        const path = window.location.pathname;
        if (path === '/' || path === '') {
            return 'index.html';
        }
        // Remove leading slash: "/about.html" → "about.html"
        return path.replace(/^\//, '');
    }
}