import { API_CONFIG, getApiHeaders } from '../config/api';

// Types for Service API
export interface ServiceFeature {
  id: number;
  title: string;
  description: string;
  icon: string;
  display_order: number;
}

export interface ServiceExpertise {
  id: number;
  title: string;
  description: string;
  icon: string;
  display_order: number;
}

export interface ServiceCategory {
  id: number;
  name: string;
  slug: string;
  description: string;
  display_order: number;
}

export interface Service {
  id: number;
  title: string;
  description: string;
  short_description?: string;
  slug: string;
  icon: string;
  image?: File | string;
  image_url?: string;
  price: string;
  formatted_price: string;
  category?: ServiceCategory;
  duration?: string;
  deliverables?: string;
  technologies?: string;
  process_steps?: string;
  features_description?: string;
  deliverables_description?: string;
  process_description?: string;
  why_choose_description?: string;
  expertise_description?: string;
  featured: boolean;
  display_order: number;
  is_active: boolean;
  created_at: string;
  updated_at: string;
  features?: ServiceFeature[];
  expertise_items?: ServiceExpertise[];
}

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

export interface ServiceStats {
  total_services: number;
  featured_services: number;
  categories: number;
  average_price: number;
}

export interface ServiceSearchResponse {
  query: string;
  count: number;
  results: Service[];
}

// Helper function to build query string
const buildQueryString = (params: Record<string, any>): string => {
  const searchParams = new URLSearchParams();
  Object.entries(params).forEach(([key, value]) => {
    if (value !== undefined && value !== null) {
      searchParams.append(key, value.toString());
    }
  });
  return searchParams.toString();
};

// Service API functions
export const serviceService = {
  // Get all services with optional filtering
  getServices: async (params?: {
    featured?: boolean;
    category?: string;
    min_price?: number;
    max_price?: number;
    search?: string;
    ordering?: string;
    page?: number;
  }): Promise<ServiceListResponse> => {
    try {
      const queryString = params ? buildQueryString(params) : '';
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/${queryString ? `?${queryString}` : ''}`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch services: ${error.message}`);
      }
      throw new Error('Failed to fetch services: Unknown error');
    }
  },

  // Get a single service by slug
  getServiceBySlug: async (slug: string): Promise<Service> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/${slug}/`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch service: ${error.message}`);
      }
      throw new Error('Failed to fetch service: Unknown error');
    }
  },

  // Get featured services
  getFeaturedServices: async (): Promise<ServiceListResponse> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES_FEATURED}/`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch featured services: ${error.message}`);
      }
      throw new Error('Failed to fetch featured services: Unknown error');
    }
  },

  // Search services
  searchServices: async (query: string): Promise<ServiceSearchResponse> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES_SEARCH}/?q=${encodeURIComponent(query)}`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to search services: ${error.message}`);
      }
      throw new Error('Failed to search services: Unknown error');
    }
  },

  // Get service statistics
  getServiceStats: async (): Promise<ServiceStats> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES_STATS}/`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch service stats: ${error.message}`);
      }
      throw new Error('Failed to fetch service stats: Unknown error');
    }
  },

  // Get all service categories
  getCategories: async (): Promise<ServiceCategory[]> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES_CATEGORIES}/`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch categories: ${error.message}`);
      }
      throw new Error('Failed to fetch categories: Unknown error');
    }
  },

  // Get a single category by slug
  getCategoryBySlug: async (slug: string): Promise<ServiceCategory> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES_CATEGORIES}/${slug}/`;
      
      const response = await fetch(url, {
        method: 'GET',
        headers: getApiHeaders(),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch category: ${error.message}`);
      }
      throw new Error('Failed to fetch category: Unknown error');
    }
  },

  // Admin functions (require authentication)
  createService: async (serviceData: Partial<Service>): Promise<Service> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/admin/create/`;
      
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(serviceData),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to create service: ${error.message}`);
      }
      throw new Error('Failed to create service: Unknown error');
    }
  },

  updateService: async (slug: string, serviceData: Partial<Service>): Promise<Service> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/admin/${slug}/update/`;
      
      const response = await fetch(url, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(serviceData),
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to update service: ${error.message}`);
      }
      throw new Error('Failed to update service: Unknown error');
    }
  },

  deleteService: async (slug: string): Promise<void> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/admin/${slug}/delete/`;
      
      const response = await fetch(url, {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to delete service: ${error.message}`);
      }
      throw new Error('Failed to delete service: Unknown error');
    }
  },

  // Upload image for a service
  uploadServiceImage: async (slug: string, imageFile: File): Promise<Service> => {
    try {
      const url = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SERVICES}/admin/${slug}/upload-image/`;
      
      const formData = new FormData();
      formData.append('image', imageFile);
      
      const response = await fetch(url, {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(
          errorData.message || 
          errorData.detail || 
          `HTTP error! status: ${response.status}`
        );
      }

      const result = await response.json();
      return result.service;
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to upload service image: ${error.message}`);
      }
      throw new Error('Failed to upload service image: Unknown error');
    }
  },
};

