/**
 * Webshop Scraper API Client
 *
 * Handles communication with the webshop scraper service including:
 * - Shop registration and management
 * - Content retrieval and filtering
 * - Custom URL management
 * - Webhook configuration
 * - Multi-scraper support with per-store configuration
 */

export interface ScraperConfig {
  apiUrl: string;
  apiSecret: string;
}

export interface ScraperJob {
  id: string;
  status: 'pending' | 'in_progress' | 'completed' | 'failed';
  url: string;
  custom_id?: string;
  created_at: string;
  updated_at: string;
  error?: string;
}

export interface ScraperShop {
  id: string;
  url: string;
  custom_id?: string;
  status: 'active' | 'inactive';
  last_scraped_at?: string;
  next_scheduled_scrape?: string;
  scheduled_enabled: boolean;
  total_urls_found: number;
  total_content_items: number;
  created_at: string;
  updated_at: string;
}

export interface ScraperContent {
  id: string;
  url: string;
  content_type: 'shipping' | 'contacts' | 'terms' | 'faq';
  title?: string;
  content: string;
  scraped_at: string;
  metadata?: Record<string, any>;
}

export interface ScraperCustomUrl {
  id: string;
  url: string;
  content_type: 'shipping' | 'contacts' | 'terms' | 'faq';
  enabled: boolean;
  created_at: string;
  last_scraped_at?: string;
  status?: 'pending' | 'completed' | 'failed';
}

export interface ScraperWebhook {
  id: string;
  url: string;
  secret?: string;
  enabled: boolean;
  created_at: string;
  last_delivery_at?: string;
  total_deliveries: number;
  failed_deliveries: number;
}

export interface ContentFilter {
  content_type?: 'shipping' | 'contacts' | 'terms' | 'faq';
  date_from?: string;
  date_to?: string;
  limit?: number;
}

/**
 * Scraper API Client
 */
export class ScraperClient {
  private config: ScraperConfig;

  constructor(config: ScraperConfig) {
    this.config = config;
  }

  /**
   * Get authentication headers for API requests
   */
  private getAuthHeaders(): Record<string, string> {
    return {
      'Authorization': `Bearer ${this.config.apiSecret}`,
      'Content-Type': 'application/json',
    };
  }

