// Centralized API configuration and functions
// Auto-detect API URL based on current origin (supports both IP and subdomain access)
import { useAuthStore } from '../store/authStore';

function getApiBaseUrl(): string {
  // First check environment variables
  const envUrl = import.meta.env.VITE_BACKEND_URL || import.meta.env.VITE_API_URL;
  if (envUrl) {
    // Ensure env URL ends with /api
    return envUrl.endsWith('/api') ? envUrl : `${envUrl}/api`;
  }
  
  // Auto-detect based on current origin
  const origin = window.location.origin;
  
  // If accessing via localhost or IP, use same origin with backend port
  if (origin.includes('localhost') || origin.includes('127.0.0.1') || /^\d+\.\d+\.\d+\.\d+/.test(origin)) {
    // Backend typically runs on port 8011 (external) or 8010 (internal)
    // If frontend is on port 3000, backend is on 8011
    if (origin.includes(':3000')) {
      return origin.replace(':3000', ':8011') + '/api';
    }
    // If frontend is on port 7921, backend is on 7911
    if (origin.includes(':7921')) {
      return origin.replace(':7921', ':7911') + '/api';
    }
    // Default: try port 8011
    return origin.split(':')[0] + ':8011/api';
  }
  
  // Production: use subdomain
  return 'https://api.igny8.com/api';
}

export const API_BASE_URL = getApiBaseUrl();

// Helper function to get active site ID from store
// Uses browser-compatible approach to avoid circular dependencies
function getActiveSiteId(): number | null {
  try {
    // Access localStorage directly to get persisted site ID
    // This avoids circular dependency issues with importing the store
    const siteStorage = localStorage.getItem('site-storage');
    if (siteStorage) {
      const parsed = JSON.parse(siteStorage);
      const activeSite = parsed?.state?.activeSite;
      if (activeSite && activeSite.id) {
        return activeSite.id;
      }
    }
    return null;
  } catch (error) {
    // If parsing fails or store not available, return null
    console.warn('Failed to get active site ID from storage:', error);
    return null;
  }
}

// Helper function to get active sector ID from store
// Uses browser-compatible approach to avoid circular dependencies
function getActiveSectorId(): number | null {
  try {
    // Access localStorage directly to get persisted sector ID
    // This avoids circular dependency issues with importing the store
    const sectorStorage = localStorage.getItem('sector-storage');
    if (sectorStorage) {
      const parsed = JSON.parse(sectorStorage);
      const activeSector = parsed?.state?.activeSector;
      if (activeSector && activeSector.id) {
        return activeSector.id;
      }
    }
    return null;
  } catch (error) {
    // If parsing fails or store not available, return null
    console.warn('Failed to get active sector ID from storage:', error);
    return null;
  }
}

// Get auth token from store - try Zustand store first, then localStorage as fallback
const getAuthToken = (): string | null => {
  try {
    // First try to get from Zustand store directly (faster, no parsing)
    const authState = useAuthStore.getState();
    if (authState?.token) {
      return authState.token;
    }
    
    // Fallback to localStorage (for cases where store hasn't initialized yet)
    const authStorage = localStorage.getItem('auth-store');
    if (authStorage) {
      const parsed = JSON.parse(authStorage);
      return parsed?.state?.token || null;
    }
  } catch (e) {
    // Ignore parsing errors
  }
  return null;
};

// Get refresh token from store - try Zustand store first, then localStorage as fallback
const getRefreshToken = (): string | null => {
  try {
    // First try to get from Zustand store directly (faster, no parsing)
    const authState = useAuthStore.getState();
    if (authState?.refreshToken) {
      return authState.refreshToken;
    }
    
    // Fallback to localStorage (for cases where store hasn't initialized yet)
    const authStorage = localStorage.getItem('auth-store');
    if (authStorage) {
      const parsed = JSON.parse(authStorage);
      return parsed?.state?.refreshToken || null;
    }
  } catch (e) {
    // Ignore parsing errors
  }
  return null;
};