// Utility functions
export const serviceUtils = {
  // Format price for display
  formatPrice: (price: string | number): string => {
    const numPrice = typeof price === 'string' ? parseFloat(price) : price;
    return new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    }).format(numPrice);
  },

  // Get service image URL with cache-busting
  // Use relative URLs for same-domain images (Next.js can optimize via rewrites)
  // Use absolute URLs only for external images
  // Adds updated_at timestamp as query parameter for cache-busting when images change
  getServiceImageUrl: (service: Service): string => {
    let imageUrl: string = '';
    
    // If service has an uploaded image
    if (service.image && typeof service.image === 'string' && service.image.startsWith('/media/')) {
      imageUrl = service.image;
    }
    // If service has an image_url
    else if (service.image_url) {
      if (service.image_url.startsWith('http')) {
        // External URL - keep as absolute
        imageUrl = service.image_url;
      } else if (service.image_url.startsWith('/media/')) {
        // Same domain media - use relative URL
        imageUrl = service.image_url;
      } else {
        // Other relative URLs
        imageUrl = service.image_url;
      }
    } else {
      // Fallback to default image (relative is fine for public images)
      imageUrl = '/images/service/default.png';
    }
    
    // Add cache-busting query parameter using updated_at timestamp
    // This ensures images refresh when service is updated
    if (service.updated_at && imageUrl && !imageUrl.includes('?')) {
      try {
        const timestamp = new Date(service.updated_at).getTime();
        const separator = imageUrl.includes('?') ? '&' : '?';
        imageUrl = `${imageUrl}${separator}v=${timestamp}`;
      } catch (error) {
        // If date parsing fails, just return the URL without cache-busting
        console.warn('Failed to parse updated_at for cache-busting:', error);
      }
    }
    
    return imageUrl;
  },

  // Generate service slug from title
  generateSlug: (title: string): string => {
    return title
      .toLowerCase()
      .replace(/[^a-z0-9\s-]/g, '')
      .replace(/\s+/g, '-')
      .replace(/-+/g, '-')
      .trim();
  },

  // Check if service is featured
  isFeatured: (service: Service): boolean => {
    return service.featured;
  },

  // Sort services by display order
  sortByDisplayOrder: (services: Service[]): Service[] => {
    return [...services].sort((a, b) => a.display_order - b.display_order);
  },

  // Filter services by category
  filterByCategory: (services: Service[], categorySlug: string): Service[] => {
    return services.filter(service => service.category?.slug === categorySlug);
  },

  // Get services within price range
  filterByPriceRange: (services: Service[], minPrice: number, maxPrice: number): Service[] => {
    return services.filter(service => {
      const price = parseFloat(service.price);
      return price >= minPrice && price <= maxPrice;
    });
  },
};
