/**
 * Scraper Management API
 *
 * Provides endpoints for managing webshop scraping functionality:
 * - Register/unregister shops with scraper
 * - Get shop status and scraped content
 * - Manage custom URLs
 * - Configure webhooks and scheduling
 * - Multi-scraper support with per-store configuration
 */

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.39.3';
import { createScraperClient, validateSameDomain } from '../_shared/scraper-client.ts';

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
  'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS',
};

interface StoreRow {
  id: string;
  store_url: string;
  scraper_api_url: string | null;
  scraper_api_secret: string | null;
  scraper_registered: boolean;
  scraper_enabled: boolean;
  user_id: string;
}

/**
 * Get scraper configuration for a store
 */
async function getStoreScraperConfig(supabase: any, storeId: string, userId: string): Promise<StoreRow> {
  const { data: store, error } = await supabase
    .from('stores')
    .select('id, store_url, scraper_api_url, scraper_api_secret, scraper_registered, scraper_enabled, user_id')
    .eq('id', storeId)
    .eq('user_id', userId)
    .single();

  if (error || !store) {
    throw new Error('Store not found or access denied');
  }

  return store;
}

/**
 * Update store scraper registration status
 */
async function updateStoreScraperStatus(
  supabase: any,
  storeId: string,
  updates: { scraper_registered?: boolean; scraper_enabled?: boolean }
) {
  const { error } = await supabase
    .from('stores')
    .update(updates)
    .eq('id', storeId);

  if (error) {
    throw new Error(`Failed to update store status: ${error.message}`);
  }
}