  /**
   * Make authenticated API request
   */
  private async makeRequest<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.config.apiUrl}${endpoint}`;

    const response = await fetch(url, {
      ...options,
      headers: {
        ...this.getAuthHeaders(),
        ...options.headers,
      },
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Scraper API error (${response.status}): ${errorText}`);
    }

    const contentType = response.headers.get('content-type');
    if (contentType && contentType.includes('application/json')) {
      return await response.json();
    }

    return response.text() as T;
  }

  /**
   * Register a new shop for scraping
   */
  async registerShop(url: string, customId: string): Promise<ScraperJob> {
    return await this.makeRequest<ScraperJob>('/jobs', {
      method: 'POST',
      body: JSON.stringify({
        url,
        custom_id: customId,
      }),
    });
  }

  /**
   * Get job status by job ID
   */
  async getJobStatus(jobId: string): Promise<ScraperJob> {
    return await this.makeRequest<ScraperJob>(`/jobs/${jobId}`);
  }

  /**
   * List all jobs
   */
  async listJobs(): Promise<{ jobs: ScraperJob[], queue_stats: any }> {
    return await this.makeRequest<{ jobs: ScraperJob[], queue_stats: any }>('/jobs');
  }

  /**
   * Get shop information by shop ID (using store_id as custom_id)
   */
  async getShop(shopId: string): Promise<ScraperShop> {
    return await this.makeRequest<ScraperShop>(`/shops/${shopId}`);
  }

  /**
   * List all shops
   */
  async listShops(): Promise<{ shops: ScraperShop[] }> {
    return await this.makeRequest<{ shops: ScraperShop[] }>('/shops');
  }

  /**
   * Get scraped content for a shop with optional filtering
   */
  async getShopContent(shopId: string, filter?: ContentFilter): Promise<{ content: ScraperContent[] }> {
    const params = new URLSearchParams();

    if (filter?.content_type) {
      params.append('content_type', filter.content_type);
    }
    if (filter?.date_from) {
      params.append('date_from', filter.date_from);
    }
    if (filter?.date_to) {
      params.append('date_to', filter.date_to);
    }
    if (filter?.limit) {
      params.append('limit', filter.limit.toString());
    }

    const endpoint = `/shops/${shopId}/results${params.toString() ? `?${params.toString()}` : ''}`;
    return await this.makeRequest<{ content: ScraperContent[] }>(endpoint);
  }

  /**
   * Enable or disable scheduled scraping for a shop
   */
  async setScheduling(shopId: string, enabled: boolean): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/schedule`, {
      method: 'PATCH',
      body: JSON.stringify({ enabled }),
    });
  }

  /**
   * Set or update custom ID for a shop
   */
  async setCustomId(shopId: string, customId: string | null): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/custom-id`, {
      method: 'PATCH',
      body: JSON.stringify({ custom_id: customId }),
    });
  }

  /**
   * Delete a shop and all its data
   */
  async deleteShop(shopId: string): Promise<void> {
    await this.makeRequest(`/shops/${shopId}`, {
      method: 'DELETE',
    });
  }

  /**
   * Configure webhook for a shop
   */
  async setWebhook(shopId: string, webhookUrl: string, secret?: string): Promise<ScraperWebhook> {
    return await this.makeRequest<ScraperWebhook>(`/shops/${shopId}/webhooks`, {
      method: 'POST',
      body: JSON.stringify({
        url: webhookUrl,
        secret,
      }),
    });
  }

  /**
   * Get webhook configuration for a shop
   */
  async getWebhook(shopId: string): Promise<ScraperWebhook> {
    return await this.makeRequest<ScraperWebhook>(`/shops/${shopId}/webhooks`);
  }

  /**
   * Enable or disable webhook for a shop
   */
  async setWebhookEnabled(shopId: string, enabled: boolean): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/webhooks`, {
      method: 'PATCH',
      body: JSON.stringify({ enabled }),
    });
  }

  /**
   * Delete webhook for a shop
   */
  async deleteWebhook(shopId: string): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/webhooks`, {
      method: 'DELETE',
    });
  }

  /**
   * Add a custom URL to scrape for a shop
   */
  async addCustomUrl(shopId: string, url: string, contentType: ScraperCustomUrl['content_type']): Promise<ScraperCustomUrl> {
    return await this.makeRequest<ScraperCustomUrl>(`/shops/${shopId}/custom-urls`, {
      method: 'POST',
      body: JSON.stringify({
        url,
        content_type: contentType,
      }),
    });
  }

  /**
   * List all custom URLs for a shop
   */
  async listCustomUrls(shopId: string): Promise<{ custom_urls: ScraperCustomUrl[] }> {
    return await this.makeRequest<{ custom_urls: ScraperCustomUrl[] }>(`/shops/${shopId}/custom-urls`);
  }

  /**
   * Enable or disable a custom URL
   */
  async setCustomUrlEnabled(shopId: string, customUrlId: string, enabled: boolean): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/custom-urls/${customUrlId}`, {
      method: 'PATCH',
      body: JSON.stringify({ enabled }),
    });
  }

  /**
   * Delete a custom URL
   */
  async deleteCustomUrl(shopId: string, customUrlId: string): Promise<void> {
    await this.makeRequest(`/shops/${shopId}/custom-urls/${customUrlId}`, {
      method: 'DELETE',
    });
  }
}

/**
 * Create a scraper client with configuration resolution
 * Supports per-store configuration with fallback to global defaults
 */
export async function createScraperClient(storeConfig?: {
  scraper_api_url?: string;
  scraper_api_secret?: string;
}): Promise<ScraperClient> {
  // Use store-specific configuration if available
  if (storeConfig?.scraper_api_url && storeConfig?.scraper_api_secret) {
    return new ScraperClient({
      apiUrl: storeConfig.scraper_api_url,
      apiSecret: storeConfig.scraper_api_secret,
    });
  }

  // Fall back to global configuration from environment
  const apiUrl = Deno.env.get('DEFAULT_SCRAPER_API_URL');
  const apiSecret = Deno.env.get('DEFAULT_SCRAPER_API_SECRET');

  if (!apiUrl || !apiSecret) {
    throw new Error('Scraper API configuration not found. Please set DEFAULT_SCRAPER_API_URL and DEFAULT_SCRAPER_API_SECRET environment variables or configure per-store settings.');
  }

  return new ScraperClient({
    apiUrl,
    apiSecret,
  });
}

/**
 * Utility function to validate if a URL belongs to the same domain as the store
 */
export function validateSameDomain(storeUrl: string, customUrl: string): boolean {
  try {
    const storeDomain = new URL(storeUrl).hostname.toLowerCase();
    const customDomain = new URL(customUrl).hostname.toLowerCase();

    // Allow exact matches and subdomains
    return customDomain === storeDomain || customDomain.endsWith(`.${storeDomain}`);
  } catch (error) {
    return false; // Invalid URLs
  }
}