/**
 * Images Page - Built with TablePageTemplate
 * Shows content images grouped by content - one row per content
 */

import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import TablePageTemplate from '../../templates/TablePageTemplate';
import {
  fetchContentImages,
  ContentImagesGroup,
  ContentImagesResponse,
  fetchImageGenerationSettings,
  generateImages,
  bulkUpdateImagesStatus,
} from '../../services/api';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { FileIcon, DownloadIcon, BoltIcon } from '../../icons';
import { createImagesPageConfig } from '../../config/pages/images.config';
import ImageQueueModal, { ImageQueueItem } from '../../components/common/ImageQueueModal';
import SingleRecordStatusUpdateModal from '../../components/common/SingleRecordStatusUpdateModal';
import { useResourceDebug } from '../../hooks/useResourceDebug';

export default function Images() {
  const toast = useToast();

  // Resource Debug toggle - controls AI Function Logs
  const resourceDebugEnabled = useResourceDebug();

  // AI Function Logs state
  const [aiLogs, setAiLogs] = useState<Array<{
    timestamp: string;
    type: 'request' | 'success' | 'error' | 'step';
    action: string;
    data: any;
    stepName?: string;
    percentage?: number;
  }>>([]);

  // Helper function to add log entry (only if Resource Debug is enabled)
  const addAiLog = useCallback((log: {
    timestamp: string;
    type: 'request' | 'success' | 'error' | 'step';
    action: string;
    data: any;
    stepName?: string;
    percentage?: number;
  }) => {
    if (resourceDebugEnabled) {
      setAiLogs(prev => [...prev, log]);
    }
  }, [resourceDebugEnabled]);

  // Data state
  const [images, setImages] = useState<ContentImagesGroup[]>([]);
  const [loading, setLoading] = useState(true);
  
  // Filter state
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState('');
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  
  // Pagination state (client-side for now)
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalCount, setTotalCount] = useState(0);
  const pageSize = 10;
  
  // Sorting state
  const [sortBy, setSortBy] = useState<string>('content_title');
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
  const [showContent, setShowContent] = useState(false);

  // Image queue modal state
  const [isQueueModalOpen, setIsQueueModalOpen] = useState(false);
  const [imageQueue, setImageQueue] = useState<ImageQueueItem[]>([]);
  const [currentContentId, setCurrentContentId] = useState<number | null>(null);
  const [taskId, setTaskId] = useState<string | null>(null);
  const [imageModel, setImageModel] = useState<string | null>(null);
  const [imageProvider, setImageProvider] = useState<string | null>(null);

  // Status update modal state
  const [isStatusModalOpen, setIsStatusModalOpen] = useState(false);
  const [statusUpdateContentId, setStatusUpdateContentId] = useState<number | null>(null);
  const [statusUpdateRecordName, setStatusUpdateRecordName] = useState<string>('');
  const [isUpdatingStatus, setIsUpdatingStatus] = useState(false);

  // Load images - wrapped in useCallback
  const loadImages = useCallback(async () => {
    setLoading(true);
    setShowContent(false);
    try {
      const data: ContentImagesResponse = await fetchContentImages();
      let filteredResults = data.results || [];
      
      // Client-side search filter
      if (searchTerm) {
        filteredResults = filteredResults.filter(group => 
          group.content_title?.toLowerCase().includes(searchTerm.toLowerCase())
        );
      }
      
      // Client-side status filter
      if (statusFilter) {
        filteredResults = filteredResults.filter(group => 
          group.overall_status === statusFilter
        );
      }
      
      // Client-side sorting
      filteredResults.sort((a, b) => {
        let aVal: any = a.content_title;
        let bVal: any = b.content_title;
        
        if (sortBy === 'overall_status') {
          aVal = a.overall_status;
          bVal = b.overall_status;
        }
        
        if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1;
        if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1;
        return 0;
      });
      
      // Client-side pagination
      const startIndex = (currentPage - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedResults = filteredResults.slice(startIndex, endIndex);
      
      setImages(paginatedResults);
      setTotalCount(filteredResults.length);
      setTotalPages(Math.ceil(filteredResults.length / pageSize));
      
      setTimeout(() => {
        setShowContent(true);
        setLoading(false);
      }, 100);
    } catch (error: any) {
      console.error('Error loading images:', error);
      toast.error(`Failed to load images: ${error.message}`);
      setShowContent(true);
      setLoading(false);
    }
  }, [currentPage, statusFilter, sortBy, sortDirection, searchTerm, toast]);

  useEffect(() => {
    loadImages();
  }, [loadImages]);

  // Debounced search
  useEffect(() => {
    const timer = setTimeout(() => {
      if (currentPage === 1) {
        loadImages();
      } else {
        setCurrentPage(1);
      }
    }, 500);

    return () => clearTimeout(timer);
  }, [searchTerm, currentPage, loadImages]);

  // Handle sorting
  const handleSort = (field: string, direction: 'asc' | 'desc') => {
    setSortBy(field || 'content_title');
    setSortDirection(direction);
    setCurrentPage(1);
  };

  // Bulk export handler
  const handleBulkExport = useCallback(async (ids: string[]) => {
    try {
      if (!ids || ids.length === 0) {
        throw new Error('No records selected for export');
      }
      toast.info('Export functionality coming soon');
    } catch (error: any) {
      throw error;
    }
  }, [toast]);

  // Bulk action handler
  const handleBulkAction = useCallback(async (action: string, ids: string[]) => {
    toast.info(`Bulk action "${action}" for ${ids.length} items`);
  }, [toast]);

  // Row action handler
  const handleRowAction = useCallback(async (action: string, row: ContentImagesGroup) => {
    if (action === 'update_status') {
      setStatusUpdateContentId(row.content_id);
      setStatusUpdateRecordName(row.content_title || `Content #${row.content_id}`);
      setIsStatusModalOpen(true);
    }
  }, []);

  // Handle status update confirmation
  const handleStatusUpdate = useCallback(async (status: string) => {
    if (!statusUpdateContentId) return;

    setIsUpdatingStatus(true);
    try {
      const result = await bulkUpdateImagesStatus(statusUpdateContentId, status);
      toast.success(`Successfully updated ${result.updated_count} image(s) status to ${status}`);
      setIsStatusModalOpen(false);
      setStatusUpdateContentId(null);
      setStatusUpdateRecordName('');
      // Reload images to reflect the changes
      loadImages();
    } catch (error: any) {
      toast.error(`Failed to update status: ${error.message}`);
    } finally {
      setIsUpdatingStatus(false);
    }
  }, [statusUpdateContentId, toast, loadImages]);

  // Build image queue structure
  const buildImageQueue = useCallback((contentId: number, maxInArticleImages: number) => {
    const contentImages = images.find(g => g.content_id === contentId);
    if (!contentImages) return [];
    
    const queue: ImageQueueItem[] = [];
    let queueIndex = 1;
    
    // Featured image (always first)
    if (contentImages.featured_image?.status === 'pending' && 
        contentImages.featured_image?.prompt) {
      queue.push({
        imageId: contentImages.featured_image.id || null,
        index: queueIndex++,
        label: 'Featured Image',
        type: 'featured',
        contentTitle: contentImages.content_title || `Content #${contentId}`,
        status: 'pending',
        progress: 0,
        imageUrl: null,
        error: null,
      });
    }
    
    // In-article images (up to max_in_article_images)
    const pendingInArticle = contentImages.in_article_images
      .filter(img => img.status === 'pending' && img.prompt)
      .slice(0, maxInArticleImages)
      .sort((a, b) => (a.position || 0) - (b.position || 0));
    
    pendingInArticle.forEach((img, idx) => {
      queue.push({
        imageId: img.id || null,
        index: queueIndex++,
        label: `In-Article Image ${img.position || idx + 1}`,
        type: 'in_article',
        position: img.position || idx + 1,
        contentTitle: contentImages.content_title || `Content #${contentId}`,
        status: 'pending',
        progress: 0,
        imageUrl: null,
        error: null,
      });
    });
    
    return queue;
  }, [images]);

  // Generate images handler - Stage 1: Open modal immediately
  const handleGenerateImages = useCallback(async (contentId: number) => {
    try {
      // Get content images
      const contentImages = images.find(g => g.content_id === contentId);
      if (!contentImages) {
        toast.error('Content not found');
        return;
      }
      
      // Fetch image generation settings to get max_in_article_images, model, and provider
      let maxInArticleImages = 2; // Default
      let model = null;
      let provider = null;
      try {
        const settings = await fetchImageGenerationSettings();
        if (settings.success && settings.config) {
          maxInArticleImages = settings.config.max_in_article_images || 2;
          model = settings.config.model || null;
          provider = settings.config.provider || null;
        }
      } catch (error) {
        console.warn('Failed to fetch image settings, using default:', error);
      }
      
      // Store model and provider for modal display
      setImageModel(model);
      setImageProvider(provider);
      
      // Build image queue
      const queue = buildImageQueue(contentId, maxInArticleImages);
      
      if (queue.length === 0) {
        toast.info('No pending images with prompts found for this content');
        return;
      }
      
      // STAGE 1: Open modal immediately with all progress bars
      setImageQueue(queue);
      setCurrentContentId(contentId);
      setIsQueueModalOpen(true);
      
      // Collect image IDs for API call
      const imageIds: number[] = queue
        .map(item => item.imageId)
        .filter((id): id is number => id !== null);
      
      console.log('[Generate Images] Stage 1 Complete: Modal opened with', queue.length, 'images');
      console.log('[Generate Images] Image IDs to generate:', imageIds);
      console.log('[Generate Images] Max in-article images from settings:', maxInArticleImages);
      
      // STAGE 2: Start actual generation
      addAiLog({
        timestamp: new Date().toISOString(),
        type: 'request',
        action: 'generate_images',
        data: { imageIds, contentId, totalImages: imageIds.length }
      });

      const result = await generateImages(imageIds, contentId);
      
      if (result.success && result.task_id) {
        // Task started successfully - polling will be handled by ImageQueueModal
        setTaskId(result.task_id);
        console.log('[Generate Images] Stage 2: Task started with ID:', result.task_id);
        addAiLog({
          timestamp: new Date().toISOString(),
          type: 'step',
          action: 'generate_images',
          stepName: 'Task Queued',
          data: { task_id: result.task_id, message: 'Image generation task queued' }
        });
      } else {
        toast.error(result.error || 'Failed to start image generation');
        setIsQueueModalOpen(false);
        setTaskId(null);
        addAiLog({
          timestamp: new Date().toISOString(),
          type: 'error',
          action: 'generate_images',
          data: { error: result.error || 'Failed to start image generation' }
        });
      }
      
    } catch (error: any) {
      console.error('[Generate Images] Exception:', error);
      toast.error(`Failed to initialize image generation: ${error.message}`);
    }
  }, [toast, images, buildImageQueue]);

  // Get max in-article images from the data (to determine column count)
  const maxInArticleImages = useMemo(() => {
    if (images.length === 0) return 5; // Default
    const max = Math.max(...images.map(group => group.in_article_images.length));
    return Math.max(max, 5); // At least 5 columns
  }, [images]);

  // Create page config
  const pageConfig = useMemo(() => {
    return createImagesPageConfig({
      searchTerm,
      setSearchTerm,
      statusFilter,
      setStatusFilter,
      setCurrentPage,
      maxInArticleImages,
      onGenerateImages: handleGenerateImages,
    });
  }, [searchTerm, statusFilter, maxInArticleImages, handleGenerateImages]);

  // Calculate header metrics
  const headerMetrics = useMemo(() => {
    if (!pageConfig?.headerMetrics) return [];
    return pageConfig.headerMetrics.map((metric) => ({
      label: metric.label,
      value: metric.calculate({ images, totalCount }),
      accentColor: metric.accentColor,
    }));
  }, [pageConfig?.headerMetrics, images, totalCount]);

  return (
    <>
    <TablePageTemplate
      title="Content Images"
      titleIcon={<FileIcon className="text-purple-500 size-5" />}
      subtitle="Manage images for content articles"
      columns={pageConfig.columns}
      data={images}
      loading={loading}
      showContent={showContent}
      filters={pageConfig.filters}
      filterValues={{
        search: searchTerm,
        status: statusFilter,
      }}
      onFilterChange={(key, value) => {
        const stringValue = value === null || value === undefined ? '' : String(value);
        if (key === 'search') {
          setSearchTerm(stringValue);
        } else if (key === 'status') {
          setStatusFilter(stringValue);
        }
        setCurrentPage(1);
      }}
      onBulkExport={handleBulkExport}
      onBulkAction={handleBulkAction}
      getItemDisplayName={(row: ContentImagesGroup) => row.content_title || `Content #${row.content_id}`}
      onExport={async () => {
        toast.info('Export functionality coming soon');
      }}
      onExportIcon={<DownloadIcon />}
      selectionLabel="content"
      pagination={{
        currentPage,
        totalPages,
        totalCount,
        onPageChange: setCurrentPage,
      }}
      selection={{
        selectedIds,
        onSelectionChange: setSelectedIds,
      }}
      sorting={{
        sortBy,
        sortDirection,
        onSort: handleSort,
      }}
      headerMetrics={headerMetrics}
      onFilterReset={() => {
        setSearchTerm('');
        setStatusFilter('');
        setCurrentPage(1);
      }}
      onRowAction={handleRowAction}
    />
      <ImageQueueModal
        isOpen={isQueueModalOpen}
        onClose={() => {
          setIsQueueModalOpen(false);
          setImageQueue([]);
          setCurrentContentId(null);
          setTaskId(null);
          setImageModel(null);
          setImageProvider(null);
          // Reload images after closing if generation completed
          loadImages();
        }}
        queue={imageQueue}
        totalImages={imageQueue.length}
        taskId={taskId}
        model={imageModel || undefined}
        provider={imageProvider || undefined}
        onUpdateQueue={setImageQueue}
        onLog={addAiLog}
      />

      {/* Status Update Modal */}
      <SingleRecordStatusUpdateModal
        isOpen={isStatusModalOpen}
        onClose={() => {
          setIsStatusModalOpen(false);
          setStatusUpdateContentId(null);
          setStatusUpdateRecordName('');
        }}
        onConfirm={handleStatusUpdate}
        title="Update Image Status"
        recordName={statusUpdateRecordName}
        statusOptions={[
          { value: 'pending', label: 'Pending' },
          { value: 'generated', label: 'Generated' },
          { value: 'failed', label: 'Failed' },
        ]}
        isLoading={isUpdatingStatus}
      />

      {/* AI Function Logs - Display below table (only when Resource Debug is enabled) */}
      {resourceDebugEnabled && aiLogs.length > 0 && (
        <div className="mt-6 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
          <div className="flex items-center justify-between mb-3">
            <h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">
              AI Function Logs
            </h3>
            <button
              onClick={() => setAiLogs([])}
              className="text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
            >
              Clear Logs
            </button>
          </div>
          <div className="space-y-2 max-h-96 overflow-y-auto">
            {aiLogs.slice().reverse().map((log, index) => (
              <div
                key={index}
                className={`p-3 rounded border text-xs font-mono ${
                  log.type === 'request'
                    ? 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800'
                    : log.type === 'success'
                    ? 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800'
                    : log.type === 'error'
                    ? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'
                    : 'bg-purple-50 dark:bg-purple-900/20 border-purple-200 dark:border-purple-800'
                }`}
              >
                <div className="flex items-center justify-between mb-1">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className={`font-semibold ${
                      log.type === 'request'
                        ? 'text-blue-700 dark:text-blue-300'
                        : log.type === 'success'
                        ? 'text-green-700 dark:text-green-300'
                        : log.type === 'error'
                        ? 'text-red-700 dark:text-red-300'
                        : 'text-purple-700 dark:text-purple-300'
                    }`}>
                      [{log.type.toUpperCase()}]
                    </span>
                    <span className="text-gray-700 dark:text-gray-300">
                      {log.action}
                    </span>
                    {log.stepName && (
                      <span className="text-xs px-2 py-0.5 rounded bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-400">
                        {log.stepName}
                      </span>
                    )}
                    {log.percentage !== undefined && (
                      <span className="text-xs text-gray-500 dark:text-gray-400">
                        {log.percentage}%
                      </span>
                    )}
                  </div>
                  <span className="text-gray-500 dark:text-gray-400">
                    {new Date(log.timestamp).toLocaleTimeString()}
                  </span>
                </div>
                <pre className="text-xs text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
                  {JSON.stringify(log.data, null, 2)}
                </pre>
              </div>
            ))}
          </div>
        </div>
      )}
    </>
  );
}
