import { logger } from '@/lib/logger';
import { useState, useCallback, useRef, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { useUpdateModules, useModules, type ModulesSettings, defaultModulesSettings } from '@/hooks/useModules';
import { useCreatePage } from '@/hooks/usePages';
import { useUpdateGeneralSettings } from '@/hooks/useSiteSettings';
import { useUpdateFooterBlock } from '@/hooks/useGlobalBlocks';
import { toast } from 'sonner';
import type { ContentBlock, ContentBlockType } from '@/types/cms';
import { extractImageUrls, updateBlockAtPath, isExternalUrl } from '@/lib/image-extraction';

// Block-to-Module mapping for auto-enabling modules
const BLOCK_MODULE_MAP: Record<string, keyof ModulesSettings> = {
  // Booking
  'booking': 'bookings',
  'smart-booking': 'bookings',
  
  // Blog
  'article-grid': 'blog',
  
  // Knowledge Base
  'kb-hub': 'knowledgeBase',
  'kb-featured': 'knowledgeBase',
  'kb-search': 'knowledgeBase',
  'kb-accordion': 'knowledgeBase',
  
  // Communication
  'chat': 'chat',
  'newsletter': 'newsletter',
  
  // E-commerce
  'products': 'ecommerce',
  'cart': 'ecommerce',
  'pricing': 'ecommerce',
  'comparison': 'ecommerce',
  
  // Forms
  'form': 'forms',
  'contact': 'forms',
};

export interface CopilotMessage {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  createdAt: Date;
  toolCall?: {
    name: string;
    arguments: Record<string, unknown>;
  };
}

// Site Discovery Types - Updated for Firecrawl Map integration
export interface DiscoveredPage {
  url: string;
  path: string;
  slug: string;
  suggestedName: string;
  suggestedType: 'page' | 'blog' | 'kb' | 'skip';
  selected: boolean;
  isDuplicate?: boolean;
  // Legacy fields for compatibility
  title?: string;
  type?: 'page' | 'blog' | 'kb';
  source?: 'navigation' | 'sitemap' | 'link' | 'firecrawl-map';
  status?: 'pending' | 'migrating' | 'completed' | 'skipped';
}

export interface SiteStructure {
  siteName: string;
  platform: string;
  baseUrl: string;
  pages: DiscoveredPage[];
  navigation: string[];
  hasBlog: boolean;
  hasKnowledgeBase: boolean;
  stats?: {
    total: number;
    pages: number;
    blog: number;
    kb: number;
    skip: number;
    selected: number;
  };
}

export type DiscoveryStatus = 'idle' | 'analyzing' | 'selecting' | 'ready' | 'migrating' | 'complete';

export interface CopilotBlock {
  id: string;
  type: string;
  data: Record<string, unknown>;
  status: 'pending' | 'approved' | 'rejected';
  sourceUrl?: string; // For migrated blocks
}

export type MigrationPhase = 'idle' | 'pages' | 'blog' | 'knowledgeBase' | 'complete';

export interface MigrationState {
  sourceUrl: string | null;
  baseDomain: string | null;
  detectedPlatform: string | null;
  pendingBlocks: CopilotBlock[];
  currentBlockIndex: number;
  migratedPages: string[];
  discoveredLinks: string[];
  isActive: boolean;
  pageTitle: string | null;
  pageSlug: string | null; // Clean slug from discovered page URL
  // Full site migration phases
  phase: MigrationPhase;
  pagesCompleted: number;
  pagesTotal: number;
  blogPostsDiscovered: number;
  blogPostsMigrated: number;
  kbArticlesDiscovered: number;
  kbArticlesMigrated: number;
  // Detected content
  hasBlog: boolean;
  hasKnowledgeBase: boolean;
  blogUrls: string[];
  kbUrls: string[];
  // New site discovery
  siteStructure: SiteStructure | null;
  discoveryStatus: DiscoveryStatus;
  currentPageUrl: string | null;
}

interface UseCopilotReturn {
  messages: CopilotMessage[];
  blocks: CopilotBlock[];
  isLoading: boolean;
  error: string | null;
  isAutoContinue: boolean;
  migrationState: MigrationState;
  sendMessage: (content: string) => Promise<void>;
  approveBlock: (blockId: string) => Promise<void>;
  rejectBlock: (blockId: string) => void;
  regenerateBlock: (blockId: string, feedback?: string) => Promise<void>;
  cancelRequest: () => void;
  clearConversation: () => void;
  stopAutoContinue: () => void;
  approvedBlocks: CopilotBlock[];
  // Site discovery with Firecrawl Map
  discoverPages: (url: string) => Promise<void>;
  updateDiscoveredPages: (pages: DiscoveredPage[]) => void;
  confirmPageSelection: () => Promise<void>;
  cancelPageSelection: () => void;
  // Legacy site discovery
  analyzeSite: (url: string) => Promise<void>;
  selectPageForMigration: (url: string) => void;
  togglePageSelection: (url: string) => void;
  migrateSelectedPages: () => Promise<void>;
  // Migration functions
  startMigration: (url: string) => Promise<void>;
  approveMigrationBlock: () => void;
  skipMigrationBlock: () => void;
  editMigrationBlock: (feedback: string) => void;
  migrateNextPage: (url: string) => Promise<void>;
  // Phase control
  startBlogMigration: () => Promise<void>;
  startKbMigration: () => Promise<void>;
  skipPhase: () => void;
}

const initialMigrationState: MigrationState = {
  sourceUrl: null,
  baseDomain: null,
  detectedPlatform: null,
  pendingBlocks: [],
  currentBlockIndex: 0,
  migratedPages: [],
  discoveredLinks: [],
  isActive: false,
  pageTitle: null,
  pageSlug: null,
  phase: 'idle',
  pagesCompleted: 0,
  pagesTotal: 0,
  blogPostsDiscovered: 0,
  blogPostsMigrated: 0,
  kbArticlesDiscovered: 0,
  kbArticlesMigrated: 0,
  hasBlog: false,
  hasKnowledgeBase: false,
  blogUrls: [],
  kbUrls: [],
  // New site discovery
  siteStructure: null,
  discoveryStatus: 'idle',
  currentPageUrl: null,
};

// LocalStorage keys for persistence
const STORAGE_KEYS = {
  messages: 'copilot_messages',
  blocks: 'copilot_blocks',
  migrationState: 'copilot_migration_state',
} as const;

// Helper to load persisted state
function loadPersistedState<T>(key: string, defaultValue: T): T {
  try {
    const stored = localStorage.getItem(key);
    if (stored) {
      const parsed = JSON.parse(stored);
      // Restore Date objects for messages
      if (key === STORAGE_KEYS.messages && Array.isArray(parsed)) {
        return parsed.map((m: CopilotMessage) => ({
          ...m,
          createdAt: new Date(m.createdAt),
        })) as T;
      }
      return parsed;
    }
  } catch (e) {
    logger.warn(`Failed to load ${key} from localStorage:`, e);
  }
  return defaultValue;
}

// Helper to save state to localStorage
function persistState<T>(key: string, value: T): void {
  try {
    localStorage.setItem(key, JSON.stringify(value));
  } catch (e) {
    logger.warn(`Failed to save ${key} to localStorage:`, e);
  }
}

export function useCopilot(): UseCopilotReturn {
  // Initialize state from localStorage if available
  const [messages, setMessages] = useState<CopilotMessage[]>(() => 
    loadPersistedState(STORAGE_KEYS.messages, [])
  );
  const [blocks, setBlocks] = useState<CopilotBlock[]>(() => 
    loadPersistedState(STORAGE_KEYS.blocks, [])
  );
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isAutoContinue, setIsAutoContinue] = useState(false);
  const [migrationState, setMigrationState] = useState<MigrationState>(() => 
    loadPersistedState(STORAGE_KEYS.migrationState, initialMigrationState)
  );
  const [enabledModulesCache, setEnabledModulesCache] = useState<Set<string>>(new Set());
  
  const abortControllerRef = useRef<AbortController | null>(null);
  const updateModules = useUpdateModules();
  const { data: currentModules } = useModules();
  const createPageMutation = useCreatePage();
  const updateGeneralSettings = useUpdateGeneralSettings();
  const updateFooterBlock = useUpdateFooterBlock();

  // Persist state changes to localStorage
  useEffect(() => {
    persistState(STORAGE_KEYS.messages, messages);
  }, [messages]);

  useEffect(() => {
    persistState(STORAGE_KEYS.blocks, blocks);
  }, [blocks]);

  useEffect(() => {
    persistState(STORAGE_KEYS.migrationState, migrationState);
  }, [migrationState]);

  // Helper to auto-enable a module silently
  const autoEnableModule = useCallback(async (moduleId: keyof ModulesSettings) => {
    if (!currentModules) return;
    
    const moduleConfig = currentModules[moduleId];
    if (!moduleConfig || moduleConfig.enabled || moduleConfig.core) return;
    
    // Prevent duplicate toasts using cache
    if (enabledModulesCache.has(moduleId)) return;
    
    try {
      const updated = { ...currentModules };
      updated[moduleId] = { ...moduleConfig, enabled: true };
      await updateModules.mutateAsync(updated);
      
      setEnabledModulesCache(prev => new Set(prev).add(moduleId));
      
      // Educational toast
      toast.success(`${moduleConfig.name} enabled`, {
        description: moduleConfig.description,
        duration: 4000,
      });
    } catch (err) {
      logger.error('Failed to auto-enable module:', moduleId, err);
    }
  }, [currentModules, updateModules, enabledModulesCache]);

  // Auto-enable modules for a block type
  const autoEnableModuleForBlock = useCallback(async (blockType: string) => {
    const requiredModule = BLOCK_MODULE_MAP[blockType];
    if (requiredModule) {
      await autoEnableModule(requiredModule);
    }
  }, [autoEnableModule]);

  const generateId = () => Math.random().toString(36).substring(2, 15);

  // Extract internal links from a URL
  const extractInternalLinks = (html: string, baseUrl: string): string[] => {
    try {
      const base = new URL(baseUrl);
      const links: string[] = [];
      const regex = /href=["']([^"']+)["']/g;
      let match;
      while ((match = regex.exec(html)) !== null) {
        try {
          const url = new URL(match[1], baseUrl);
          if (url.hostname === base.hostname && 
              !url.pathname.includes('#') &&
              !links.includes(url.pathname) &&
              url.pathname !== '/' &&
              url.pathname !== base.pathname) {
            links.push(url.pathname);
          }
        } catch {
          // Invalid URL, skip
        }
      }
      return links.slice(0, 10); // Limit to 10 links
    } catch {
      return [];
    }
  };

  // Detect modules based on platform
  const detectModulesFromPlatform = (platform: string): (keyof ModulesSettings)[] => {
    const platformModules: Record<string, (keyof ModulesSettings)[]> = {
      wordpress: ['blog', 'forms', 'newsletter'],
      woocommerce: ['ecommerce', 'blog', 'newsletter'],
      shopify: ['ecommerce', 'newsletter'],
      wix: ['forms', 'bookings', 'blog'],
      squarespace: ['blog', 'newsletter', 'forms'],
    };
    return platformModules[platform.toLowerCase()] || ['forms', 'newsletter'];
  };

  const startMigration = useCallback(async (url: string) => {
    setIsLoading(true);
    setError(null);

    // Add assistant message about starting migration
    const startMessage: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `🔍 Analyzing ${url}... I'll scan the page and prepare your content for migration.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, startMessage]);

    try {
      const { data, error: fnError } = await supabase.functions.invoke('migrate-page', {
        body: { url },
      });

      if (fnError) throw new Error(fnError.message);
      if (!data?.success) throw new Error(data?.error || 'Migration failed');

      const migratedBlocks: CopilotBlock[] = (data.blocks || []).map((block: { id?: string; type: string; data: Record<string, unknown> }) => ({
        id: block.id || generateId(),
        type: block.type,
        data: block.data,
        status: 'pending' as const,
        sourceUrl: url,
      }));

      // Extract discovered links from metadata if available
      const discoveredLinks: string[] = data.metadata?.internalLinks || [];
      
      // Detect blog and KB presence
      const hasBlog = data.metadata?.hasBlog || discoveredLinks.some(l => /blog|news|articles?|posts?/i.test(l));
      const hasKnowledgeBase = data.metadata?.hasKnowledgeBase || discoveredLinks.some(l => /help|faq|support|kb|knowledge/i.test(l));
      const blogUrls = discoveredLinks.filter(l => /blog|news|articles?|posts?/i.test(l));
      const kbUrls = discoveredLinks.filter(l => /help|faq|support|kb|knowledge/i.test(l));
      const pageUrls = discoveredLinks.filter(l => !blogUrls.includes(l) && !kbUrls.includes(l));
      
      // Extract base domain
      let baseDomain = null;
      try {
        baseDomain = new URL(url).origin;
      } catch {}

      // Get slug from discovered page if available, otherwise generate from URL path
      const discoveredPage = migrationState.siteStructure?.pages.find(p => p.url === url);
      let pageSlug = discoveredPage?.slug;
      if (!pageSlug) {
        // Fallback: generate slug from URL path
        try {
          const path = new URL(url).pathname;
          const segments = path.split('/').filter(Boolean);
          const lastSegment = segments[segments.length - 1] || 'home';
          pageSlug = lastSegment
            .replace(/\.(html|php|aspx?)$/i, '')
            .toLowerCase()
            .replace(/[^a-z0-9-]/g, '-')
            .replace(/-+/g, '-')
            .replace(/^-|-$/g, '') || 'home';
        } catch {
          pageSlug = 'page';
        }
      }

      setMigrationState(prev => ({
        ...prev,
        sourceUrl: url,
        baseDomain,
        detectedPlatform: data.metadata?.platform || 'unknown',
        pendingBlocks: migratedBlocks,
        currentBlockIndex: 0,
        migratedPages: [url],
        discoveredLinks: pageUrls,
        isActive: true,
        pageTitle: data.title || 'Untitled Page',
        pageSlug, // Use clean slug from URL, not from title
        phase: 'pages',
        pagesCompleted: 1,
        pagesTotal: pageUrls.length + 1,
        blogPostsDiscovered: blogUrls.length,
        blogPostsMigrated: 0,
        kbArticlesDiscovered: kbUrls.length,
        kbArticlesMigrated: 0,
        hasBlog,
        hasKnowledgeBase,
        blogUrls,
        kbUrls,
        currentPageUrl: url,
      }));

      // Notify about company profile extraction
      if (data.companyProfile) {
        toast.success('Company profile extracted and saved', {
          description: 'Your company data has been auto-filled from the website',
          duration: 5000,
        });
      }

      // Add success message with first block preview
      const successMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `✨ Found ${migratedBlocks.length} sections on "${data.title || 'the page'}"${data.metadata?.platform ? ` (${data.metadata.platform})` : ''}!${data.companyProfile ? '\n\n📋 Company profile auto-extracted and saved to Settings.' : ''}\n\nLet me show you each section one at a time. You can approve, edit, or skip each one.`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, successMessage]);

      // Auto-enable modules based on detected platform
      if (data.metadata?.platform) {
        const suggestedModules = detectModulesFromPlatform(data.metadata.platform);
        for (const moduleId of suggestedModules) {
          await autoEnableModule(moduleId);
        }
      }

    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to analyze URL';
      setError(message);
      toast.error(message);
      
      const errorMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `❌ I couldn't analyze that URL. ${message}\n\nPlease check that:\n• The URL is correct and accessible\n• The site isn't password protected\n• You've included https://`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsLoading(false);
    }
  }, []);

  // Helper: Update page status in siteStructure
  const updatePageStatusInStructure = useCallback((url: string, status: 'pending' | 'migrating' | 'completed' | 'skipped') => {
    setMigrationState(prev => {
      if (!prev.siteStructure) return prev;
      return {
        ...prev,
        siteStructure: {
          ...prev.siteStructure,
          pages: prev.siteStructure.pages.map(p =>
            p.url === url || p.url === prev.currentPageUrl ? { ...p, status } : p
          ),
        },
      };
    });
  }, []);

  // Helper: Find next pending page from selected pages
  const findNextPendingPage = useCallback(() => {
    if (!migrationState.siteStructure) return null;
    
    // Find pages that are selected and still pending (not yet migrated)
    const pendingPages = migrationState.siteStructure.pages.filter(p => {
      const isSelected = p.selected !== false; // Include if selected or undefined
      const isPending = p.status === 'pending' || p.status === undefined;
      const isPage = p.suggestedType === 'page' || p.type === 'page';
      const notCurrentPage = p.url !== migrationState.currentPageUrl;
      return isSelected && isPending && isPage && notCurrentPage;
    });
    
    logger.log('[Copilot] findNextPendingPage - found:', pendingPages.length, 'pending pages');
    return pendingPages[0] || null;
  }, [migrationState.siteStructure, migrationState.currentPageUrl]);

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

  const approveMigrationBlock = useCallback(async () => {
    if (!migrationState.isActive || migrationState.pendingBlocks.length === 0) return;

    const currentBlock = migrationState.pendingBlocks[migrationState.currentBlockIndex];
    if (!currentBlock) return;

    // Add to approved blocks
    const updatedBlocks = [...blocks, { ...currentBlock, status: 'approved' as const }];
    setBlocks(updatedBlocks);

    // Move to next block
    const nextIndex = migrationState.currentBlockIndex + 1;
    
    if (nextIndex >= migrationState.pendingBlocks.length) {
      // All blocks reviewed - AUTO-SAVE and CONTINUE
      setMigrationState(prev => ({ ...prev, currentBlockIndex: nextIndex }));
      
      const approvedBlocks = updatedBlocks.filter(b => b.status === 'approved');
      
      if (approvedBlocks.length > 0) {
        const pageTitle = migrationState.pageTitle || 'Imported Page';
        // Use clean slug from URL path (stored in migrationState), not generated from title
        const pageSlug = migrationState.pageSlug || generateSlug(pageTitle);
        
        // Get pagesTotal from siteStructure (count of selected pages)
        const pagesTotal = migrationState.siteStructure?.pages.filter(p => p.selected !== false).length || migrationState.pagesTotal || 1;
        
        try {
          // Auto-save page - show_in_menu: false by default, user can enable manually
          await createPageMutation.mutateAsync({
            title: pageTitle,
            slug: pageSlug,
            content: approvedBlocks.map(b => ({ 
              id: b.id, 
              type: b.type as ContentBlockType, 
              data: b.data 
            })) as ContentBlock[],
            status: 'draft',
            show_in_menu: false, // Don't auto-add to menu
          });
          
          // Check if this is the homepage (source URL ends with "/" or is the base domain)
          const currentUrl = migrationState.currentPageUrl;
          const isHomepage = currentUrl && (
            currentUrl === migrationState.baseDomain ||
            currentUrl === migrationState.baseDomain + '/' ||
            new URL(currentUrl).pathname === '/'
          );
          
          // If this is the homepage, automatically set it as the site's homepage
          if (isHomepage) {
            try {
              await updateGeneralSettings.mutateAsync({ homepageSlug: pageSlug });
              logger.log('[Copilot] Set homepage slug to:', pageSlug);
            } catch (err) {
              logger.warn('[Copilot] Failed to set homepage slug:', err);
            }
          }
          
          // Mark current page as completed and find next pending page atomically
          
          // Calculate next page from current state (before React batches updates)
          let nextPendingPage: DiscoveredPage | null = null;
          if (migrationState.siteStructure) {
            const pendingPages = migrationState.siteStructure.pages.filter(p => {
              const isSelected = p.selected !== false;
              const isPending = p.status === 'pending' || p.status === undefined;
              const isPage = p.suggestedType === 'page' || p.type === 'page';
              const notCurrentPage = p.url !== currentUrl;
              return isSelected && isPending && isPage && notCurrentPage;
            });
            nextPendingPage = pendingPages[0] || null;
            logger.log('[Copilot] After save - pending pages remaining:', pendingPages.length);
          }
          
          // Update state: mark current as completed
          if (currentUrl) {
            updatePageStatusInStructure(currentUrl, 'completed');
          }
          
          // Clear blocks for next page
          setBlocks([]);
          
          // Calculate completed pages count: pages already marked completed + current page
          const alreadyCompletedCount = migrationState.siteStructure?.pages.filter(
            p => p.status === 'completed'
          ).length || 0;
          // Add 1 for current page which we just completed
          const newPagesCompleted = alreadyCompletedCount + 1;
          
          setMigrationState(prev => ({ ...prev, pagesCompleted: newPagesCompleted }));
          
          if (nextPendingPage) {
            // Auto-continue to next page
            const continueMessage: CopilotMessage = {
              id: generateId(),
              role: 'assistant',
              content: `✅ **${pageTitle}** saved! (${newPagesCompleted}/${pagesTotal})\n\n➡️ Moving to: **${nextPendingPage.suggestedName || nextPendingPage.title || 'next page'}**...`,
              createdAt: new Date(),
            };
            setMessages(prev => [...prev, continueMessage]);
            
            // Start next page migration after short delay
            const fullUrl = nextPendingPage.url.startsWith('http') 
              ? nextPendingPage.url 
              : `${migrationState.baseDomain}${nextPendingPage.url}`;
            
            setTimeout(() => startMigration(fullUrl), 800);
          } else {
            // All pages done - check for blog/kb
            const hasBlog = migrationState.hasBlog && migrationState.blogUrls.length > 0;
            const hasKb = migrationState.hasKnowledgeBase && migrationState.kbUrls.length > 0;
            
            let completeContent = `🎉 **All ${newPagesCompleted} pages migrated!**\n\n`;
            
            if (hasBlog) {
              completeContent += `📝 Found ${migrationState.blogUrls.length} blog posts. Say "yes" or "migrate blog" to continue.\n\n`;
            }
            if (hasKb) {
              completeContent += `📚 Found ${migrationState.kbUrls.length} knowledge base articles. Say "migrate kb" to continue.\n\n`;
            }
            if (!hasBlog && !hasKb) {
              completeContent += `Your site migration is complete! All pages have been saved as drafts.`;
            }
            
            const completeMessage: CopilotMessage = {
              id: generateId(),
              role: 'assistant',
              content: completeContent,
              createdAt: new Date(),
            };
            setMessages(prev => [...prev, completeMessage]);
            setMigrationState(prev => ({ ...prev, discoveryStatus: 'complete', phase: 'complete' }));
          }
        } catch (err) {
          logger.error('Failed to save page:', err);
          toast.error('Failed to save page');
          
          const errorMessage: CopilotMessage = {
            id: generateId(),
            role: 'assistant',
            content: `❌ Failed to save "${pageTitle}". You can try again or skip to the next page.`,
            createdAt: new Date(),
          };
          setMessages(prev => [...prev, errorMessage]);
        }
      }
    } else {
      setMigrationState(prev => ({ ...prev, currentBlockIndex: nextIndex }));
      
      const progressMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `✓ Added! Here's section ${nextIndex + 1} of ${migrationState.pendingBlocks.length}...`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, progressMessage]);
    }

    toast.success('Block added');
  }, [migrationState, blocks, createPageMutation, updatePageStatusInStructure, findNextPendingPage, startMigration]);

  // Process images: download external images and save to media library
  const processImages = useCallback(async (blocksToProcess: CopilotBlock[]): Promise<ContentBlock[]> => {
    const contentBlocks = blocksToProcess.map(b => ({ 
      id: b.id, 
      type: b.type as ContentBlockType, 
      data: b.data 
    })) as ContentBlock[];
    
    const images = extractImageUrls(contentBlocks);
    
    if (images.length === 0) {
      return contentBlocks;
    }
    
    logger.log(`Processing ${images.length} images for local storage...`);
    let updatedBlocks = contentBlocks;
    let processedCount = 0;
    
    for (const { blockIndex, path, url } of images) {
      try {
        const { data, error } = await supabase.functions.invoke('process-image', {
          body: { imageUrl: url, folder: 'flowpilot' }
        });
        
        if (error) {
          logger.warn(`Failed to process image ${url}:`, error);
          continue;
        }
        
        if (data.success && data.url) {
          updatedBlocks = updateBlockAtPath(updatedBlocks, blockIndex, path, data.url);
          processedCount++;
          logger.log(`Processed image ${processedCount}/${images.length}: ${url} → ${data.url}`);
        }
      } catch (err) {
        logger.warn(`Error processing image ${url}:`, err);
        // Continue with other images even if one fails
      }
    }
    
    logger.log(`Image processing complete: ${processedCount}/${images.length} images saved locally`);
    return updatedBlocks;
  }, []);

  const skipMigrationBlock = useCallback(async () => {
    if (!migrationState.isActive || migrationState.pendingBlocks.length === 0) return;

    const nextIndex = migrationState.currentBlockIndex + 1;
    
    if (nextIndex >= migrationState.pendingBlocks.length) {
      // All blocks reviewed - check if we have any approved blocks to save
      setMigrationState(prev => ({ ...prev, currentBlockIndex: nextIndex }));
      
      const approvedBlocks = blocks.filter(b => b.status === 'approved');
      
      if (approvedBlocks.length > 0) {
        // Auto-save with approved blocks
        const pageTitle = migrationState.pageTitle || 'Imported Page';
        // Use clean slug from URL path (stored in migrationState), not generated from title
        const pageSlug = migrationState.pageSlug || generateSlug(pageTitle);
        const pagesCompleted = migrationState.pagesCompleted;
        const pagesTotal = migrationState.pagesTotal;
        
        try {
          // Process images before saving
          const processedBlocks = await processImages(approvedBlocks);
          
          await createPageMutation.mutateAsync({
            title: pageTitle,
            slug: pageSlug,
            content: processedBlocks,
            status: 'draft',
            show_in_menu: false, // Don't auto-add to menu
          });
          
          if (migrationState.currentPageUrl) {
            updatePageStatusInStructure(migrationState.currentPageUrl, 'completed');
          }
          
          setBlocks([]);
          const newPagesCompleted = pagesCompleted + 1;
          setMigrationState(prev => ({ ...prev, pagesCompleted: newPagesCompleted }));
          
          const nextPage = findNextPendingPage();
          
          if (nextPage && nextPage.status === 'pending') {
            const continueMessage: CopilotMessage = {
              id: generateId(),
              role: 'assistant',
              content: `✅ **${pageTitle}** saved with ${approvedBlocks.length} sections! (${newPagesCompleted}/${pagesTotal})\n\n➡️ Moving to: **${nextPage.title}**...`,
              createdAt: new Date(),
            };
            setMessages(prev => [...prev, continueMessage]);
            
            const fullUrl = nextPage.url.startsWith('http') 
              ? nextPage.url 
              : `${migrationState.baseDomain}${nextPage.url}`;
            
            setTimeout(() => startMigration(fullUrl), 800);
          } else {
            // All pages done
            const completeMessage: CopilotMessage = {
              id: generateId(),
              role: 'assistant',
              content: `🎉 **All ${newPagesCompleted} pages migrated!**\n\nYour site migration is complete!`,
              createdAt: new Date(),
            };
            setMessages(prev => [...prev, completeMessage]);
            setMigrationState(prev => ({ ...prev, discoveryStatus: 'complete', phase: 'complete' }));
          }
        } catch (err) {
          logger.error('Failed to save page:', err);
          toast.error('Failed to save page');
        }
      } else {
        // No approved blocks - skip this page entirely
        if (migrationState.currentPageUrl) {
          updatePageStatusInStructure(migrationState.currentPageUrl, 'skipped');
        }
        
        const nextPage = findNextPendingPage();
        
        if (nextPage && nextPage.status === 'pending') {
          const skipMessage: CopilotMessage = {
            id: generateId(),
            role: 'assistant',
            content: `⏭️ Page skipped. Moving to: **${nextPage.title}**...`,
            createdAt: new Date(),
          };
          setMessages(prev => [...prev, skipMessage]);
          
          const fullUrl = nextPage.url.startsWith('http') 
            ? nextPage.url 
            : `${migrationState.baseDomain}${nextPage.url}`;
          
          setTimeout(() => startMigration(fullUrl), 800);
        } else {
          const completeMessage: CopilotMessage = {
            id: generateId(),
            role: 'assistant',
            content: `✅ Migration review complete! ${migrationState.pagesCompleted} pages were saved as drafts.`,
            createdAt: new Date(),
          };
          setMessages(prev => [...prev, completeMessage]);
          setMigrationState(prev => ({ ...prev, discoveryStatus: 'complete', phase: 'complete' }));
        }
      }
    } else {
      setMigrationState(prev => ({ ...prev, currentBlockIndex: nextIndex }));
    }
  }, [migrationState, blocks, createPageMutation, updatePageStatusInStructure, findNextPendingPage, startMigration]);

  const editMigrationBlock = useCallback((feedback: string) => {
    if (!migrationState.isActive) return;
    
    const currentBlock = migrationState.pendingBlocks[migrationState.currentBlockIndex];
    if (!currentBlock) return;

    // Send feedback to regenerate
    sendMessage(`Modify the ${currentBlock.type} section: ${feedback}`);
  }, [migrationState]);

  const migrateNextPage = useCallback(async (url: string) => {
    // Check if already migrated
    if (migrationState.migratedPages.includes(url)) {
      toast.info('This page has already been migrated');
      return;
    }
    
    await startMigration(url);
  }, [migrationState.migratedPages, startMigration]);

  const sendMessage = useCallback(async (content: string) => {
    if (!content.trim() || isLoading) return;

    const lowerContent = content.toLowerCase().trim();

    // CONVERSATIONAL COMMANDS - Handle quick intents locally
    // Approval commands
    if (['yes', 'looks good', 'keep it', 'approve', 'ok', 'perfect', 'great'].includes(lowerContent)) {
      if (migrationState.isActive && migrationState.pendingBlocks.length > 0) {
        approveMigrationBlock();
        return;
      }
    }

    // Skip commands
    if (['skip', 'next', 'pass', 'no'].includes(lowerContent)) {
      if (migrationState.isActive && migrationState.pendingBlocks.length > 0) {
        skipMigrationBlock();
        return;
      }
    }

    // Phase skip commands
    if (lowerContent.includes('skip blog') || lowerContent.includes('skip kb') || 
        lowerContent.includes('just pages') || lowerContent.includes('only pages')) {
      if (migrationState.phase !== 'complete') {
        skipPhase();
        return;
      }
    }

    // NOTE: URL-based migration requests are now handled by CopilotChat's
    // onAnalyzeSite callback which routes to discoverPages for page selection

    // Add user message
    const userMessage: CopilotMessage = {
      id: generateId(),
      role: 'user',
      content,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, userMessage]);
    setIsLoading(true);
    setError(null);

    // Create abort controller for this request
    abortControllerRef.current = new AbortController();

    try {
      // Build conversation history for API
      const conversationHistory = [...messages, userMessage].map(m => ({
        role: m.role,
        content: m.content,
      }));

      const { data, error: fnError } = await supabase.functions.invoke('copilot-action', {
        body: { 
          messages: conversationHistory,
          currentModules: currentModules || defaultModulesSettings,
          migrationState: migrationState.isActive ? {
            sourceUrl: migrationState.sourceUrl,
            platform: migrationState.detectedPlatform,
          } : null,
        },
      });

      if (fnError) throw new Error(fnError.message);
      if (data?.error) throw new Error(data.error);

      // Process response
      const assistantMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: data.message || '',
        createdAt: new Date(),
      };

      // Handle tool calls
      if (data.toolCall) {
        assistantMessage.toolCall = data.toolCall;

        if (data.toolCall.name === 'activate_modules') {
          // Auto-enable modules silently instead of asking
          const args = data.toolCall.arguments as { modules: string[]; reason: string };
          for (const moduleId of args.modules) {
            await autoEnableModule(moduleId as keyof ModulesSettings);
          }
        } else if (data.toolCall.name === 'migrate_url') {
          // Migration request from AI
          const args = data.toolCall.arguments as { url: string };
          setMessages(prev => [...prev, assistantMessage]);
          await startMigration(args.url);
          return;
        } else if (data.toolCall.name === 'update_footer') {
          // Footer update from extracted contact info
          const args = data.toolCall.arguments as {
            phone?: string;
            email?: string;
            address?: string;
            postalCode?: string;
            weekdayHours?: string;
            weekendHours?: string;
          };
          
          try {
            // Update footer with extracted contact information
            await updateFooterBlock.mutateAsync({
              phone: args.phone || '',
              email: args.email || '',
              address: args.address || '',
              postalCode: args.postalCode || '',
              weekdayHours: args.weekdayHours || 'Monday–Friday: 09:00–17:00',
              weekendHours: args.weekendHours || 'Saturday–Sunday: Closed',
            });
            toast.success('Footer updated with contact information');
          } catch (err) {
            logger.error('Failed to update footer:', err);
            toast.error('Failed to update footer');
          }
        } else if (data.toolCall.name.startsWith('create_') && data.toolCall.name.endsWith('_block')) {
          // Block creation - auto-approve and auto-enable required modules
          const blockType = data.toolCall.name.replace('create_', '').replace('_block', '');
          
          // Auto-enable required module for this block type
          await autoEnableModuleForBlock(blockType);
          
          const newBlock: CopilotBlock = {
            id: generateId(),
            type: blockType,
            data: data.toolCall.arguments as Record<string, unknown>,
            status: 'approved',
          };
          setBlocks(prev => [...prev, newBlock]);
        }
      }

      setMessages(prev => [...prev, assistantMessage]);

    } catch (err) {
      if (err instanceof Error && err.name === 'AbortError') {
        return;
      }
      const message = err instanceof Error ? err.message : 'Failed to send message';
      setError(message);
      toast.error(message);
    } finally {
      setIsLoading(false);
      abortControllerRef.current = null;
    }
  }, [messages, isLoading, currentModules, migrationState, autoEnableModule, autoEnableModuleForBlock]);

  const approveBlock = useCallback(async (blockId: string) => {
    const block = blocks.find(b => b.id === blockId);
    if (!block) return;
    
    // Auto-enable required module for this block type
    await autoEnableModuleForBlock(block.type);
    
    setBlocks(prev => prev.map(b => 
      b.id === blockId ? { ...b, status: 'approved' as const } : b
    ));
    toast.success('Block approved');
  }, [blocks, autoEnableModuleForBlock]);

  const rejectBlock = useCallback((blockId: string) => {
    setBlocks(prev => prev.map(b => 
      b.id === blockId ? { ...b, status: 'rejected' as const } : b
    ));
  }, []);

  const regenerateBlock = useCallback(async (blockId: string, feedback?: string) => {
    const block = blocks.find(b => b.id === blockId);
    if (!block) return;

    const regeneratePrompt = feedback 
      ? `Regenerate the ${block.type} block with this feedback: ${feedback}`
      : `Regenerate the ${block.type} block with better content`;

    // Remove the old block
    setBlocks(prev => prev.filter(b => b.id !== blockId));
    
    // Send regenerate request
    await sendMessage(regeneratePrompt);
  }, [blocks, sendMessage]);

  const cancelRequest = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
      setIsLoading(false);
    }
    setIsAutoContinue(false);
  }, []);

  const stopAutoContinue = useCallback(() => {
    setIsAutoContinue(false);
  }, []);

  const clearConversation = useCallback(() => {
    setMessages([]);
    setBlocks([]);
    setError(null);
    setIsAutoContinue(false);
    setMigrationState(initialMigrationState);
    setEnabledModulesCache(new Set());
    
    // Clear localStorage
    localStorage.removeItem(STORAGE_KEYS.messages);
    localStorage.removeItem(STORAGE_KEYS.blocks);
    localStorage.removeItem(STORAGE_KEYS.migrationState);
  }, []);

  // Phase control functions
  const startBlogMigration = useCallback(async () => {
    if (!migrationState.hasBlog || migrationState.blogUrls.length === 0) {
      const msg: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `No blog detected on this site. Let's move on!`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, msg]);
      return;
    }
    
    setMigrationState(prev => ({ ...prev, phase: 'blog' }));
    
    const msg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `📝 Great! I found ${migrationState.blogUrls.length} blog posts. Let me start migrating them as blog posts in your new system.\n\nI'll handle the content, categories, and metadata automatically.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, msg]);
    
    // Start migrating first blog URL
    if (migrationState.blogUrls[0]) {
      const fullUrl = migrationState.baseDomain 
        ? new URL(migrationState.blogUrls[0], migrationState.baseDomain).href 
        : migrationState.blogUrls[0];
      await startMigration(fullUrl);
    }
  }, [migrationState, startMigration]);

  const startKbMigration = useCallback(async () => {
    if (!migrationState.hasKnowledgeBase || migrationState.kbUrls.length === 0) {
      const msg: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `No knowledge base detected on this site. You're all set!`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, msg]);
      setMigrationState(prev => ({ ...prev, phase: 'complete' }));
      return;
    }
    
    setMigrationState(prev => ({ ...prev, phase: 'knowledgeBase' }));
    
    const msg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `📚 Found ${migrationState.kbUrls.length} knowledge base articles. I'll migrate these into structured FAQ/help content.\n\nEach article will be organized by category for easy navigation.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, msg]);
    
    // Start migrating first KB URL
    if (migrationState.kbUrls[0]) {
      const fullUrl = migrationState.baseDomain 
        ? new URL(migrationState.kbUrls[0], migrationState.baseDomain).href 
        : migrationState.kbUrls[0];
      await startMigration(fullUrl);
    }
  }, [migrationState, startMigration]);

  const skipPhase = useCallback(() => {
    const currentPhase = migrationState.phase;
    let nextPhase: MigrationPhase = 'complete';
    let message = '';
    
    if (currentPhase === 'pages') {
      if (migrationState.hasBlog) {
        nextPhase = 'blog';
        message = `Skipped remaining pages. Found ${migrationState.blogUrls.length} blog posts. Would you like me to migrate them?`;
      } else if (migrationState.hasKnowledgeBase) {
        nextPhase = 'knowledgeBase';
        message = `Skipped remaining pages. Found ${migrationState.kbUrls.length} KB articles. Would you like me to migrate them?`;
      } else {
        message = `Migration complete! All content has been imported.`;
      }
    } else if (currentPhase === 'blog') {
      if (migrationState.hasKnowledgeBase) {
        nextPhase = 'knowledgeBase';
        message = `Skipped blog migration. Found ${migrationState.kbUrls.length} KB articles. Would you like me to migrate them?`;
      } else {
        message = `Migration complete! Your pages and content are ready.`;
      }
    } else {
      message = `Migration complete! All content has been imported.`;
    }
    
    setMigrationState(prev => ({ ...prev, phase: nextPhase }));
    
    const msg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: message,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, msg]);
  }, [migrationState]);

  const approvedBlocks = blocks.filter(b => b.status === 'approved');

  // ==================== FIRECRAWL MAP PAGE DISCOVERY ====================

  // Discover pages using Firecrawl Map - returns all URLs for user selection
  const discoverPages = useCallback(async (url: string) => {
    setIsLoading(true);
    setError(null);
    setMigrationState(prev => ({ ...prev, discoveryStatus: 'analyzing', sourceUrl: url }));

    const discoverMessage: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `🔍 Discovering pages on ${url}...\n\nUsing Firecrawl Map to find all URLs.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, discoverMessage]);

    try {
      const { data, error: fnError } = await supabase.functions.invoke('firecrawl-map', {
        body: { url, options: { limit: 100 } },
      });

      if (fnError) throw new Error(fnError.message);
      if (!data?.success) throw new Error(data?.error || 'Page discovery failed');

      const siteStructure: SiteStructure = {
        siteName: data.siteName || 'Unknown Site',
        platform: data.platform || 'unknown',
        baseUrl: data.baseUrl || url,
        pages: data.pages || [],
        navigation: [],
        hasBlog: data.stats?.blog > 0,
        hasKnowledgeBase: data.stats?.kb > 0,
        stats: data.stats,
      };

      setMigrationState(prev => ({
        ...prev,
        siteStructure,
        discoveryStatus: 'selecting',
        baseDomain: siteStructure.baseUrl,
        detectedPlatform: siteStructure.platform,
        hasBlog: siteStructure.hasBlog,
        hasKnowledgeBase: siteStructure.hasKnowledgeBase,
        pagesTotal: data.stats?.selected || data.pages?.length || 0,
        blogPostsDiscovered: data.stats?.blog || 0,
        kbArticlesDiscovered: data.stats?.kb || 0,
      }));

      // Auto-enable modules based on detected platform
      if (siteStructure.platform && siteStructure.platform !== 'unknown') {
        const suggestedModules = detectModulesFromPlatform(siteStructure.platform);
        for (const moduleId of suggestedModules) {
          await autoEnableModule(moduleId);
        }
      }

      const successMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `✨ **${siteStructure.siteName}** - Found ${data.pages?.length || 0} pages!${siteStructure.platform !== 'unknown' ? ` (${siteStructure.platform})` : ''}\n\n📋 **${data.stats?.selected || 0}** pages pre-selected. Review and select which pages to migrate.`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, successMessage]);

    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to discover pages';
      setError(message);
      setMigrationState(prev => ({ ...prev, discoveryStatus: 'idle' }));
      toast.error(message);

      const errorMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `❌ I couldn't discover pages on that site. ${message}\n\nPlease check that:\n• The URL is correct and accessible\n• The site isn't password protected`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsLoading(false);
    }
  }, [autoEnableModule]);

  // Update discovered pages (for checkbox changes in UI)
  const updateDiscoveredPages = useCallback((pages: DiscoveredPage[]) => {
    setMigrationState(prev => {
      if (!prev.siteStructure) return prev;
      return {
        ...prev,
        siteStructure: { ...prev.siteStructure, pages },
        pagesTotal: pages.filter(p => p.selected).length,
      };
    });
  }, []);

  // Confirm page selection and start migration
  const confirmPageSelection = useCallback(async () => {
    if (!migrationState.siteStructure) return;

    const selectedPages = migrationState.siteStructure.pages.filter(p => p.selected);
    
    if (selectedPages.length === 0) {
      toast.info('No pages selected for migration');
      return;
    }

    setMigrationState(prev => ({ 
      ...prev, 
      discoveryStatus: 'migrating', 
      phase: 'pages',
      pagesTotal: selectedPages.length,
      pagesCompleted: 0,
    }));

    const startMsg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `🚀 Starting migration of ${selectedPages.length} pages...\n\nI'll process each page and show you the content for review.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, startMsg]);

    // Mark selected pages as pending
    setMigrationState(prev => {
      if (!prev.siteStructure) return prev;
      return {
        ...prev,
        siteStructure: {
          ...prev.siteStructure,
          pages: prev.siteStructure.pages.map(p => ({
            ...p,
            status: p.selected ? 'pending' as const : 'skipped' as const,
          })),
        },
      };
    });

    // Start with the first selected page
    const firstPage = selectedPages[0];
    if (firstPage) {
      await startMigration(firstPage.url);
    }
  }, [migrationState.siteStructure, startMigration]);

  // Cancel page selection
  const cancelPageSelection = useCallback(() => {
    setMigrationState(initialMigrationState);
    const msg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `Page selection cancelled. Let me know if you'd like to try a different site!`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, msg]);
  }, []);

  // ==================== LEGACY SITE DISCOVERY FUNCTIONS ====================

  const analyzeSite = useCallback(async (url: string) => {
    setIsLoading(true);
    setError(null);
    setMigrationState(prev => ({ ...prev, discoveryStatus: 'analyzing', sourceUrl: url }));

    // Add analyzing message
    const analyzeMessage: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `🔍 Analyzing site structure for ${url}...\n\nScanning navigation, sitemap, and detecting content types.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, analyzeMessage]);

    try {
      const { data, error: fnError } = await supabase.functions.invoke('migrate-page', {
        body: { url, action: 'analyze-site' },
      });

      if (fnError) throw new Error(fnError.message);
      if (!data?.success) throw new Error(data?.error || 'Site analysis failed');

      const siteStructure: SiteStructure = {
        siteName: data.siteName || 'Unknown Site',
        platform: data.platform || 'unknown',
        baseUrl: data.baseUrl || url,
        pages: (data.pages || []).map((p: DiscoveredPage) => ({
          ...p,
          status: 'pending' as const,
        })),
        navigation: data.navigation || [],
        hasBlog: data.hasBlog || false,
        hasKnowledgeBase: data.hasKnowledgeBase || false,
      };

      // Categorize pages
      const pageCount = siteStructure.pages.filter(p => p.type === 'page').length;
      const blogCount = siteStructure.pages.filter(p => p.type === 'blog').length;
      const kbCount = siteStructure.pages.filter(p => p.type === 'kb').length;

      setMigrationState(prev => ({
        ...prev,
        siteStructure,
        discoveryStatus: 'ready',
        baseDomain: siteStructure.baseUrl,
        detectedPlatform: siteStructure.platform,
        hasBlog: siteStructure.hasBlog,
        hasKnowledgeBase: siteStructure.hasKnowledgeBase,
        pagesTotal: pageCount,
        blogPostsDiscovered: blogCount,
        kbArticlesDiscovered: kbCount,
      }));

      // Auto-enable modules based on detected platform
      if (siteStructure.platform && siteStructure.platform !== 'unknown') {
        const suggestedModules = detectModulesFromPlatform(siteStructure.platform);
        for (const moduleId of suggestedModules) {
          await autoEnableModule(moduleId);
        }
      }

      // Success message - immediately start migration
      const totalPages = siteStructure.pages.length;
      
      // Prioritize homepage selection
      const homePage = siteStructure.pages.find(p => 
        p.url === siteStructure.baseUrl || 
        p.url === siteStructure.baseUrl + '/' ||
        p.title.toLowerCase() === 'home' ||
        p.title.toLowerCase() === 'hem' ||
        p.title.toLowerCase() === 'start' ||
        p.title.toLowerCase() === 'startsida'
      );
      const firstPage = homePage || siteStructure.pages.find(p => p.type === 'page') || siteStructure.pages[0];
      
      const successMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `✨ **${siteStructure.siteName}** - Found ${totalPages} pages!${siteStructure.platform !== 'unknown' ? ` (${siteStructure.platform})` : ''}\n\nStarting with ${firstPage?.title || 'homepage'}. I'll show you each section for review.`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, successMessage]);

      // AUTO-START MIGRATION with first page (homepage)
      if (firstPage) {
        setMigrationState(prev => ({ ...prev, discoveryStatus: 'migrating', phase: 'pages' }));
        const fullUrl = firstPage.url.startsWith('http') 
          ? firstPage.url 
          : `${siteStructure.baseUrl}${firstPage.url}`;
        
        // Small delay for UX
        setTimeout(() => {
          startMigration(fullUrl);
        }, 500);
      }

    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to analyze site';
      setError(message);
      setMigrationState(prev => ({ ...prev, discoveryStatus: 'idle' }));
      toast.error(message);

      const errorMessage: CopilotMessage = {
        id: generateId(),
        role: 'assistant',
        content: `❌ I couldn't analyze that site. ${message}\n\nPlease check that:\n• The URL is correct and accessible\n• The site isn't password protected`,
        createdAt: new Date(),
      };
      setMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsLoading(false);
    }
  }, [autoEnableModule, startMigration]);

  const selectPageForMigration = useCallback((url: string) => {
    setMigrationState(prev => {
      if (!prev.siteStructure) return prev;
      
      const updatedPages = prev.siteStructure.pages.map(p =>
        p.url === url ? { ...p, status: 'pending' as const } : p
      );
      
      return {
        ...prev,
        siteStructure: { ...prev.siteStructure, pages: updatedPages },
      };
    });
  }, []);

  const togglePageSelection = useCallback((url: string) => {
    setMigrationState(prev => {
      if (!prev.siteStructure) return prev;
      
      const updatedPages = prev.siteStructure.pages.map(p => {
        if (p.url === url) {
          const newStatus = p.status === 'pending' ? 'skipped' : 'pending';
          return { ...p, status: newStatus as 'pending' | 'skipped' };
        }
        return p;
      });
      
      return {
        ...prev,
        siteStructure: { ...prev.siteStructure, pages: updatedPages },
      };
    });
  }, []);

  const migrateSelectedPages = useCallback(async () => {
    if (!migrationState.siteStructure) return;

    const selectedPages = migrationState.siteStructure.pages.filter(
      p => p.status === 'pending'
    );

    if (selectedPages.length === 0) {
      toast.info('No pages selected for migration');
      return;
    }

    setMigrationState(prev => ({ ...prev, discoveryStatus: 'migrating', phase: 'pages' }));

    const startMsg: CopilotMessage = {
      id: generateId(),
      role: 'assistant',
      content: `🚀 Starting migration of ${selectedPages.length} pages...\n\nI'll process each page and show you the content for review.`,
      createdAt: new Date(),
    };
    setMessages(prev => [...prev, startMsg]);

    // Start with the first selected page
    const firstPage = selectedPages[0];
    if (firstPage) {
      const fullUrl = firstPage.url.startsWith('http') 
        ? firstPage.url 
        : `${migrationState.siteStructure.baseUrl}${firstPage.url}`;
      await startMigration(fullUrl);
    }
  }, [migrationState.siteStructure, startMigration]);

  return {
    messages,
    blocks,
    isLoading,
    error,
    isAutoContinue,
    migrationState,
    sendMessage,
    approveBlock,
    rejectBlock,
    regenerateBlock,
    cancelRequest,
    clearConversation,
    stopAutoContinue,
    approvedBlocks,
    // Firecrawl Map page discovery
    discoverPages,
    updateDiscoveredPages,
    confirmPageSelection,
    cancelPageSelection,
    // Legacy site discovery
    analyzeSite,
    selectPageForMigration,
    togglePageSelection,
    migrateSelectedPages,
    // Migration functions
    startMigration,
    approveMigrationBlock,
    skipMigrationBlock,
    editMigrationBlock,
    migrateNextPage,
    // Phase control
    startBlogMigration,
    startKbMigration,
    skipPhase,
  };
}