// Generic API fetch function with timeout
export async function fetchAPI(endpoint: string, options?: RequestInit & { timeout?: number }) {
  const timeout = options?.timeout || 30000; // Default 30 second timeout
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);
  
  try {
    const token = getAuthToken();
    const headers: HeadersInit = {
      'Content-Type': 'application/json',
      ...options?.headers,
    };
    
    // Add JWT token if available
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }

    const response = await fetch(`${API_BASE_URL}${endpoint}`, {
      headers,
      credentials: 'include',
      signal: controller.signal,
      ...options,
    });
    
    clearTimeout(timeoutId);

    // Check content type and length before reading body
    const contentType = response.headers.get('content-type') || '';
    const contentLength = response.headers.get('content-length');

    // Read response body once (can only be consumed once)
    const text = await response.text();

    // Handle 403 Forbidden - check for authentication errors FIRST before throwing
    if (response.status === 403) {
      try {
        const errorData = text ? JSON.parse(text) : null;
        const errorMessage = errorData?.detail || errorData?.message || errorData?.error || response.statusText;
        
        // Check if it's an authentication credentials error
        if (errorMessage?.includes?.('Authentication credentials') || 
            errorMessage?.includes?.('not authenticated') ||
            errorMessage?.includes?.('Invalid token') ||
            errorMessage?.includes?.('Token has expired')) {
          
          // CRITICAL: Authentication token is invalid/missing - force logout
          const authState = useAuthStore.getState();
          if (authState?.isAuthenticated || authState?.token) {
            console.warn('Authentication token invalid - forcing logout');
            const { logout } = useAuthStore.getState();
            logout();
            
            // Redirect to login page
            if (typeof window !== 'undefined') {
              window.location.href = '/signin';
            }
          }
          
          // Throw authentication error
          let err: any = new Error(errorMessage);
          err.status = 403;
          err.data = errorData;
          throw err;
        }
        
        // Not an auth error - could be permissions/plan issue
        let err: any = new Error(errorMessage);
        err.status = 403;
        err.data = errorData;
        throw err;
      } catch (e: any) {
        // If it's the error we just threw, re-throw it
        if (e.status === 403) throw e;
        
        // Parsing failed - throw generic 403 error
        let err: any = new Error(text || response.statusText);
        err.status = 403;
        throw err;
      }
    }

    // Handle 402 Payment Required - plan/limits issue
    if (response.status === 402) {
      let err: any = new Error(response.statusText);
      err.status = response.status;
      try {
        const parsed = text ? JSON.parse(text) : null;
        err.message = parsed?.error || parsed?.message || response.statusText;
        err.data = parsed;
      } catch (_) {
        err.message = text || response.statusText;
      }
      throw err;
    }

    // Handle 401 Unauthorized - try to refresh token
    if (response.status === 401) {
      const refreshToken = getRefreshToken();
      if (refreshToken) {
        try {
          // Try to refresh the token
          const refreshResponse = await fetch(`${API_BASE_URL}/v1/auth/refresh/`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ refresh: refreshToken }),
            credentials: 'include',
          });

          if (refreshResponse.ok) {
            const refreshData = await refreshResponse.json();
            const accessToken = refreshData.data?.access || refreshData.access;
            if (refreshData.success && accessToken) {
              // Update token in store
              try {
                const authStorage = localStorage.getItem('auth-storage');
                if (authStorage) {
                  const parsed = JSON.parse(authStorage);
                  parsed.state.token = accessToken;
                  localStorage.setItem('auth-storage', JSON.stringify(parsed));
                }
              } catch (e) {
                // Ignore storage errors
              }

              // Retry original request with new token
              const newHeaders = {
                ...headers,
                'Authorization': `Bearer ${accessToken}`,
              };
              
              const retryResponse = await fetch(`${API_BASE_URL}${endpoint}`, {
                headers: newHeaders,
                credentials: 'include',
                ...options,
              });
              
              // Process retry response
              const retryText = await retryResponse.text();
              if (retryResponse.ok) {
                if (retryText && retryText.trim()) {
                  try {
                    return JSON.parse(retryText);
                  } catch {
                    return retryText;
                  }
                }
                return null;
              } else {
                // Retry failed - parse and throw the retry error (not the original 401)
                let retryError: any = new Error(retryResponse.statusText);
                retryError.status = retryResponse.status;
                try {
                  const retryErrorData = JSON.parse(retryText);
                  retryError.message = retryErrorData.error || retryErrorData.message || retryResponse.statusText;
                  retryError.data = retryErrorData;
                } catch (e) {
                  retryError.message = retryText.substring(0, 200) || retryResponse.statusText;
                }
                throw retryError;
              }
            }
          }
        } catch (refreshError) {
          // Refresh failed, clear auth state and force re-login
          const { logout } = useAuthStore.getState();
          logout();
          throw refreshError;
        }
      } else {
        // No refresh token available, clear auth state
        const { logout } = useAuthStore.getState();
        logout();
      }
    }

    // Parse error response - extract meaningful error information
    if (!response.ok) {
      let errorMessage = response.statusText;
      let errorType = 'HTTP_ERROR';
      let errorData = null;
      
      try {
        if (contentType.includes('application/json')) {
          try {
            errorData = JSON.parse(text);
            
            // Handle unified error format: {success: false, error: "...", errors: {...}}
            if (errorData.success === false) {
              // Extract error message from unified format
              errorMessage = errorData.error || errorData.message || errorData.detail || errorMessage;
              // Keep errorData for structured error handling
            } else {
              // Old format or other error structure
              errorMessage = errorData.error || errorData.message || errorData.detail || errorMessage;
            }
            
            // Classify error type
            if (errorData.error?.includes('OperationalError')) errorType = 'DATABASE_ERROR';
            else if (errorData.error?.includes('ValidationError')) errorType = 'VALIDATION_ERROR';
            else if (errorData.error?.includes('PermissionDenied')) errorType = 'PERMISSION_ERROR';
            else if (errorData.error?.includes('NotFound')) errorType = 'NOT_FOUND_ERROR';
            else if (errorData.error?.includes('IntegrityError')) errorType = 'DATABASE_ERROR';
            else if (errorData.error?.includes('RelatedObjectDoesNotExist')) errorType = 'RELATED_OBJECT_ERROR';
          } catch (e) {
            // JSON parse failed, use text
            errorMessage = text.substring(0, 200);
          }
        } else {
          // HTML or text response (Django debug page)
          if (text.includes('<!DOCTYPE html>')) {
            // Extract error title from HTML
            const titleMatch = text.match(/<title>([^<]+) at ([^<]+)<\/title>/);
            if (titleMatch) {
              errorType = titleMatch[1].trim(); // e.g., "OperationalError"
              errorMessage = `${errorType} at ${titleMatch[2].trim()}`;
            } else {
              // Fallback: try to extract from h1
              const h1Match = text.match(/<h1[^>]*>([^<]+)<\/h1>/);
              if (h1Match) {
                errorMessage = h1Match[1].trim();
                errorType = errorMessage.split(' ')[0]; // First word is usually error type
              } else {
                errorMessage = `HTTP ${response.status} Error`;
              }
            }
          } else {
            // Plain text error
            errorMessage = text.substring(0, 200); // Limit length
          }
        }
      } catch (e) {
        // If parsing fails, use status text
        errorMessage = response.statusText;
      }

      // Log structured error (not full HTML)
      console.error('API Error:', {
        status: response.status,
        type: errorType,
        message: errorMessage,
        endpoint,
        errorData, // Include full error data for debugging
      });
      
      // Attach error data to error object so it can be accessed in catch block
      const apiError = new Error(`API Error (${response.status}): ${errorType} - ${errorMessage}`);
      (apiError as any).response = errorData;
      (apiError as any).status = response.status;
      throw apiError;
    }

    // Check if response has content before parsing JSON
    // DELETE requests often return 204 No Content with empty body
    if (
      response.status === 204 || // No Content
      contentLength === '0' ||
      !text || text.trim() === '' ||
      (contentType && !contentType.includes('application/json'))
    ) {
      // Return void for empty responses
      return;
    }

    // Parse JSON response
    let parsedResponse;
    try {
      parsedResponse = JSON.parse(text);
    } catch (e) {
      // If JSON parsing fails, return text
      return text;
    }

    // Handle unified API response format
    // Paginated responses: {success: true, count: X, results: [...], next: ..., previous: ...}
    // Single object/list responses: {success: true, data: {...}}
    // Error responses: {success: false, error: "...", errors: {...}}
    
    // If it's a unified format response with success field
    if (parsedResponse && typeof parsedResponse === 'object' && 'success' in parsedResponse) {
      // For paginated responses, return as-is (results is at top level)
      if ('results' in parsedResponse && 'count' in parsedResponse) {
        return parsedResponse;
      }
      
      // For single object/list responses, extract data field
      if ('data' in parsedResponse) {
        return parsedResponse.data;
      }
      
      // Error responses should have been thrown already in !response.ok block above
      // If we somehow get here with an error response (shouldn't happen), throw it
      if (parsedResponse.success === false) {
        const errorMsg = parsedResponse.error || parsedResponse.message || 'Request failed';
        const apiError = new Error(`API Error: ${errorMsg}`);
        (apiError as any).response = parsedResponse;
        (apiError as any).status = 400;
        throw apiError;
      }
      
      // If success is true but no data/results, return the whole response
      return parsedResponse;
    }
    
    // Not a unified format response, return as-is (backward compatibility)
    return parsedResponse;
  } catch (error: any) {
    clearTimeout(timeoutId);
    
    if (error.name === 'AbortError') {
      throw new Error(`Request timeout after ${timeout}ms: ${API_BASE_URL}${endpoint}`);
    }
    
    if (error instanceof TypeError && error.message.includes('Failed to fetch')) {
      throw new Error(`Network Error: Unable to reach API at ${API_BASE_URL}${endpoint}. Check CORS and network connectivity.`);
    }
    throw error;
  }
}

// Keywords-specific API functions
export interface KeywordFilters {
  search?: string;
  status?: string;
  cluster_id?: string;
  intent?: string;
  difficulty_min?: number;
  difficulty_max?: number;
  volume_min?: number;
  volume_max?: number;
  page?: number;
  page_size?: number;
  ordering?: string;
  site_id?: number; // Site filter - automatically added from siteStore
  sector_id?: number; // Sector filter - for second-level filtering
}

export interface KeywordsResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: Keyword[];
}

export interface Keyword {
  id: number;
  seed_keyword_id: number;
  seed_keyword?: SeedKeyword; // Populated by serializer
  keyword: string; // Read-only property from seed_keyword
  volume: number; // Read-only property from seed_keyword or volume_override
  difficulty: number; // Read-only property from seed_keyword or difficulty_override
  intent: string; // Read-only property from seed_keyword
  volume_override?: number | null;
  difficulty_override?: number | null;
  cluster_id: number | null;
  cluster_name?: string | null; // Optional: populated by serializer or frontend
  sector_name?: string | null; // Optional: populated by serializer
  status: string;
  created_at: string;
  updated_at: string;
}

export interface KeywordCreateData {
  seed_keyword_id: number;
  volume_override?: number | null;
  difficulty_override?: number | null;
  cluster_id?: number | null;
  status: string;
}

export interface KeywordUpdateData extends Partial<KeywordCreateData> {}

export async function fetchKeywords(filters: KeywordFilters = {}): Promise<KeywordsResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  // Always add site_id if there's an active site (even for admin/developer)
  // The backend will respect it appropriately - admin/developer can still see all sites
  // but if a specific site is selected, filter by it
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  // Only add if activeSector is not null (null means "All Sectors")
  // ADMIN/DEV OVERRIDE: Only inject if user is not admin/developer (handled by backend)
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    // Only add sector_id if it's not null (null means "All Sectors")
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.status) params.append('status', filters.status);
  if (filters.cluster_id) params.append('cluster_id', filters.cluster_id);
  if (filters.intent) params.append('intent', filters.intent);
  if (filters.difficulty_min !== undefined) params.append('difficulty_min', filters.difficulty_min.toString());
  if (filters.difficulty_max !== undefined) params.append('difficulty_max', filters.difficulty_max.toString());
  if (filters.volume_min !== undefined) params.append('volume_min', filters.volume_min.toString());
  if (filters.volume_max !== undefined) params.append('volume_max', filters.volume_max.toString());
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);

  const queryString = params.toString();
  const endpoint = `/v1/planner/keywords/${queryString ? `?${queryString}` : ''}`;

  return fetchAPI(endpoint);
}

