/**
 * Site Definition Loader
 * Phase 5: Sites Renderer & Publishing
 * 
 * Loads site definitions from the filesystem or API.
 */
import axios from 'axios';
import type { SiteDefinition } from '../types';

const SITES_DATA_PATH = import.meta.env.SITES_DATA_PATH || '/sites';

/**
 * Get API base URL - auto-detect based on current origin
 */
function getApiBaseUrl(): string {
  // First check environment variables
  const envUrl = import.meta.env.VITE_API_URL;
  if (envUrl) {
    return envUrl.endsWith('/api') ? envUrl : `${envUrl}/api`;
  }
  
  // Auto-detect based on current origin (browser only)
  if (typeof window !== 'undefined') {
    const origin = window.location.origin;
    
    // If accessing via IP address, use direct backend port
    if (/^\d+\.\d+\.\d+\.\d+/.test(origin) || origin.includes('localhost') || origin.includes('127.0.0.1')) {
      // Backend is on port 8011 (external) when accessed via IP
      if (origin.includes(':8024')) {
        return origin.replace(':8024', ':8011') + '/api';
      }
      // Default: try port 8011
      return origin.split(':')[0] + ':8011/api';
    }
  }
  
  // Production: use subdomain
  return 'https://api.igny8.com/api';
}

const API_URL = getApiBaseUrl();

/**
 * Resolve site slug to site ID.
 * Queries the Site API to get the site ID from the slug.
 */
async function resolveSiteIdFromSlug(siteSlug: string): Promise<number> {
  try {
    // Query sites by slug - slug is unique per account, but we need to search across all accounts for public sites
    const response = await axios.get(`${API_URL}/v1/auth/sites/`, {
      params: { slug: siteSlug },
      timeout: 10000,
      headers: {
        'Accept': 'application/json',
      },
    });
    
    const sites = Array.isArray(response.data?.results) ? response.data.results : 
                  Array.isArray(response.data) ? response.data : [];
    
    if (sites.length > 0) {
      return sites[0].id;
    }
    
    throw new Error(`Site with slug "${siteSlug}" not found`);
  } catch (error) {
    if (axios.isAxiosError(error)) {
      if (error.response?.status === 404) {
        throw new Error(`Site with slug "${siteSlug}" not found`);
      }
      throw new Error(`Failed to resolve site slug: ${error.message}`);
    }
    throw error;
  }
}

/**
 * Load site definition by site slug.
 * First resolves slug to ID, then tries to load from filesystem (deployed sites),
 * then falls back to API.
 */
export async function loadSiteDefinition(siteSlug: string): Promise<SiteDefinition> {
  // First, resolve slug to site ID
  let siteId: number;
  try {
    siteId = await resolveSiteIdFromSlug(siteSlug);
  } catch (error) {
    throw error; // Re-throw slug resolution errors
  }

  // Try API endpoint for deployed site definition first
  try {
    const response = await axios.get(`${API_URL}/v1/publisher/sites/${siteId}/definition/`, {
      timeout: 10000, // 10 second timeout
      headers: {
        'Accept': 'application/json',
      },
    });
    if (response.data) {
      return response.data as SiteDefinition;
    }
  } catch (error) {
    // API load failed, try blueprint endpoint as fallback
    console.error('Failed to load deployed site definition:', error);
    if (axios.isAxiosError(error)) {
      console.error('Error details:', {
        message: error.message,
        code: error.code,
        response: error.response?.status,
        url: error.config?.url,
      });
    }
  }

  // Fallback to blueprint API (for non-deployed sites)
  try {
    const response = await axios.get(`${API_URL}/v1/site-builder/blueprints/?site=${siteId}`);
    const blueprints = Array.isArray(response.data?.results) ? response.data.results : 
                      Array.isArray(response.data) ? response.data : [];
    
    if (blueprints.length > 0) {
      const blueprint = blueprints[0]; // Get latest blueprint
      // Transform blueprint to site definition format
      return transformBlueprintToSiteDefinition(blueprint);
    }
    
    throw new Error(`No blueprint found for site ${siteSlug}`);
  } catch (error) {
    if (axios.isAxiosError(error)) {
      throw new Error(`Failed to load site: ${error.message}`);
    }
    throw error;
  }
}

/**
 * Transform SiteBlueprint to SiteDefinition format.
 */
function transformBlueprintToSiteDefinition(blueprint: any): SiteDefinition {
  return {
    id: blueprint.id,
    name: blueprint.name,
    description: blueprint.description,
    version: blueprint.version,
    layout: blueprint.structure_json?.layout || 'default',
    theme: blueprint.structure_json?.theme || {},
    navigation: blueprint.structure_json?.navigation || [],
    pages: blueprint.pages?.map((page: any) => ({
      id: page.id,
      slug: page.slug,
      title: page.title,
      type: page.type,
      blocks: page.blocks_json || [],
      status: page.status,
      order: page.order || 0,
    })) || [],
    config: blueprint.config_json || {},
    created_at: blueprint.created_at,
    updated_at: blueprint.updated_at,
  };
}

/**
 * Load site definition from a specific version.
 */
export async function loadSiteDefinitionByVersion(
  siteId: string,
  version: number
): Promise<SiteDefinition> {
  try {
    const fsPath = `${SITES_DATA_PATH}/clients/${siteId}/v${version}/site.json`;
    const response = await fetch(fsPath);
    if (response.ok) {
      const definition = await response.json();
      return definition;
    }
    throw new Error(`Version ${version} not found`);
  } catch (error) {
    throw new Error(`Failed to load site version ${version}: ${error}`);
  }
}

