/**
 * Clusters Page - Refactored to use TablePageTemplate
 * Consistent with Keywords page layout, structure and design
 */

import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import TablePageTemplate from '../../templates/TablePageTemplate';
import {
  fetchClusters,
  createCluster,
  updateCluster,
  deleteCluster,
  bulkDeleteClusters,
  bulkUpdateClustersStatus,
  autoGenerateIdeas,
  Cluster,
  ClusterFilters,
  ClusterCreateData,
} from '../../services/api';
import FormModal from '../../components/common/FormModal';
import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { GroupIcon, PlusIcon, DownloadIcon } from '../../icons';
import { createClustersPageConfig } from '../../config/pages/clusters.config';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import { getDifficultyLabelFromNumber, getDifficultyRange } from '../../utils/difficulty';
import PageHeader from '../../components/common/PageHeader';

export default function Clusters() {
  const toast = useToast();
  const { activeSector } = useSectorStore();
  const { pageSize } = usePageSizeStore();

  // Data state
  const [clusters, setClusters] = useState<Cluster[]>([]);
  const [loading, setLoading] = useState(true);
  
  // Filter state
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState('');
  const [difficultyFilter, setDifficultyFilter] = useState('');
  const [volumeMin, setVolumeMin] = useState<number | ''>('');
  const [volumeMax, setVolumeMax] = useState<number | ''>('');
  const [isVolumeDropdownOpen, setIsVolumeDropdownOpen] = useState(false);
  const [tempVolumeMin, setTempVolumeMin] = useState<number | ''>('');
  const [tempVolumeMax, setTempVolumeMax] = useState<number | ''>('');
  const volumeDropdownRef = useRef<HTMLDivElement>(null);
  const volumeButtonRef = useRef<HTMLButtonElement>(null);
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  
  // Pagination state
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalCount, setTotalCount] = useState(0);
  
  // Sorting state
  const [sortBy, setSortBy] = useState<string>('name');
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
  const [showContent, setShowContent] = useState(false);
  
  // Modal state
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isEditMode, setIsEditMode] = useState(false);
  const [editingCluster, setEditingCluster] = useState<Cluster | null>(null);
  const [formData, setFormData] = useState<ClusterCreateData>({
    name: '',
    description: '',
    status: 'active',
  });

  // Progress modal for AI functions
  const progressModal = useProgressModal();
  const hasReloadedRef = useRef(false);

  // Load clusters - wrapped in useCallback to prevent infinite loops
  const loadClusters = useCallback(async () => {
    setLoading(true);
    setShowContent(false);
    try {
      const ordering = sortBy ? `${sortDirection === 'desc' ? '-' : ''}${sortBy}` : 'name';
      
      const filters: ClusterFilters = {
        ...(searchTerm && { search: searchTerm }),
        ...(statusFilter && { status: statusFilter }),
        ...(activeSector?.id && { sector_id: activeSector.id }),
        page: currentPage,
        page_size: pageSize,
        ordering,
      };
      
      // Add difficulty range filter
      if (difficultyFilter) {
        const difficultyNum = parseInt(difficultyFilter);
        const label = getDifficultyLabelFromNumber(difficultyNum);
        if (label !== null) {
          const range = getDifficultyRange(label);
          if (range) {
            filters.difficulty_min = range.min;
            filters.difficulty_max = range.max;
          }
        }
      }
      
      // Add volume range filters
      if (volumeMin !== '' && volumeMin !== null && volumeMin !== undefined) {
        filters.volume_min = Number(volumeMin);
      }
      if (volumeMax !== '' && volumeMax !== null && volumeMax !== undefined) {
        filters.volume_max = Number(volumeMax);
      }
      
      const data = await fetchClusters(filters);
      setClusters(data.results || []);
      setTotalCount(data.count || 0);
      setTotalPages(Math.ceil((data.count || 0) / pageSize));
      
      setTimeout(() => {
        setShowContent(true);
        setLoading(false);
      }, 100);
    } catch (error: any) {
      console.error('Error loading clusters:', error);
      toast.error(`Failed to load clusters: ${error.message}`);
      setShowContent(true);
      setLoading(false);
    }
    }, [currentPage, statusFilter, sortBy, sortDirection, searchTerm, difficultyFilter, volumeMin, volumeMax, activeSector, pageSize]);

  // Load data on mount and when filters change
  useEffect(() => {
    loadClusters();
  }, [loadClusters]);

  // Listen for site and sector changes and refresh data
  useEffect(() => {
    const handleSiteChange = () => {
      loadClusters();
    };
    
    const handleSectorChange = () => {
      loadClusters();
    };
    
    window.addEventListener('siteChanged', handleSiteChange);
    window.addEventListener('sectorChanged', handleSectorChange);
    return () => {
      window.removeEventListener('siteChanged', handleSiteChange);
      window.removeEventListener('sectorChanged', handleSectorChange);
    };
  }, [loadClusters]);

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

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

  // Reset to page 1 when pageSize changes
  useEffect(() => {
    setCurrentPage(1);
  }, [pageSize]);

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

  // Bulk status update handler
  const handleBulkUpdateStatus = useCallback(async (ids: string[], status: string) => {
    try {
      const numIds = ids.map(id => parseInt(id));
      await bulkUpdateClustersStatus(numIds, status);
      await loadClusters();
    } catch (error: any) {
      throw error;
    }
  }, [loadClusters]);

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

  // Row action handler
  const handleRowAction = useCallback(async (action: string, row: Cluster) => {
    if (action === 'generate_ideas') {
      try {
        const result = await autoGenerateIdeas([row.id]);
        
        if (result.success && result.task_id) {
          // Async task - show progress modal
          progressModal.openModal(result.task_id, 'Generating Ideas', 'ai-generate-ideas-01-desktop');
        } else if (result.success && result.ideas_created) {
          // Synchronous completion
          toast.success(result.message || 'Ideas generated successfully');
          await loadClusters();
        } else {
          toast.error(result.error || 'Failed to generate ideas');
        }
      } catch (error: any) {
        toast.error(`Failed to generate ideas: ${error.message}`);
      }
    }
  }, [toast, progressModal, loadClusters]);

  // Bulk action handler
  const handleBulkAction = useCallback(async (action: string, ids: string[]) => {
    if (action === 'auto_generate_ideas') {
      if (ids.length === 0) {
        toast.error('Please select at least one cluster to generate ideas');
        return;
      }
      if (ids.length > 5) {
        toast.error('Maximum 5 clusters allowed for idea generation');
        return;
      }
      
      try {
        const numIds = ids.map(id => parseInt(id));
        const result = await autoGenerateIdeas(numIds);
        
        // Check if result has success field - if false, it's an error response
        if (result && result.success === false) {
          // Error response from API
          const errorMsg = result.error || 'Failed to generate ideas';
          toast.error(errorMsg);
          return;
        }
        
        if (result && result.success) {
          if (result.task_id) {
            // Async task - open progress modal
            hasReloadedRef.current = false;
            progressModal.openModal(result.task_id, 'Generating Content Ideas', 'ai-generate-ideas-01-desktop');
            // Don't show toast - progress modal will show status
          } else {
            // Synchronous completion
            toast.success(`Ideas generation complete: ${result.ideas_created || 0} ideas created`);
            if (!hasReloadedRef.current) {
              hasReloadedRef.current = true;
              loadClusters();
            }
          }
        } else {
          // Unexpected response format - show error
          const errorMsg = result?.error || 'Unexpected response format';
          toast.error(errorMsg);
        }
      } catch (error: any) {
        // API error (network error, parse error, etc.)
        let errorMsg = 'Failed to generate ideas';
        if (error.message) {
          // Extract clean error message from API error format
          errorMsg = error.message.replace(/^API Error \(\d+\): [^-]+ - /, '').trim();
          if (!errorMsg || errorMsg === error.message) {
            errorMsg = error.message;
          }
        }
        toast.error(errorMsg);
      }
    } else {
      toast.info(`Bulk action "${action}" for ${ids.length} items`);
    }
  }, [toast, loadClusters, progressModal]);

  // Close volume dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        volumeDropdownRef.current &&
        !volumeDropdownRef.current.contains(event.target as Node) &&
        volumeButtonRef.current &&
        !volumeButtonRef.current.contains(event.target as Node)
      ) {
        setIsVolumeDropdownOpen(false);
      }
    };

    if (isVolumeDropdownOpen) {
      document.addEventListener('mousedown', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [isVolumeDropdownOpen]);

  // Create page config
  const pageConfig = useMemo(() => {
    return createClustersPageConfig({
      activeSector,
      formData,
      setFormData,
      searchTerm,
      setSearchTerm,
      statusFilter,
      setStatusFilter,
      difficultyFilter,
      setDifficultyFilter,
      volumeMin,
      volumeMax,
      setVolumeMin,
      setVolumeMax,
      isVolumeDropdownOpen,
      setIsVolumeDropdownOpen,
      tempVolumeMin,
      tempVolumeMax,
      setTempVolumeMin,
      setTempVolumeMax,
      volumeButtonRef,
      volumeDropdownRef,
      setCurrentPage,
      loadClusters,
    });
  }, [
    activeSector,
    formData,
    searchTerm,
    statusFilter,
    difficultyFilter,
    volumeMin,
    volumeMax,
    isVolumeDropdownOpen,
    tempVolumeMin,
    tempVolumeMax,
    loadClusters,
  ]);

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

  const resetForm = useCallback(() => {
    setFormData({
      name: '',
      description: '',
      status: 'active',
    });
    setIsEditMode(false);
    setEditingCluster(null);
  }, []);

  // Handle create/edit
  const handleSave = async () => {
    try {
      if (isEditMode && editingCluster) {
        await updateCluster(editingCluster.id, formData);
        toast.success('Cluster updated successfully');
      } else {
        await createCluster(formData);
        toast.success('Cluster created successfully');
      }
      setIsModalOpen(false);
      resetForm();
      loadClusters();
    } catch (error: any) {
      toast.error(`Failed to save: ${error.message}`);
    }
  };

  return (
    <>
      <PageHeader 
        title="Keyword Clusters" 
        badge={{ icon: <GroupIcon />, color: 'purple' }}
      />
      <TablePageTemplate
        columns={pageConfig.columns}
        data={clusters}
        loading={loading}
        showContent={showContent}
        filters={pageConfig.filters}
        filterValues={{
          search: searchTerm,
          status: statusFilter,
          difficulty: difficultyFilter,
          volumeMin: volumeMin,
          volumeMax: volumeMax,
        }}
        onFilterChange={(key, value) => {
          const stringValue = value === null || value === undefined ? '' : String(value);
          if (key === 'search') {
            setSearchTerm(stringValue);
          } else if (key === 'status') {
            setStatusFilter(stringValue);
          } else if (key === 'difficulty') {
            setDifficultyFilter(stringValue);
          }
          setCurrentPage(1);
        }}
        onEdit={(row) => {
          setEditingCluster(row);
          setFormData({
            name: row.name || '',
            description: row.description || '',
            status: row.status || 'active',
          });
          setIsEditMode(true);
          setIsModalOpen(true);
        }}
        onCreate={() => {
          resetForm();
          setIsModalOpen(true);
        }}
        createLabel="Create Cluster"
        onCreateIcon={<PlusIcon />}
        onDelete={async (id: number) => {
          await deleteCluster(id);
          loadClusters();
        }}
        onBulkDelete={async (ids: number[]) => {
          const result = await bulkDeleteClusters(ids);
          // Clear selection first
          setSelectedIds([]);
          // Reset to page 1 if we deleted all items on current page
          if (currentPage > 1 && clusters.length <= ids.length) {
            setCurrentPage(1);
          }
          // Always reload data to refresh the table
          await loadClusters();
          return result;
        }}
        onBulkExport={handleBulkExport}
        onBulkUpdateStatus={handleBulkUpdateStatus}
        onBulkAction={handleBulkAction}
        onRowAction={handleRowAction}
        getItemDisplayName={(row: Cluster) => row.name}
        onExport={async () => {
          toast.info('Export functionality coming soon');
        }}
        onExportIcon={<DownloadIcon />}
        selectionLabel="cluster"
        pagination={{
          currentPage,
          totalPages,
          totalCount,
          onPageChange: setCurrentPage,
        }}
        selection={{
          selectedIds,
          onSelectionChange: setSelectedIds,
        }}
        sorting={{
          sortBy,
          sortDirection,
          onSort: handleSort,
        }}
        headerMetrics={headerMetrics}
        onFilterReset={() => {
          setSearchTerm('');
          setStatusFilter('');
          setDifficultyFilter('');
          setVolumeMin('');
          setVolumeMax('');
          setCurrentPage(1);
        }}
      />

      {/* Progress Modal for AI Functions */}
      <ProgressModal
        isOpen={progressModal.isOpen}
        title={progressModal.title}
        percentage={progressModal.progress.percentage}
        status={progressModal.progress.status}
        message={progressModal.progress.message}
        details={progressModal.progress.details}
        taskId={progressModal.taskId || undefined}
        functionId={progressModal.functionId}
        stepLogs={progressModal.stepLogs}
        onClose={() => {
          progressModal.closeModal();
          // Reload once when modal closes if task was completed
          if (progressModal.progress.status === 'completed' && !hasReloadedRef.current) {
            hasReloadedRef.current = true;
            loadClusters();
          }
        }}
      />

      {/* Create/Edit Modal */}
      <FormModal
        isOpen={isModalOpen}
        onClose={() => {
          setIsModalOpen(false);
          resetForm();
        }}
        onSubmit={handleSave}
        title={isEditMode ? 'Edit Cluster' : 'Add Cluster'}
        submitLabel={isEditMode ? 'Update' : 'Create'}
        fields={pageConfig.formFields()}
      />
    </>
  );
}
