/**
 * MyUIbrix Backend API Service
 * Provides validation and optimization for MyUIbrix editor
 */

import api from './api';

export interface ElementConfig {
  page_type: string;
  element_name: string;
  variant: string;
  visible: boolean;
  display_order: number;
  custom_styles?: Record<string, any>;
}

export interface ValidationResult {
  valid: boolean;
  optimized_styles?: Record<string, any>;
  suggestions?: string[];
  error?: string;
}

export interface OptimizationResult {
  current_layout: any[];
  suggestions: string[];
  performance_score: number;
}

/**
 * Validate a single element configuration
 */
export const validateElementConfig = async (config: ElementConfig): Promise<ValidationResult> => {
  try {
    const response = await api.post('/admin/myuibrix/validate', config);
    return response.data;
  } catch (error: any) {
    console.error('Failed to validate element config:', error);
    return {
      valid: false,
      error: error.response?.data?.error || 'Validation failed'
    };
  }
};

/**
 * Validate multiple element configurations at once
 */
export const batchValidateConfigs = async (configs: ElementConfig[]): Promise<any> => {
  try {
    const response = await api.post('/admin/myuibrix/validate-batch', configs);
    return response.data;
  } catch (error: any) {
    console.error('Failed to batch validate configs:', error);
    throw error;
  }
};

/**
 * Get element preview metadata
 */
export const getElementPreview = async (
  element: string,
  variant: string,
  viewport: 'desktop' | 'tablet' | 'mobile' = 'desktop'
): Promise<any> => {
  try {
    const response = await api.get('/admin/myuibrix/preview', {
      params: { element, variant, viewport }
    });
    return response.data;
  } catch (error: any) {
    console.error('Failed to get element preview:', error);
    throw error;
  }
};

/**
 * Get layout optimization suggestions
 */
export const optimizePageLayout = async (pageType: string = 'homepage'): Promise<OptimizationResult> => {
  try {
    const response = await api.get('/admin/myuibrix/optimize-layout', {
      params: { page_type: pageType }
    });
    return response.data;
  } catch (error: any) {
    console.error('Failed to optimize layout:', error);
    throw error;
  }
};

/**
 * Debounce helper for style changes
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: NodeJS.Timeout | null = null;
  
  return (...args: Parameters<T>) => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
};

/**
 * Safe DOM manipulation wrapper
 */
export const safeDOM = {
  /**
   * Safely append child element
   */
  appendChild: (parent: Element, child: Element): boolean => {
    try {
      if (!parent.contains(child)) {
        parent.appendChild(child);
        return true;
      }
      return false;
    } catch (e) {
      console.warn('Failed to append child:', e);
      return false;
    }
  },

  /**
   * Safely remove child element
   */
  removeChild: (parent: Element, child: Element): boolean => {
    try {
      if (parent.contains(child)) {
        parent.removeChild(child);
        return true;
      }
      return false;
    } catch (e) {
      console.warn('Failed to remove child:', e);
      return false;
    }
  },

  /**
   * Safely replace child element
   */
  replaceChild: (parent: Element, newChild: Element, oldChild: Element): boolean => {
    try {
      if (parent.contains(oldChild)) {
        parent.replaceChild(newChild, oldChild);
        return true;
      }
      return false;
    } catch (e) {
      console.warn('Failed to replace child:', e);
      return false;
    }
  },

  /**
   * Safely query selector
   */
  querySelector: (selector: string): Element | null => {
    try {
      return document.querySelector(selector);
    } catch (e) {
      console.warn('Invalid selector:', selector, e);
      return null;
    }
  },

  /**
   * Safely query selector all
   */
  querySelectorAll: (selector: string): Element[] => {
    try {
      return Array.from(document.querySelectorAll(selector));
    } catch (e) {
      console.warn('Invalid selector:', selector, e);
      return [];
    }
  },

  /**
   * Safely insert before another element
   */
  insertBefore: (parent: Element, newChild: Element, referenceChild: Node | null): boolean => {
    try {
      if (referenceChild && !parent.contains(referenceChild)) {
        console.warn('Reference child is not a child of parent');
        return false;
      }
      if (!parent.contains(newChild)) {
        parent.insertBefore(newChild, referenceChild);
        return true;
      }
      return false;
    } catch (e) {
      console.warn('Failed to insert before:', e);
      return false;
    }
  }
};