Deno.serve(async (req) => {
  // Handle CORS preflight requests
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  try {
    // Initialize Supabase client
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
    const supabase = createClient(supabaseUrl, supabaseKey);

    // Get user from authorization header
    const authHeader = req.headers.get('Authorization');
    if (!authHeader) {
      return new Response(
        JSON.stringify({ error: 'Authorization header required' }),
        { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      );
    }

    const { data: { user }, error: authError } = await supabase.auth.getUser(
      authHeader.replace('Bearer ', '')
    );

    if (authError || !user) {
      return new Response(
        JSON.stringify({ error: 'Invalid authorization token' }),
        { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      );
    }

    const url = new URL(req.url);
    const pathParts = url.pathname.split('/').filter(Boolean);

    // Remove 'scraper-management' from path if present (when called via /functions/v1/scraper-management/...)
    const functionName = 'scraper-management';
    if (pathParts.length > 0 && pathParts[0] === functionName) {
      pathParts.shift();
    }

    // Route to different endpoints based on path
    if (pathParts.length < 1) {
      return new Response(
        JSON.stringify({ error: 'Invalid endpoint' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      );
    }

    const action = pathParts[0];

    switch (action) {
      case 'register-shop': {
        // POST /register-shop
        // Register a store with the scraper
        if (req.method !== 'POST') {
          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const { store_id } = await req.json();
        if (!store_id) {
          return new Response(
            JSON.stringify({ error: 'store_id is required' }),
            { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const store = await getStoreScraperConfig(supabase, store_id, user.id);

        if (store.scraper_registered) {
          return new Response(
            JSON.stringify({ success: true, message: 'Store already registered', shop_id: store_id }),
            { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        // Create scraper client with store configuration
        const scraperClient = await createScraperClient({
          scraper_api_url: store.scraper_api_url,
          scraper_api_secret: store.scraper_api_secret,
        });

        // Register shop with scraper using store_id as custom_id
        const job = await scraperClient.registerShop(store.store_url, store.id);

        // Set up webhook
        const frontendUrl = Deno.env.get('FRONTEND_URL');
        const webhookUrl = `${Deno.env.get('SUPABASE_URL')}/functions/v1/scraper-webhook`;

        try {
          await scraperClient.setWebhook(store.id, webhookUrl);
          console.log(`Webhook configured for store ${store.id}`);
        } catch (webhookError) {
          console.warn(`Failed to configure webhook for store ${store.id}:`, webhookError);
          // Continue anyway - webhook is optional
        }

        // Enable scheduled scraping
        try {
          await scraperClient.setScheduling(store.id, true);
          console.log(`Scheduled scraping enabled for store ${store.id}`);
        } catch (scheduleError) {
          console.warn(`Failed to enable scheduling for store ${store.id}:`, scheduleError);
          // Continue anyway
        }

        // Update database
        await updateStoreScraperStatus(supabase, store.id, { scraper_registered: true });

        return new Response(
          JSON.stringify({
            success: true,
            message: 'Store registered with scraper successfully',
            job_id: job.id,
            shop_id: store.id,
          }),
          { status: 201, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
        );
      }

      case 'shop-status': {
        // GET /shop-status?store_id=xxx
        if (req.method !== 'GET') {
          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const storeId = url.searchParams.get('store_id');
        if (!storeId) {
          return new Response(
            JSON.stringify({ error: 'store_id parameter is required' }),
            { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const store = await getStoreScraperConfig(supabase, storeId, user.id);

        if (!store.scraper_registered) {
          return new Response(
            JSON.stringify({
              registered: false,
              enabled: store.scraper_enabled,
              message: 'Store not registered with scraper',
            }),
            { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        // Get shop status from scraper
        const scraperClient = await createScraperClient({
          scraper_api_url: store.scraper_api_url,
          scraper_api_secret: store.scraper_api_secret,
        });

        try {
          const shopData = await scraperClient.getShop(store.id);

          // Transform the scraper API response to match UI expectations
          const transformedData = {
            id: shopData.shop?.id || store.id,
            url: shopData.shop?.url || store.store_url,
            custom_id: shopData.shop?.custom_id,
            status: (shopData.scheduled_jobs && shopData.scheduled_jobs.some((job: any) => job.enabled && job.status !== 'completed'))
              ? 'active' as const
              : 'inactive' as const,
            last_scraped_at: shopData.analytics?.last_scraped_at,
            next_scheduled_scrape: shopData.analytics?.next_scrape_at,
            scheduled_enabled: shopData.scheduled_jobs?.some((job: any) => job.enabled) || false,
            total_urls_found: shopData.analytics?.total_urls_found || 0,
            total_content_items: (
              (shopData.content_metadata?.shipping_informations?.length || 0) +
              (shopData.content_metadata?.contacts?.length || 0) +
              (shopData.content_metadata?.terms_of_conditions?.length || 0) +
              (shopData.content_metadata?.faq?.length || 0)
            ),
            scrape_count: shopData.analytics?.total_scrapes || 0,
            analytics: {
              shipping_count: shopData.content_metadata?.shipping_informations?.length || 0,
              contacts_count: shopData.content_metadata?.contacts?.length || 0,
              terms_count: shopData.content_metadata?.terms_of_conditions?.length || 0,
              faq_count: shopData.content_metadata?.faq?.length || 0,
            },
            created_at: shopData.shop?.created_at,
            updated_at: shopData.shop?.updated_at,
          };

          return new Response(
            JSON.stringify({
              registered: true,
              enabled: store.scraper_enabled,
              shop_data: transformedData,
            }),
            { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        } catch (error) {
          console.error(`Failed to get shop status for ${storeId}:`, error);
          return new Response(
            JSON.stringify({
              registered: true,
              enabled: store.scraper_enabled,
              error: 'Failed to fetch shop data from scraper',
              message: error.message,
            }),
            { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }
      }

      case 'shop-content': {
        // GET /shop-content?store_id=xxx&content_type=faq&limit=50
        if (req.method !== 'GET') {
          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const storeId = url.searchParams.get('store_id');
        if (!storeId) {
          return new Response(
            JSON.stringify({ error: 'store_id parameter is required' }),
            { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const store = await getStoreScraperConfig(supabase, storeId, user.id);

        if (!store.scraper_registered) {
          return new Response(
            JSON.stringify({ error: 'Store not registered with scraper' }),
            { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const scraperClient = await createScraperClient({
          scraper_api_url: store.scraper_api_url,
          scraper_api_secret: store.scraper_api_secret,
        });

        // Build filter from query parameters
        const filter: any = {};
        const contentType = url.searchParams.get('content_type');
        const dateFrom = url.searchParams.get('date_from');
        const dateTo = url.searchParams.get('date_to');
        const limit = url.searchParams.get('limit');

        if (contentType) filter.content_type = contentType;
        if (dateFrom) filter.date_from = dateFrom;
        if (dateTo) filter.date_to = dateTo;
        if (limit) filter.limit = parseInt(limit, 10);

        const rawContent = await scraperClient.getShopContent(store.id, filter);

        // Transform the scraper API response to match UI expectations
        const contentArray: any[] = [];
        const results = rawContent.results || {};

        // Helper function to transform content items
        const transformContentItems = (items: any[], type: string) => {
          return (items || []).map((item: any, index: number) => ({
            id: `${type}-${index}-${item.url}`,
            url: item.url,
            content_type: type,
            title: item.url.split('/').pop()?.replace(/-/g, ' ') || type,
            content: item.content || '',
            scraped_at: item.last_updated || new Date().toISOString(),
            metadata: {
              changed: item.changed,
              last_updated: item.last_updated,
            },
          }));
        };

        // Map content type names from API to UI format
        if (results.shipping_informations) {
          contentArray.push(...transformContentItems(results.shipping_informations, 'shipping'));
        }
        if (results.contacts) {
          contentArray.push(...transformContentItems(results.contacts, 'contacts'));
        }
        if (results.terms_of_conditions) {
          contentArray.push(...transformContentItems(results.terms_of_conditions, 'terms'));
        }
        if (results.faq) {
          contentArray.push(...transformContentItems(results.faq, 'faq'));
        }

        return new Response(
          JSON.stringify({ content: contentArray }),
          { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
        );
      }

      case 'custom-urls': {
        // Handle GET and POST for listing/adding custom URLs
        if (pathParts.length === 1) {
          const storeId = url.searchParams.get('store_id') || (await req.json())?.store_id;
          if (!storeId) {
            return new Response(
              JSON.stringify({ error: 'store_id is required' }),
              { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          const store = await getStoreScraperConfig(supabase, storeId, user.id);

          if (!store.scraper_registered) {
            return new Response(
              JSON.stringify({ error: 'Store not registered with scraper' }),
              { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          const scraperClient = await createScraperClient({
            scraper_api_url: store.scraper_api_url,
            scraper_api_secret: store.scraper_api_secret,
          });

          if (req.method === 'GET') {
            // List custom URLs
            const customUrls = await scraperClient.listCustomUrls(store.id);
            return new Response(
              JSON.stringify(customUrls),
              { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );

          } else if (req.method === 'POST') {
            // Add custom URL
            const { url: customUrl, content_type } = await req.json();

            if (!customUrl || !content_type) {
              return new Response(
                JSON.stringify({ error: 'url and content_type are required' }),
                { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
              );
            }

            // Validate same domain
            if (!validateSameDomain(store.store_url, customUrl)) {
              return new Response(
                JSON.stringify({ error: 'Custom URL must be from the same domain as the store' }),
                { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
              );
            }

            const result = await scraperClient.addCustomUrl(store.id, customUrl, content_type);

            return new Response(
              JSON.stringify(result),
              { status: 201, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        // Handle PATCH /custom-urls/:customUrlId/toggle and DELETE /custom-urls/:customUrlId
        if (pathParts.length >= 2) {
          const customUrlId = pathParts[1];
          const subAction = pathParts[2]; // 'toggle' or undefined

          const { store_id, enabled } = await req.json().catch(() => ({ store_id: null, enabled: null }));

          if (!store_id) {
            return new Response(
              JSON.stringify({ error: 'store_id is required' }),
              { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          const store = await getStoreScraperConfig(supabase, store_id, user.id);

          if (!store.scraper_registered) {
            return new Response(
              JSON.stringify({ error: 'Store not registered with scraper' }),
              { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          const scraperClient = await createScraperClient({
            scraper_api_url: store.scraper_api_url,
            scraper_api_secret: store.scraper_api_secret,
          });

          if (req.method === 'PATCH' && subAction === 'toggle') {
            // Toggle custom URL enabled status
            if (typeof enabled !== 'boolean') {
              return new Response(
                JSON.stringify({ error: 'enabled (boolean) is required' }),
                { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
              );
            }

            await scraperClient.setCustomUrlEnabled(store.id, customUrlId, enabled);

            return new Response(
              JSON.stringify({ success: true, message: `Custom URL ${enabled ? 'enabled' : 'disabled'}` }),
              { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );

          } else if (req.method === 'DELETE') {
            // Delete custom URL
            await scraperClient.deleteCustomUrl(store.id, customUrlId);

            return new Response(
              JSON.stringify({ success: true, message: 'Custom URL deleted successfully' }),
              { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
            );
          }

          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        break;
      }

      case 'scheduling': {
        // PATCH /scheduling
        if (req.method !== 'PATCH') {
          return new Response(
            JSON.stringify({ error: 'Method not allowed' }),
            { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const { store_id, enabled } = await req.json();

        if (!store_id || typeof enabled !== 'boolean') {
          return new Response(
            JSON.stringify({ error: 'store_id and enabled (boolean) are required' }),
            { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const store = await getStoreScraperConfig(supabase, store_id, user.id);

        if (!store.scraper_registered) {
          return new Response(
            JSON.stringify({ error: 'Store not registered with scraper' }),
            { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
          );
        }

        const scraperClient = await createScraperClient({
          scraper_api_url: store.scraper_api_url,
          scraper_api_secret: store.scraper_api_secret,
        });

        await scraperClient.setScheduling(store.id, enabled);

        return new Response(
          JSON.stringify({ success: true, message: `Scheduling ${enabled ? 'enabled' : 'disabled'}` }),
          { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
        );
      }

      default:
        return new Response(
          JSON.stringify({ error: 'Unknown endpoint' }),
          { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
        );
    }

  } catch (error) {
    console.error('Error in scraper management API:', error);

    return new Response(
      JSON.stringify({
        error: 'Internal server error',
        message: error instanceof Error ? error.message : 'Unknown error',
      }),
      {
        status: 500,
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      }
    );
  }
});