export async function fetchKeyword(id: number): Promise<Keyword> {
  return fetchAPI(`/v1/planner/keywords/${id}/`);
}

export async function createKeyword(data: KeywordCreateData): Promise<Keyword> {
  return fetchAPI('/v1/planner/keywords/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateKeyword(id: number, data: KeywordUpdateData): Promise<Keyword> {
  return fetchAPI(`/v1/planner/keywords/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteKeyword(id: number): Promise<void> {
  return fetchAPI(`/v1/planner/keywords/${id}/`, {
    method: 'DELETE',
  });
}

export async function bulkDeleteKeywords(ids: number[]): Promise<{ deleted_count: number }> {
  return fetchAPI(`/v1/planner/keywords/bulk_delete/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

export async function bulkUpdateKeywordsStatus(ids: number[], status: string): Promise<{ updated_count: number }> {
  return fetchAPI(`/v1/planner/keywords/bulk_update/`, {
    method: 'POST',
    body: JSON.stringify({ ids, status }),
  });
}

// Clusters-specific API functions
export interface ClusterFilters {
  search?: string;
  status?: string;
  difficulty_min?: number;
  difficulty_max?: number;
  volume_min?: number;
  volume_max?: number;
  page?: number;
  page_size?: number;
  ordering?: string;
  site_id?: number; // Site filter - automatically added from siteStore
  sector_id?: number; // Sector filter - for second-level filtering
}

export interface ClustersResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: Cluster[];
}

export interface Cluster {
  id: number;
  name: string;
  description?: string | null;
  keywords_count: number;
  volume: number;
  difficulty: number;  // Average difficulty of keywords in cluster
  mapped_pages: number;
  ideas_count: number;
  content_count: number;
  status: string;
  sector_name?: string | null; // Optional: populated by serializer
  created_at: string;
}

export interface ClusterCreateData {
  name: string;
  description?: string | null;
  status?: string;
}

export interface ClusterUpdateData extends Partial<ClusterCreateData> {}

export async function fetchClusters(filters: ClusterFilters = {}): Promise<ClustersResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  // Always add site_id if there's an active site (even for admin/developer)
  // The backend will respect it appropriately - admin/developer can still see all sites
  // but if a specific site is selected, filter by it
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  // Only add if activeSector is not null (null means "All Sectors")
  // ADMIN/DEV OVERRIDE: Only inject if user is not admin/developer (handled by backend)
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    // Only add sector_id if it's not null (null means "All Sectors")
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.status) params.append('status', filters.status);
  if (filters.difficulty_min !== undefined) params.append('difficulty_min', filters.difficulty_min.toString());
  if (filters.difficulty_max !== undefined) params.append('difficulty_max', filters.difficulty_max.toString());
  if (filters.volume_min !== undefined) params.append('volume_min', filters.volume_min.toString());
  if (filters.volume_max !== undefined) params.append('volume_max', filters.volume_max.toString());
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);

  const queryString = params.toString();
  const endpoint = `/v1/planner/clusters/${queryString ? `?${queryString}` : ''}`;

  return fetchAPI(endpoint);
}

export async function fetchCluster(id: number): Promise<Cluster> {
  return fetchAPI(`/v1/planner/clusters/${id}/`);
}

export async function createCluster(data: ClusterCreateData): Promise<Cluster> {
  return fetchAPI('/v1/planner/clusters/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateCluster(id: number, data: ClusterUpdateData): Promise<Cluster> {
  return fetchAPI(`/v1/planner/clusters/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteCluster(id: number): Promise<void> {
  return fetchAPI(`/v1/planner/clusters/${id}/`, {
    method: 'DELETE',
  });
}

export async function bulkDeleteClusters(ids: number[]): Promise<{ deleted_count: number }> {
  return fetchAPI(`/v1/planner/clusters/bulk_delete/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

export async function bulkUpdateClustersStatus(ids: number[], status: string): Promise<{ updated_count: number }> {
  return fetchAPI(`/v1/planner/clusters/bulk_update/`, {
    method: 'POST',
    body: JSON.stringify({ ids, status }),
  });
}

export async function autoClusterKeywords(keywordIds: number[], sectorId?: number): Promise<{ success: boolean; task_id?: string; clusters_created?: number; keywords_updated?: number; message?: string; error?: string }> {
  const endpoint = `/v1/planner/keywords/auto_cluster/`;
  const requestBody = { ids: keywordIds, sector_id: sectorId };
  
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI(endpoint, {
      method: 'POST',
      body: JSON.stringify(requestBody),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

export async function autoGenerateIdeas(clusterIds: number[]): Promise<{ success: boolean; task_id?: string; ideas_created?: number; message?: string; error?: string }> {
  const endpoint = `/v1/planner/clusters/auto_generate_ideas/`;
  const requestBody = { ids: clusterIds };
  
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI(endpoint, {
      method: 'POST',
      body: JSON.stringify(requestBody),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

export async function generateSingleIdea(ideaId: string | number, clusterId: number): Promise<{ success: boolean; task_id?: string; idea_created?: number; message?: string; error?: string }> {
  const endpoint = `/v1/planner/ideas/${ideaId}/generate_idea/`;
  const requestBody = { cluster_id: clusterId };
  
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI(endpoint, {
      method: 'POST',
      body: JSON.stringify(requestBody),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

// Helper function to fetch all clusters (for dropdowns)
export async function fetchAllClusters(): Promise<Cluster[]> {
  const response = await fetchClusters({ ordering: 'name' });
  return response.results;
}

// ContentIdeas API functions
export interface ContentIdeasFilters {
  search?: string;
  status?: string;
  keyword_cluster_id?: string;
  content_structure?: string;
  content_type?: string;
  page?: number;
  page_size?: number;
  ordering?: string;
  site_id?: number; // Site filter - automatically added from siteStore
  sector_id?: number; // Sector filter - for second-level filtering
}

export interface ContentIdeasResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: ContentIdea[];
}

export interface ContentIdea {
  id: number;
  idea_title: string;
  description?: string | null;
  content_type: string;  // post, page, product, taxonomy
  content_structure: string;  // article, guide, comparison, review, etc.
  target_keywords?: string | null;
  keyword_cluster_id?: number | null;
  keyword_cluster_name?: string | null;
  sector_name?: string | null; // Optional: populated by serializer
  status: string;
  estimated_word_count: number;
  created_at: string;
  updated_at: string;
  // Taxonomy fields
  taxonomy_id?: number | null;
  taxonomy_name?: string | null;
}

export interface ContentIdeaCreateData {
  idea_title: string;
  description?: string | null;
  content_type?: string;
  content_structure?: string;
  target_keywords?: string | null;
  keyword_cluster_id?: number | null;
  status?: string;
  estimated_word_count?: number;
}

export interface ContentIdeaUpdateData extends Partial<ContentIdeaCreateData> {}

export async function fetchContentIdeas(filters: ContentIdeasFilters = {}): Promise<ContentIdeasResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  // Always add site_id if there's an active site (even for admin/developer)
  // The backend will respect it appropriately - admin/developer can still see all sites
  // but if a specific site is selected, filter by it
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  // Only add if activeSector is not null (null means "All Sectors")
  // ADMIN/DEV OVERRIDE: Only inject if user is not admin/developer (handled by backend)
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    // Only add sector_id if it's not null (null means "All Sectors")
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.status) params.append('status', filters.status);
  if (filters.keyword_cluster_id) params.append('keyword_cluster_id', filters.keyword_cluster_id);
  if (filters.content_structure) params.append('content_structure', filters.content_structure);
  if (filters.content_type) params.append('content_type', filters.content_type);
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);

  const queryString = params.toString();
  const endpoint = `/v1/planner/ideas/${queryString ? `?${queryString}` : ''}`;
  return fetchAPI(endpoint);
}

export async function fetchContentIdea(id: number): Promise<ContentIdea> {
  return fetchAPI(`/v1/planner/ideas/${id}/`);
}

export async function createContentIdea(data: ContentIdeaCreateData): Promise<ContentIdea> {
  return fetchAPI('/v1/planner/ideas/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateContentIdea(id: number, data: ContentIdeaUpdateData): Promise<ContentIdea> {
  return fetchAPI(`/v1/planner/ideas/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteContentIdea(id: number): Promise<void> {
  return fetchAPI(`/v1/planner/ideas/${id}/`, {
    method: 'DELETE',
  });
}

export async function bulkDeleteContentIdeas(ids: number[]): Promise<{ deleted_count: number }> {
  return fetchAPI(`/v1/planner/ideas/bulk_delete/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

export async function bulkUpdateContentIdeasStatus(ids: number[], status: string): Promise<{ updated_count: number }> {
  return fetchAPI(`/v1/planner/ideas/bulk_update/`, {
    method: 'POST',
    body: JSON.stringify({ ids, status }),
  });
}

export async function bulkQueueIdeasToWriter(ids: number[]): Promise<{ created_count: number; task_ids: number[] }> {
  return fetchAPI(`/v1/planner/ideas/bulk_queue_to_writer/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

// Tasks API functions
export interface TasksFilters {
  search?: string;
  status?: string;
  cluster_id?: string;
  content_type?: string;
  content_structure?: string;
  page?: number;
  page_size?: number;
  ordering?: string;
  site_id?: number; // Site filter - automatically added from siteStore
  sector_id?: number; // Sector filter - for second-level filtering
}

export interface TasksResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: Task[];
}

export interface Task {
  id: number;
  title: string;
  description?: string | null;
  keywords?: string | null;
  cluster_id?: number | null;
  cluster_name?: string | null;
  sector_name?: string | null; // Optional: populated by serializer
  idea_id?: number | null;
  idea_title?: string | null;
  content_structure: string;
  content_type: string;
  status: string;
  content?: string | null;
  word_count: number;
  meta_title?: string | null;
  meta_description?: string | null;
  content_html?: string | null;
  content_primary_keyword?: string | null;
  content_secondary_keywords?: string[];
  content_tags?: string[];
  content_categories?: string[];
  assigned_post_id?: number | null;
  post_url?: string | null;
  created_at: string;
  updated_at: string;
  // Taxonomy fields
  taxonomy_term_id?: number | null;
  taxonomy_id?: number | null;
  taxonomy_name?: string | null;
}

export interface TaskCreateData {
  title: string;
  description?: string | null;
  keywords?: string | null;
  cluster_id?: number | null;
  idea_id?: number | null;
  content_structure?: string;
  content_type?: string;
  status?: string;
  content?: string | null;
  word_count?: number;
  meta_title?: string | null;
  meta_description?: string | null;
}

export interface TaskUpdateData extends Partial<TaskCreateData> {}

export async function fetchTasks(filters: TasksFilters = {}): Promise<TasksResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  // Always add site_id if there's an active site (even for admin/developer)
  // The backend will respect it appropriately - admin/developer can still see all sites
  // but if a specific site is selected, filter by it
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  // Only add if activeSector is not null (null means "All Sectors")
  // ADMIN/DEV OVERRIDE: Only inject if user is not admin/developer (handled by backend)
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    // Only add sector_id if it's not null (null means "All Sectors")
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.status) params.append('status', filters.status);
  if (filters.cluster_id) params.append('cluster_id', filters.cluster_id);
  if (filters.content_type) params.append('content_type', filters.content_type);
  if (filters.content_structure) params.append('content_structure', filters.content_structure);
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);

  const queryString = params.toString();
  const endpoint = `/v1/writer/tasks/${queryString ? `?${queryString}` : ''}`;
  return fetchAPI(endpoint);
}

export async function fetchTask(id: number): Promise<Task> {
  return fetchAPI(`/v1/writer/tasks/${id}/`);
}

export async function createTask(data: TaskCreateData): Promise<Task> {
  return fetchAPI('/v1/writer/tasks/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateTask(id: number, data: TaskUpdateData): Promise<Task> {
  return fetchAPI(`/v1/writer/tasks/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteTask(id: number): Promise<void> {
  return fetchAPI(`/v1/writer/tasks/${id}/`, {
    method: 'DELETE',
  });
}

export async function bulkDeleteTasks(ids: number[]): Promise<{ deleted_count: number }> {
  return fetchAPI(`/v1/writer/tasks/bulk_delete/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

export async function bulkUpdateTasksStatus(ids: number[], status: string): Promise<{ updated_count: number }> {
  return fetchAPI(`/v1/writer/tasks/bulk_update/`, {
    method: 'POST',
    body: JSON.stringify({ ids, status }),
  });
}

export async function autoGenerateContent(ids: number[]): Promise<{ success: boolean; task_id?: string; tasks_updated?: number; message?: string; error?: string }> {
  const endpoint = `/v1/writer/tasks/auto_generate_content/`;
  const requestBody = { ids };
  
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI(endpoint, {
      method: 'POST',
      body: JSON.stringify(requestBody),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

export async function autoGenerateImages(taskIds: number[]): Promise<{ success: boolean; task_id?: string; images_created?: number; message?: string; error?: string }> {
  const endpoint = `/v1/writer/tasks/auto_generate_images/`;
  const requestBody = { task_ids: taskIds };
  
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI(endpoint, {
      method: 'POST',
      body: JSON.stringify(requestBody),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

export async function generateImagePrompts(contentIds: number[]): Promise<{ success: boolean; task_id?: string; message?: string; error?: string }> {
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI('/v1/writer/content/generate_image_prompts/', {
      method: 'POST',
      body: JSON.stringify({ ids: contentIds }),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

// TaskImages API functions
export interface TaskImage {
  id: number;
  task_id: number;
  task_title?: string | null;
  image_type: string;
  image_url?: string | null;
  image_path?: string | null;
  prompt?: string | null;
  status: string;
  position: number;
  created_at: string;
  updated_at: string;
}

export interface TaskImageFilters {
  task_id?: string;
  image_type?: string;
  status?: string;
  page?: number;
  ordering?: string;
}

export interface TaskImagesResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: TaskImage[];
}

export async function fetchTaskImages(filters: TaskImageFilters = {}): Promise<TaskImagesResponse> {
  const params = new URLSearchParams();
  if (filters.task_id) params.append('task_id', filters.task_id);
  if (filters.image_type) params.append('image_type', filters.image_type);
  if (filters.status) params.append('status', filters.status);
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.ordering) params.append('ordering', filters.ordering || 'task,position,-created_at');

  const queryString = params.toString();
  const endpoint = `/v1/writer/images/${queryString ? `?${queryString}` : ''}`;
  return fetchAPI(endpoint);
}

// Content Images (grouped by content)
export interface ContentImage {
  id: number;
  image_type: string;
  image_url?: string | null;
  image_path?: string | null;
  prompt?: string | null;
  status: string;
  position: number;
  created_at: string;
  updated_at: string;
}

export interface ContentImagesGroup {
  content_id: number;
  content_title: string;
  content_status: 'draft' | 'review' | 'publish';
  featured_image: ContentImage | null;
  in_article_images: ContentImage[];
  overall_status: 'pending' | 'partial' | 'complete' | 'failed';
}

export interface ContentImagesResponse {
  count: number;
  results: ContentImagesGroup[];
}

export interface ImageRecord {
  id: number;
  task_id?: number | null;
  task_title?: string | null;
  content_id?: number | null;
  content_title?: string | null;
  image_type: string;
  image_url?: string | null;
  image_path?: string | null;
  prompt?: string | null;
  status: string;
  position: number;
  created_at: string;
  updated_at: string;
  account_id?: number | null;
}

export interface ImageListResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: ImageRecord[];
}

export interface ImageFilters {
  content_id?: number;
  task_id?: number;
  image_type?: string;
  status?: string;
  ordering?: string;
  page?: number;
  page_size?: number;
}

export interface ContentImagesFilters {
  site_id?: number;
  sector_id?: number;
}

export async function fetchContentImages(filters: ContentImagesFilters = {}): Promise<ContentImagesResponse> {
  const params = new URLSearchParams();
  
  // Automatically add active site filter if not explicitly provided
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  
  const queryString = params.toString();
  // fetchAPI automatically extracts data field from unified format
  return fetchAPI(`/v1/writer/images/content_images/${queryString ? `?${queryString}` : ''}`);
}

export async function bulkUpdateImagesStatus(contentId: number, status: string): Promise<{ updated_count: number }> {
  return fetchAPI(`/v1/writer/images/bulk_update/`, {
    method: 'POST',
    body: JSON.stringify({ content_id: contentId, status }),
  });
}

export async function generateImages(imageIds: number[], contentId?: number): Promise<{ success: boolean; task_id?: string; message?: string; error?: string }> {
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {task_id: "...", ...}
    const response = await fetchAPI('/v1/writer/images/generate_images/', {
      method: 'POST',
      body: JSON.stringify({ 
        ids: imageIds,
        content_id: contentId 
      }),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

export async function fetchImages(filters: ImageFilters = {}): Promise<ImageListResponse> {
  const params = new URLSearchParams();
  if (filters.content_id) params.append('content_id', filters.content_id.toString());
  if (filters.task_id) params.append('task_id', filters.task_id.toString());
  if (filters.image_type) params.append('image_type', filters.image_type);
  if (filters.status) params.append('status', filters.status);
  if (filters.ordering) params.append('ordering', filters.ordering);
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size) params.append('page_size', filters.page_size.toString());

  const queryString = params.toString();
  return fetchAPI(`/v1/writer/images/${queryString ? `?${queryString}` : ''}`);
}

export interface ImageGenerationSettings {
  success: boolean;
  config: {
    provider: string;
    model: string;
    image_type: string;
    max_in_article_images: number;
    image_format: string;
    desktop_enabled: boolean;
    mobile_enabled: boolean;
  };
}

export async function fetchImageGenerationSettings(): Promise<ImageGenerationSettings> {
  return fetchAPI('/v1/system/integrations/image_generation/');
}

export async function deleteTaskImage(id: number): Promise<void> {
  return fetchAPI(`/v1/writer/images/${id}/`, {
    method: 'DELETE',
  });
}

// Sites API functions
export interface Site {
  id: number;
  name: string;
  slug: string;
  domain?: string | null;
  description?: string | null;
  industry?: number | null;
  industry_name?: string | null;
  industry_slug?: string | null;
  is_active: boolean;
  status: string;
  wp_url?: string | null;
  wp_username?: string | null;
  sectors_count: number;
  active_sectors_count: number;
  selected_sectors: number[];
  can_add_sectors: boolean;
  created_at: string;
  updated_at: string;
}

export interface SiteCreateData {
  name: string;
  slug?: string;
  domain?: string;
  description?: string;
  is_active?: boolean;
  status?: string;
  wp_url?: string;
  wp_username?: string;
  wp_app_password?: string;
}

export interface SitesResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: Site[];
}

export async function fetchSites(): Promise<SitesResponse> {
  return fetchAPI('/v1/auth/sites/');
}

export async function fetchSite(id: number): Promise<Site> {
  return fetchAPI(`/v1/auth/sites/${id}/`);
}

export async function createSite(data: SiteCreateData): Promise<Site> {
  return fetchAPI('/v1/auth/sites/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateSite(id: number, data: Partial<SiteCreateData>): Promise<Site> {
  return fetchAPI(`/v1/auth/sites/${id}/`, {
    method: 'PATCH',
    body: JSON.stringify(data),
  });
}

export async function deleteSite(id: number): Promise<void> {
  return fetchAPI(`/v1/auth/sites/${id}/`, {
    method: 'DELETE',
  });
}

export async function setActiveSite(id: number): Promise<{ success: boolean; message: string; site: Site }> {
  return fetchAPI(`/v1/auth/sites/${id}/set_active/`, {
    method: 'POST',
  });
}

export async function selectSectorsForSite(
  siteId: number,
  industrySlug: string,
  sectorSlugs: string[]
): Promise<{ success: boolean; message: string; created_count: number; updated_count: number; sectors: any[] }> {
  return fetchAPI(`/v1/auth/sites/${siteId}/select_sectors/`, {
    method: 'POST',
    body: JSON.stringify({
      industry_slug: industrySlug,
      sector_slugs: sectorSlugs,
    }),
  });
}

export async function fetchSiteSectors(siteId: number): Promise<any[]> {
  const response = await fetchAPI(`/v1/auth/sites/${siteId}/sectors/`);
  // fetchAPI automatically extracts data field from unified format
  return Array.isArray(response) ? response : [];
}

// Industries API functions
export interface Industry {
  id?: number;
  name: string;
  slug: string;
  description: string;
  sectors: Sector[];
  sectors_count?: number;
  keywords_count?: number;
  is_active?: boolean;
}

export interface Sector {
  name: string;
  slug: string;
  description: string;
}

export interface IndustriesResponse {
  success: boolean;
  industries: Industry[];
}

export async function fetchIndustries(): Promise<IndustriesResponse> {
  const response = await fetchAPI('/v1/auth/industries/');
  // fetchAPI automatically extracts data field, but industries endpoint returns {industries: [...]}
  // So we need to handle the nested structure
  if (response && typeof response === 'object' && 'industries' in response) {
    return {
      success: true,
      industries: response.industries || []
    };
  }
  // If response is already an array or different format
  return {
    success: true,
    industries: Array.isArray(response) ? response : []
  };
}

// Sectors API functions

// Settings API functions
export interface AccountSetting {
  id: number;
  key: string;
  config: Record<string, any>;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface AccountSettingsResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: AccountSetting[];
}

export type AccountSettingsErrorType =
  | 'ACCOUNT_SETTINGS_API_ERROR'
  | 'ACCOUNT_SETTINGS_NOT_FOUND'
  | 'ACCOUNT_SETTINGS_VALIDATION_ERROR';

export class AccountSettingsError extends Error {
  type: AccountSettingsErrorType;
  status?: number;
  details?: unknown;

  constructor(type: AccountSettingsErrorType, message: string, status?: number, details?: unknown) {
    super(message);
    this.name = 'AccountSettingsError';
    this.type = type;
    this.status = status;
    this.details = details;
  }
}

function buildAccountSettingsError(error: any, fallbackMessage: string): AccountSettingsError {
  const status = error?.status;
  const response = error?.response;
  const details = response || error;

  if (status === 404) {
    return new AccountSettingsError(
      'ACCOUNT_SETTINGS_NOT_FOUND',
      'No account settings were found for this account yet.',
      status,
      details
    );
  }

  if (status === 400 || response?.errors) {
    const validationMessage =
      response?.error ||
      response?.message ||
      response?.detail ||
      'The account settings request is invalid. Please review the submitted data.';

    return new AccountSettingsError(
      'ACCOUNT_SETTINGS_VALIDATION_ERROR',
      validationMessage,
      status,
      details
    );
  }

  return new AccountSettingsError(
    'ACCOUNT_SETTINGS_API_ERROR',
    error?.message || fallbackMessage,
    status,
    details
  );
}

export async function fetchAccountSettings(): Promise<AccountSettingsResponse> {
  try {
    return await fetchAPI('/v1/system/settings/account/');
  } catch (error: any) {
    throw buildAccountSettingsError(error, 'Unable to load account settings right now.');
  }
}

export async function fetchAccountSetting(key: string): Promise<AccountSetting> {
  try {
    return await fetchAPI(`/v1/system/settings/account/${key}/`);
  } catch (error: any) {
    throw buildAccountSettingsError(error, `Account setting "${key}" is not available.`);
  }
}

export async function createAccountSetting(data: { key: string; config: Record<string, any>; is_active?: boolean }): Promise<AccountSetting> {
  try {
    return await fetchAPI('/v1/system/settings/account/', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  } catch (error: any) {
    throw buildAccountSettingsError(error, 'Unable to create the account setting.');
  }
}

export async function updateAccountSetting(key: string, data: Partial<{ config: Record<string, any>; is_active: boolean }>): Promise<AccountSetting> {
  try {
    return await fetchAPI(`/v1/system/settings/account/${key}/`, {
      method: 'PUT',
      body: JSON.stringify(data),
    });
  } catch (error: any) {
    throw buildAccountSettingsError(error, `Unable to update account setting "${key}".`);
  }
}

export async function deleteAccountSetting(key: string): Promise<void> {
  try {
    await fetchAPI(`/v1/system/settings/account/${key}/`, {
      method: 'DELETE',
    });
  } catch (error: any) {
    throw buildAccountSettingsError(error, `Unable to delete account setting "${key}".`);
  }
}

// User Settings API functions
export interface UserSetting {
  id: number;
  key: string;
  value: Record<string, any>;
  created_at: string;
  updated_at: string;
}

export interface UserSettingsResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: UserSetting[];
}

export async function fetchUserSettings(): Promise<UserSettingsResponse> {
  return fetchAPI('/v1/system/settings/user/');
}

export async function fetchUserSetting(key: string): Promise<UserSetting> {
  return fetchAPI(`/v1/system/settings/user/${key}/`);
}

export async function createUserSetting(data: { key: string; value: Record<string, any> }): Promise<UserSetting> {
  return fetchAPI('/v1/system/settings/user/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateUserSetting(key: string, data: { value: Record<string, any> }): Promise<UserSetting> {
  return fetchAPI(`/v1/system/settings/user/${key}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteUserSetting(key: string): Promise<void> {
  await fetchAPI(`/v1/system/settings/user/${key}/`, {
    method: 'DELETE',
  });
}

// Module Settings
export interface ModuleEnableSettings {
  id: number;
  planner_enabled: boolean;
  writer_enabled: boolean;
  thinker_enabled: boolean;
  automation_enabled: boolean;
  site_builder_enabled: boolean;
  linker_enabled: boolean;
  optimizer_enabled: boolean;
  publisher_enabled: boolean;
  created_at: string;
  updated_at: string;
}

export interface ModuleSetting {
  id: number;
  module_name: string;
  key: string;
  config: Record<string, any>;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

// Deduplicate module-enable fetches to prevent 429s for normal users
let moduleEnableSettingsInFlight: Promise<ModuleEnableSettings> | null = null;

export async function fetchModuleSettings(moduleName: string): Promise<ModuleSetting[]> {
  // fetchAPI extracts data from unified format {success: true, data: [...]}
  // So response IS the array, not an object with results
  const response = await fetchAPI(`/v1/system/settings/modules/module/${moduleName}/`);
  return Array.isArray(response) ? response : [];
}

export async function createModuleSetting(data: { module_name: string; key: string; config: Record<string, any>; is_active?: boolean }): Promise<ModuleSetting> {
  return fetchAPI('/v1/system/settings/modules/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function fetchModuleEnableSettings(): Promise<ModuleEnableSettings> {
  if (moduleEnableSettingsInFlight) {
    return moduleEnableSettingsInFlight;
  }

  moduleEnableSettingsInFlight = fetchAPI('/v1/system/settings/modules/enable/');
  try {
    const response = await moduleEnableSettingsInFlight;
    return response;
  } finally {
    moduleEnableSettingsInFlight = null;
  }
}

export async function updateModuleEnableSettings(data: Partial<ModuleEnableSettings>): Promise<ModuleEnableSettings> {
  const response = await fetchAPI('/v1/system/settings/modules/enable/', {
    method: 'PUT',
    body: JSON.stringify(data),
  });
  return response;
}

export async function updateModuleSetting(moduleName: string, key: string, data: Partial<{ config: Record<string, any>; is_active: boolean }>): Promise<ModuleSetting> {
  return fetchAPI(`/v1/system/settings/modules/${key}/?module_name=${moduleName}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

// Billing API functions
export interface CreditBalance {
  credits: number;
  plan_credits_per_month: number;
  credits_used_this_month: number;
  credits_remaining: number;
}

export interface CreditUsageLog {
  id: number;
  operation_type: string;
  operation_type_display: string;
  credits_used: number;
  cost_usd: string | null;
  model_used: string;
  tokens_input: number | null;
  tokens_output: number | null;
  related_object_type: string;
  related_object_id: number | null;
  metadata: Record<string, any>;
  created_at: string;
}

export interface CreditUsageResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: CreditUsageLog[];
}

export interface UsageSummary {
  period: {
    start: string;
    end: string;
  };
  total_credits_used: number;
  total_cost_usd: number;
  by_operation: Record<string, {
    credits: number;
    cost: number;
    count: number;
  }>;
  by_model: Record<string, {
    credits: number;
    cost: number;
  }>;
}

export async function fetchCreditBalance(): Promise<CreditBalance> {
  try {
    // Canonical balance endpoint (business billing CreditTransactionViewSet.balance)
    const response = await fetchAPI('/v1/billing/transactions/balance/');
    if (response && typeof response === 'object' && 'credits' in response) {
      return response as CreditBalance;
    }
    // Default if response is invalid
    return {
      credits: 0,
      plan_credits_per_month: 0,
      credits_used_this_month: 0,
      credits_remaining: 0,
    };
  } catch (error: any) {
    console.debug('Failed to fetch credit balance, using defaults:', error?.message || error);
    // Return default balance on error so UI can still render
    return {
      credits: 0,
      plan_credits_per_month: 0,
      credits_used_this_month: 0,
      credits_remaining: 0,
    };
  }
}

export async function fetchCreditUsage(filters?: {
  operation_type?: string;
  start_date?: string;
  end_date?: string;
  page?: number;
}): Promise<CreditUsageResponse> {
  const params = new URLSearchParams();
  if (filters?.operation_type) params.append('operation_type', filters.operation_type);
  if (filters?.start_date) params.append('start_date', filters.start_date);
  if (filters?.end_date) params.append('end_date', filters.end_date);
  if (filters?.page) params.append('page', filters.page.toString());
  
  const queryString = params.toString();
  return fetchAPI(`/v1/billing/credits/usage/${queryString ? `?${queryString}` : ''}`);
}

export async function fetchUsageSummary(startDate?: string, endDate?: string): Promise<UsageSummary> {
  const params = new URLSearchParams();
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);
  
  const queryString = params.toString();
  // fetchAPI automatically extracts data field from unified format
  return fetchAPI(`/v1/billing/credits/usage/summary/${queryString ? `?${queryString}` : ''}`);
}

export interface LimitCard {
  title: string;
  limit: number;
  used: number;
  available: number;
  unit: string;
  category: 'planner' | 'writer' | 'images' | 'ai' | 'general';
  percentage: number;
}

export interface UsageLimitsResponse {
  limits: LimitCard[];
}

export async function fetchUsageLimits(): Promise<UsageLimitsResponse> {
  console.log('Fetching usage limits from:', '/v1/billing/credits/usage/limits/');
  try {
    // fetchAPI extracts data from unified format {success: true, data: { limits: [...] }}
    // So response IS the data object
    const response = await fetchAPI('/v1/billing/credits/usage/limits/');
    console.log('Usage limits API response:', response);
    return response;
  } catch (error) {
    console.error('Error fetching usage limits:', error);
    throw error;
  }
}

export interface CreditTransaction {
  id: number;
  transaction_type: string;
  transaction_type_display: string;
  amount: number;
  balance_after: number;
  description: string;
  metadata: Record<string, any>;
  created_at: string;
}

export interface CreditTransactionResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: CreditTransaction[];
}

export async function fetchCreditTransactions(filters?: {
  transaction_type?: string;
  page?: number;
}): Promise<CreditTransactionResponse> {
  const params = new URLSearchParams();
  if (filters?.transaction_type) params.append('transaction_type', filters.transaction_type);
  if (filters?.page) params.append('page', filters.page.toString());
  
  const queryString = params.toString();
  return fetchAPI(`/v1/billing/credits/transactions/${queryString ? `?${queryString}` : ''}`);
}

// Seed Keywords API
export interface SeedKeyword {
  id: number;
  keyword: string;
  industry: number;
  industry_name: string;
  industry_slug: string;
  sector: number;
  sector_name: string;
  sector_slug: string;
  volume: number;
  difficulty: number;
  intent: string;
  intent_display: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface SeedKeywordResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: SeedKeyword[];
}

export async function fetchSeedKeywords(filters?: {
  industry?: number;
  sector?: number;
  intent?: string;
  search?: string;
  page?: number;
  page_size?: number;
}): Promise<SeedKeywordResponse> {
  const params = new URLSearchParams();
  // Use industry_id and sector_id as per backend get_queryset, but also try industry/sector for filterset_fields
  if (filters?.industry) {
    params.append('industry', filters.industry.toString());
    params.append('industry_id', filters.industry.toString()); // Also send industry_id for get_queryset
  }
  if (filters?.sector) {
    params.append('sector', filters.sector.toString());
    params.append('sector_id', filters.sector.toString()); // Also send sector_id for get_queryset
  }
  if (filters?.intent) params.append('intent', filters.intent);
  if (filters?.search) params.append('search', filters.search);
  if (filters?.page) params.append('page', filters.page.toString());
  if (filters?.page_size) params.append('page_size', filters.page_size.toString());
  
  const queryString = params.toString();
  return fetchAPI(`/v1/auth/seed-keywords/${queryString ? `?${queryString}` : ''}`);
}

/**
 * Add SeedKeywords to workflow (create Keywords records)
 */
export async function addSeedKeywordsToWorkflow(seedKeywordIds: number[], siteId: number, sectorId: number): Promise<{ success: boolean; created: number; skipped?: number; errors?: string[] }> {
  try {
    // fetchAPI extracts data from unified format {success: true, data: {...}}
    // So response is already the data object: {created: X, skipped: X, errors: [...]}
    const response = await fetchAPI('/v1/planner/keywords/bulk_add_from_seed/', {
      method: 'POST',
      body: JSON.stringify({
        seed_keyword_ids: seedKeywordIds,
        site_id: siteId,
        sector_id: sectorId,
      }),
    });
    
    // Wrap extracted data with success: true for frontend compatibility
    if (response && typeof response === 'object') {
      return { success: true, ...response } as any;
    }
    
    return { success: true, ...response } as any;
  } catch (error: any) {
    // Error responses are thrown by fetchAPI, but wrap them for consistency
    if (error.response && typeof error.response === 'object') {
      return { success: false, error: error.message, ...error.response } as any;
    }
    throw error;
  }
}

// Author Profiles API
export interface AuthorProfile {
  id: number;
  name: string;
  description: string;
  tone: string;
  language: string;
  structure_template: Record<string, any>;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface AuthorProfileResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: AuthorProfile[];
}

export async function fetchAuthorProfiles(filters?: {
  is_active?: boolean;
  language?: string;
  search?: string;
  page?: number;
}): Promise<AuthorProfileResponse> {
  const params = new URLSearchParams();
  if (filters?.is_active !== undefined) params.append('is_active', filters.is_active.toString());
  if (filters?.language) params.append('language', filters.language);
  if (filters?.search) params.append('search', filters.search);
  if (filters?.page) params.append('page', filters.page.toString());
  
  const queryString = params.toString();
  return fetchAPI(`/v1/system/author-profiles/${queryString ? `?${queryString}` : ''}`);
}

export async function createAuthorProfile(data: Partial<AuthorProfile>): Promise<AuthorProfile> {
  return fetchAPI('/v1/system/author-profiles/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateAuthorProfile(id: number, data: Partial<AuthorProfile>): Promise<AuthorProfile> {
  return fetchAPI(`/v1/system/author-profiles/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

export async function deleteAuthorProfile(id: number): Promise<void> {
  return fetchAPI(`/v1/system/author-profiles/${id}/`, {
    method: 'DELETE',
  });
}

// Content API
export interface ContentFilters {
  search?: string;
  status?: string;
  content_type?: string;
  content_structure?: string;
  source?: string;
  cluster_id?: number;
  page?: number;
  page_size?: number;
  ordering?: string;
  site_id?: number;
  sector_id?: number;
}

export interface Content {
  id: number;
  // Core fields
  title: string;
  content_html: string;
  content_type: string;
  content_structure: string;
  status: 'draft' | 'published';
  source: 'igny8' | 'wordpress';
  // Relations
  cluster_id: number;
  cluster_name?: string | null;
  sector_name?: string | null;
  taxonomy_terms?: Array<{
    id: number;
    name: string;
    taxonomy_type: string;
  }>;
  taxonomy_terms_data?: Array<{
    id: number;
    name: string;
    taxonomy_type: string;
  }>;
  tags?: string[];
  categories?: string[];
  // WordPress integration
  external_id?: string | null;
  external_url?: string | null;
  wordpress_status?: 'publish' | 'draft' | 'pending' | 'future' | 'private' | 'trash' | null;
  // Timestamps
  created_at: string;
  updated_at: string;
  // Image support
  has_image_prompts?: boolean;
  has_generated_images?: boolean;
  // Additional fields used in Linker/Optimizer
  internal_links?: Array<{ anchor_text: string; target_content_id: number }>;
  linker_version?: number;
  optimization_scores?: {
    seo_score: number;
    readability_score: number;
    engagement_score: number;
    overall_score: number;
  };
}

export interface ContentResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: Content[];
}

export async function fetchContent(filters: ContentFilters = {}): Promise<ContentResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.status) params.append('status', filters.status);
  if (filters.task_id) params.append('task_id', filters.task_id.toString());
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);
  
  const queryString = params.toString();
  return fetchAPI(`/v1/writer/content/${queryString ? `?${queryString}` : ''}`);
}

export async function fetchContentById(id: number): Promise<Content> {
  return fetchAPI(`/v1/writer/content/${id}/`);
}

// Fetch WordPress status for published content
export interface WordPressStatusResult {
  wordpress_status: 'publish' | 'draft' | 'pending' | 'future' | 'private' | 'trash' | null;
  external_id: string | null;
  external_url: string | null;
  post_title?: string;
  post_modified?: string;
  last_checked?: string;
}

export async function fetchWordPressStatus(contentId: number): Promise<WordPressStatusResult> {
  try {
    const response = await fetchAPI(`/v1/writer/content/${contentId}/wordpress_status/`);
    return response.data || response;
  } catch (error) {
    console.warn(`Failed to fetch WordPress status for content ${contentId}:`, error);
    return {
      wordpress_status: null,
      external_id: null,
      external_url: null,
    };
  }
}

// Content Publishing API
export interface PublishContentResult {
  content_id: number;
  status: string;
  external_id: string;
  external_url: string;
  message?: string;
}

export interface UnpublishContentResult {
  content_id: number;
  status: string;
  message?: string;
}

export async function publishContent(id: number, site_id?: number): Promise<PublishContentResult> {
  const body: { site_id?: number } = {};
  if (site_id !== undefined) {
    body.site_id = site_id;
  }
  return fetchAPI(`/v1/writer/content/${id}/publish/`, {
    method: 'POST',
    body: JSON.stringify(body),
  });
}

export async function unpublishContent(id: number): Promise<UnpublishContentResult> {
  return fetchAPI(`/v1/writer/content/${id}/unpublish/`, {
    method: 'POST',
  });
}

export async function deleteContent(id: number): Promise<void> {
  return fetchAPI(`/v1/writer/content/${id}/`, {
    method: 'DELETE',
  });
}

export async function bulkDeleteContent(ids: number[]): Promise<{ deleted_count: number }> {
  return fetchAPI(`/v1/writer/content/bulk_delete/`, {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

// Stage 3: Content Validation API
export interface ContentValidationResult {
  content_id: number;
  is_valid: boolean;
  ready_to_publish: boolean;
  validation_errors: Array<{
    field: string;
    code: string;
    message: string;
  }>;
  publish_errors: Array<{
    field: string;
    code: string;
    message: string;
  }>;
  metadata: {
    has_content_type: boolean;
    content_type: string | null;
    has_cluster_mapping: boolean;
    has_taxonomy_mapping: boolean;
  };
}

export async function fetchContentValidation(id: number): Promise<ContentValidationResult> {
  return fetchAPI(`/v1/writer/content/${id}/validation/`);
}

export async function validateContent(id: number): Promise<{
  content_id: number;
  is_valid: boolean;
  errors: Array<{
    field: string;
    code: string;
    message: string;
  }>;
}> {
  return fetchAPI(`/v1/writer/content/${id}/validate/`, {
    method: 'POST',
  });
}

// Content Taxonomy API
export interface ContentTaxonomy {
  id: number;
  name: string;
  slug: string;
  taxonomy_type: 'category' | 'tag' | 'product_category' | 'product_tag' | 'product_attribute' | 'cluster';
  external_taxonomy?: string | null;
  external_id?: string | null;
  parent_id?: number | null;
  description?: string | null;
  count?: number;
  site_id: number;
  sector_id?: number | null;
  created_at: string;
  updated_at: string;
}

export interface ContentTaxonomyFilters {
  taxonomy_type?: string;
  search?: string;
  site_id?: number;
  sector_id?: number;
  page?: number;
  page_size?: number;
  ordering?: string;
}

export interface ContentTaxonomyResponse {
  count: number;
  next: string | null;
  previous: string | null;
  results: ContentTaxonomy[];
}

export async function fetchTaxonomies(filters: ContentTaxonomyFilters = {}): Promise<ContentTaxonomyResponse> {
  const params = new URLSearchParams();

  // Automatically add active site filter if not explicitly provided
  if (!filters.site_id) {
    const activeSiteId = getActiveSiteId();
    if (activeSiteId) {
      filters.site_id = activeSiteId;
    }
  }

  // Automatically add active sector filter if not explicitly provided
  if (filters.sector_id === undefined) {
    const activeSectorId = getActiveSectorId();
    if (activeSectorId !== null && activeSectorId !== undefined) {
      filters.sector_id = activeSectorId;
    }
  }

  if (filters.search) params.append('search', filters.search);
  if (filters.taxonomy_type) params.append('taxonomy_type', filters.taxonomy_type);
  if (filters.site_id) params.append('site_id', filters.site_id.toString());
  if (filters.sector_id) params.append('sector_id', filters.sector_id.toString());
  if (filters.page) params.append('page', filters.page.toString());
  if (filters.page_size !== undefined && filters.page_size !== null) {
    params.append('page_size', filters.page_size.toString());
  }
  if (filters.ordering) params.append('ordering', filters.ordering);
  
  const queryString = params.toString();
  return fetchAPI(`/v1/writer/taxonomies/${queryString ? `?${queryString}` : ''}`);
}

export async function fetchTaxonomyById(id: number): Promise<ContentTaxonomy> {
  return fetchAPI(`/v1/writer/taxonomies/${id}/`);
}

export async function createTaxonomy(data: Partial<ContentTaxonomy>): Promise<ContentTaxonomy> {
  return fetchAPI('/v1/writer/taxonomies/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

export async function updateTaxonomy(id: number, data: Partial<ContentTaxonomy>): Promise<ContentTaxonomy> {
  return fetchAPI(`/v1/writer/taxonomies/${id}/`, {
    method: 'PATCH',
    body: JSON.stringify(data),
  });
}

export async function deleteTaxonomy(id: number): Promise<void> {
  return fetchAPI(`/v1/writer/taxonomies/${id}/`, {
    method: 'DELETE',
  });
}

// Legacy: Site Builder API removed
// SiteBlueprint, PageBlueprint, and related functions deprecated

// Stage 4: Sync Health API
export interface SyncStatus {
  site_id: number;
  integrations: Array<{
    id: number;
    platform: string;
    status: string;
    last_sync_at: string | null;
    sync_enabled: boolean;
    is_healthy: boolean;
    error: string | null;
    mismatch_count: number;
  }>;
  overall_status: 'healthy' | 'warning' | 'error';
  last_sync_at: string | null;
}

export interface SyncMismatches {
  taxonomies: {
    missing_in_wordpress: Array<{
      id: number;
      name: string;
      type: string;
      external_reference?: string;
    }>;
    missing_in_igny8: Array<{
      name: string;
      slug: string;
      type: string;
      external_reference: string;
    }>;
    mismatched: Array<any>;
  };
  products: {
    missing_in_wordpress: Array<any>;
    missing_in_igny8: Array<any>;
  };
  posts: {
    missing_in_wordpress: Array<any>;
    missing_in_igny8: Array<any>;
  };
}

export interface SyncLog {
  integration_id: number;
  platform: string;
  timestamp: string;
  status: string;
  error: string | null;
  duration: number | null;
  items_processed: number | null;
}

export async function fetchSyncStatus(siteId: number): Promise<SyncStatus> {
  return fetchAPI(`/v1/integration/integrations/sites/${siteId}/sync/status/`);
}

export async function runSync(
  siteId: number,
  direction: 'both' | 'to_external' | 'from_external' = 'both',
  contentTypes?: string[]
): Promise<{ site_id: number; sync_results: any[]; total_integrations: number }> {
  return fetchAPI(`/v1/integration/integrations/sites/${siteId}/sync/run/`, {
    method: 'POST',
    body: JSON.stringify({ direction, content_types: contentTypes }),
  });
}

export async function fetchSyncMismatches(siteId: number): Promise<SyncMismatches> {
  return fetchAPI(`/v1/integration/integrations/sites/${siteId}/sync/mismatches/`);
}

export async function fetchSyncLogs(
  siteId: number,
  limit: number = 100,
  integrationId?: number
): Promise<{ site_id: number; logs: SyncLog[]; count: number }> {
  const params = new URLSearchParams();
  params.append('limit', limit.toString());
  if (integrationId) params.append('integration_id', integrationId.toString());
  
  return fetchAPI(`/v1/integration/integrations/sites/${siteId}/sync/logs/?${params.toString()}`);
}

// Stage 4: Deployment Readiness API
export interface DeploymentReadiness {
  ready: boolean;
  checks: {
    cluster_coverage: boolean;
    content_validation: boolean;
    sync_status: boolean;
    taxonomy_completeness: boolean;
  };
  errors: string[];
  warnings: string[];
  details: {
    cluster_coverage: {
      ready: boolean;
      total_clusters: number;
      covered_clusters: number;
      incomplete_clusters: Array<any>;
      errors: string[];
      warnings: string[];
    };
    content_validation: {
      ready: boolean;
      total_content: number;
      valid_content: number;
      invalid_content: Array<any>;
      errors: string[];
      warnings: string[];
    };
    sync_status: {
      ready: boolean;
      has_integration: boolean;
      sync_status: string | null;
      mismatch_count: number;
      errors: string[];
      warnings: string[];
    };
    taxonomy_completeness: {
      ready: boolean;
      total_taxonomies: number;
      required_taxonomies: string[];
      missing_taxonomies: string[];
      errors: string[];
      warnings: string[];
    };
  };
}

// Legacy: Site Builder API removed
// SiteBlueprint, PageBlueprint, and related functions deprecated


export async function generatePageContent(
  pageId: number,
  force?: boolean
): Promise<{ success: boolean; task_id?: string }> {
  return fetchAPI(`/v1/site-builder/pages/${pageId}/generate_content/`, {
    method: 'POST',
    body: JSON.stringify({ force: force || false }),
  });
}

