/**
 * CrawledPagesSection Component
 *
 * Displays a filterable table of discovered pages with:
 * - Search by URL
 * - Filter by status, analysis status, discovery source, reliability status
 * - Pagination support
 * - View page details
 * - Sort by columns
 *
 * @component
 * @layer Presentation
 */

import { useState, useMemo } from 'react';
import { Search, ExternalLink, ChevronDown, ChevronUp } from 'lucide-react';
import type { DiscoveredPage } from '@domain/entities';
import { PageStatus, AnalysisStatus, DiscoverySource } from '@domain/entities';
import { ReliabilityStatus } from '@archer/domain';
import { PAGE_STATUS_CONFIG, ANALYSIS_STATUS_CONFIG, DISCOVERY_SOURCE_CONFIG } from '@domain/constants';
import { Pagination } from '@/components/ui/Pagination';
import { ReliabilityStatusBadge } from '@/components/ui/ReliabilityStatusBadge';

interface CrawledPagesSectionProps {
  pages: DiscoveredPage[];
  /**
   * Optional page analyses for displaying reliability status
   * Maps page ID to its analysis
   */
  pageAnalyses?: Map<string, { reliabilityStatus?: ReliabilityStatus }>;
}

/**
 * Status Badge Component
 */
function StatusBadge({ status }: { status: PageStatus }) {
  const config = PAGE_STATUS_CONFIG[status];
  const colorClasses: Record<string, string> = {
    green: 'bg-green-100 text-green-800 border-green-200',
    yellow: 'bg-yellow-100 text-yellow-800 border-yellow-200',
    red: 'bg-red-100 text-red-800 border-red-200',
    gray: 'bg-gray-100 text-gray-700 border-gray-200',
  };

  // Extract color name from config.color (e.g., "text-green-600" -> "green")
  const colorName = config.color.split('-')[1] || 'gray';

  return (
    <span
      className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${colorClasses[colorName] || colorClasses.gray}`}
    >
      {config.label}
    </span>
  );
}

/**
 * Analysis Status Badge Component
 */
function AnalysisStatusBadge({ status }: { status: AnalysisStatus }) {
  const config = ANALYSIS_STATUS_CONFIG[status];
  const colorClasses: Record<string, string> = {
    green: 'bg-green-100 text-green-800 border-green-200',
    blue: 'bg-blue-100 text-blue-800 border-blue-200',
    yellow: 'bg-yellow-100 text-yellow-800 border-yellow-200',
    orange: 'bg-orange-100 text-orange-800 border-orange-200',
    red: 'bg-red-100 text-red-800 border-red-200',
    gray: 'bg-gray-100 text-gray-700 border-gray-200',
  };

  // Extract color name from config.color (e.g., "text-green-600" -> "green")
  const colorName = config.color.split('-')[1] || 'gray';

  return (
    <span
      className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${colorClasses[colorName] || colorClasses.gray}`}
    >
      {config.label}
    </span>
  );
}

/**
 * Discovery Source Badge Component
 */
function DiscoverySourceBadge({ source }: { source: DiscoverySource }) {
  const config = DISCOVERY_SOURCE_CONFIG[source];
  const colorClasses: Record<string, string> = {
    blue: 'bg-blue-100 text-blue-800 border-blue-200',
    green: 'bg-green-100 text-green-800 border-green-200',
    purple: 'bg-purple-100 text-purple-800 border-purple-200',
  };

  // Extract color name from config.color (e.g., "text-green-600" -> "green")
  const colorName = config.color.split('-')[1] || 'blue';

  return (
    <span
      className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${colorClasses[colorName] || colorClasses.blue}`}
    >
      {config.label}
    </span>
  );
}

/**
 * Format date to relative time
 */
function formatRelativeTime(dateInput?: string | Date): string {
  if (!dateInput) return 'Never';
  const date = typeof dateInput === 'string' ? new Date(dateInput) : dateInput;
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffDays = Math.floor(diffMs / 86400000);

  if (diffDays === 0) return 'Today';
  if (diffDays === 1) return 'Yesterday';
  if (diffDays < 7) return `${diffDays}d ago`;
  if (diffDays < 30) return `${Math.floor(diffDays / 7)}w ago`;
  return date.toLocaleDateString();
}

/**
 * CrawledPagesSection Component
 */
export function CrawledPagesSection({ pages, pageAnalyses }: CrawledPagesSectionProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [statusFilter, setStatusFilter] = useState<PageStatus | 'ALL'>('ALL');
  const [analysisStatusFilter, setAnalysisStatusFilter] = useState<AnalysisStatus | 'ALL'>('ALL');
  const [discoverySourceFilter, setDiscoverySourceFilter] = useState<DiscoverySource | 'ALL'>('ALL');
  const [reliabilityFilter, setReliabilityFilter] = useState<ReliabilityStatus | 'all'>('all');
  const [sortField, setSortField] = useState<'url' | 'depth' | 'discoveredAt' | 'lastAnalyzedAt'>('discoveredAt');
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);

  // Filtered and sorted pages
  const filteredPages = useMemo(() => {
    let filtered = pages.filter((page) => {
      // Search filter
      const matchesSearch =
        searchQuery === '' ||
        page.url.toLowerCase().includes(searchQuery.toLowerCase()) ||
        page.title?.toLowerCase().includes(searchQuery.toLowerCase());

      // Status filter
      const matchesStatus = statusFilter === 'ALL' || page.status === statusFilter;

      // Analysis status filter
      const matchesAnalysisStatus =
        analysisStatusFilter === 'ALL' || page.analysisStatus === analysisStatusFilter;

      // Discovery source filter
      const matchesDiscoverySource =
        discoverySourceFilter === 'ALL' || page.discoverySource === discoverySourceFilter;

      // Reliability status filter
      const pageReliabilityStatus = pageAnalyses?.get(page.id)?.reliabilityStatus;
      const matchesReliability =
        reliabilityFilter === 'all' ||
        (pageReliabilityStatus && pageReliabilityStatus === reliabilityFilter);

      return matchesSearch && matchesStatus && matchesAnalysisStatus && matchesDiscoverySource && matchesReliability;
    });

    // Sort
    filtered.sort((a, b) => {
      let aVal, bVal;
      switch (sortField) {
        case 'url':
          aVal = a.url;
          bVal = b.url;
          break;
        case 'depth':
          aVal = a.depth;
          bVal = b.depth;
          break;
        case 'discoveredAt':
          aVal = a.discoveredAt;
          bVal = b.discoveredAt;
          break;
        case 'lastAnalyzedAt':
          aVal = a.lastAnalyzedAt || '';
          bVal = b.lastAnalyzedAt || '';
          break;
        default:
          return 0;
      }

      if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1;
      if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1;
      return 0;
    });

    return filtered;
  }, [pages, searchQuery, statusFilter, analysisStatusFilter, discoverySourceFilter, reliabilityFilter, sortField, sortDirection, pageAnalyses]);

  // Paginated pages for current view
  const paginatedPages = useMemo(() => {
    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return filteredPages.slice(startIndex, endIndex);
  }, [filteredPages, currentPage, pageSize]);

  // Reset to page 1 when filters change
  const resetPagination = () => {
    setCurrentPage(1);
  };

  // Handle sort
  const handleSort = (field: typeof sortField) => {
    if (sortField === field) {
      setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
    } else {
      setSortField(field);
      setSortDirection('asc');
    }
  };

  // Sort icon
  const SortIcon = ({ field }: { field: typeof sortField }) => {
    if (sortField !== field) return null;
    return sortDirection === 'asc' ? <ChevronUp size={14} /> : <ChevronDown size={14} />;
  };

  return (
    <div className="space-y-4">
      {/* Filters */}
      <div className="flex flex-wrap gap-4">
        {/* Search */}
        <div className="flex-1 min-w-[280px] max-w-md relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" size={20} />
          <input
            type="text"
            placeholder="Search by URL or title..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent"
          />
        </div>

        {/* Status Filter */}
        <select
          value={statusFilter}
          onChange={(e) => {
            setStatusFilter(e.target.value as PageStatus | 'ALL');
            resetPagination();
          }}
          className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 text-sm"
        >
          <option value="ALL">All Statuses</option>
          <option value={PageStatus.ACTIVE}>Active</option>
          <option value={PageStatus.EXCLUDED}>Excluded</option>
          <option value={PageStatus.BROKEN}>Broken</option>
          <option value={PageStatus.REDIRECT}>Redirect</option>
        </select>

        {/* Analysis Status Filter */}
        <select
          value={analysisStatusFilter}
          onChange={(e) => {
            setAnalysisStatusFilter(e.target.value as AnalysisStatus | 'ALL');
            resetPagination();
          }}
          className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 text-sm"
        >
          <option value="ALL">All Analysis Status</option>
          <option value={AnalysisStatus.ANALYZED}>Analyzed</option>
          <option value={AnalysisStatus.PENDING}>Pending</option>
          <option value={AnalysisStatus.IN_PROGRESS}>In Progress</option>
          <option value={AnalysisStatus.OUTDATED}>Outdated</option>
          <option value={AnalysisStatus.FAILED}>Failed</option>
          <option value={AnalysisStatus.NONE}>Not Analyzed</option>
        </select>

        {/* Discovery Source Filter */}
        <select
          value={discoverySourceFilter}
          onChange={(e) => {
            setDiscoverySourceFilter(e.target.value as DiscoverySource | 'ALL');
            resetPagination();
          }}
          className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 text-sm"
        >
          <option value="ALL">All Sources</option>
          <option value={DiscoverySource.MANUAL}>Manual</option>
          <option value={DiscoverySource.CRAWL}>Crawl</option>
          <option value={DiscoverySource.LINK_EXTRACTION}>Link Extraction</option>
        </select>

        {/* Reliability Status Filter */}
        <select
          value={reliabilityFilter}
          onChange={(e) => {
            setReliabilityFilter(e.target.value as ReliabilityStatus | 'all');
            resetPagination();
          }}
          className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 text-sm"
        >
          <option value="all">All Reliability</option>
          <option value={ReliabilityStatus.DRAFT}>Draft</option>
          <option value={ReliabilityStatus.PENDING_CONFIRMATION}>Pending</option>
          <option value={ReliabilityStatus.CONFIRMED}>Confirmed</option>
          <option value={ReliabilityStatus.REJECTED}>Rejected</option>
        </select>

        {/* Results Count */}
        <div className="ml-auto flex items-center text-sm text-gray-600">
          <span className="font-medium">{filteredPages.length}</span>
          <span className="ml-1">{filteredPages.length === 1 ? 'page' : 'pages'}</span>
        </div>
      </div>

      {/* Table */}
      <div className="bg-card rounded-lg border border-border shadow-sm overflow-hidden">
        <div className="overflow-x-auto">
          <table className="w-full">
            <thead className="bg-gray-50 border-b border-gray-200">
              <tr>
                <th
                  className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100"
                  onClick={() => handleSort('url')}
                >
                  <div className="flex items-center gap-1">
                    URL
                    <SortIcon field="url" />
                  </div>
                </th>
                <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  Status
                </th>
                <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  Analysis
                </th>
                <th className="hidden md:table-cell px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  Source
                </th>
                <th className="hidden md:table-cell px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  Reliability
                </th>
                <th
                  className="hidden md:table-cell px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100"
                  onClick={() => handleSort('depth')}
                >
                  <div className="flex items-center gap-1">
                    Depth
                    <SortIcon field="depth" />
                  </div>
                </th>
                <th className="hidden lg:table-cell px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  Elements
                </th>
                <th
                  className="hidden md:table-cell px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100"
                  onClick={() => handleSort('lastAnalyzedAt')}
                >
                  <div className="flex items-center gap-1">
                    Last Analyzed
                    <SortIcon field="lastAnalyzedAt" />
                  </div>
                </th>
              </tr>
            </thead>
            <tbody className="bg-white divide-y divide-gray-200">
              {paginatedPages.length === 0 ? (
                <tr>
                  <td colSpan={8} className="px-6 py-12 text-center text-gray-500">
                    {filteredPages.length === 0
                      ? 'No pages found matching your filters'
                      : 'No pages on this page'}
                  </td>
                </tr>
              ) : (
                paginatedPages.map((page) => {
                  const reliabilityStatus = pageAnalyses?.get(page.id)?.reliabilityStatus;
                  return (
                  <tr key={page.id} className="hover:bg-gray-50 transition-colors">
                    <td className="px-6 py-4">
                      <div className="flex items-center gap-2">
                        <a
                          href={page.url}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-sm text-cyan-600 hover:text-cyan-800 hover:underline flex items-center gap-1 max-w-md truncate"
                          title={page.url}
                        >
                          {page.url}
                          <ExternalLink size={12} />
                        </a>
                      </div>
                      {page.title && (
                        <div className="text-xs text-gray-500 mt-1">{page.title}</div>
                      )}
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <StatusBadge status={page.status} />
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <AnalysisStatusBadge status={page.analysisStatus} />
                    </td>
                    <td className="hidden md:table-cell px-6 py-4 whitespace-nowrap">
                      <DiscoverySourceBadge source={page.discoverySource} />
                    </td>
                    <td className="hidden md:table-cell px-6 py-4 whitespace-nowrap">
                      {reliabilityStatus ? (
                        <ReliabilityStatusBadge status={reliabilityStatus} size="sm" />
                      ) : (
                        <span className="text-xs text-gray-400">-</span>
                      )}
                    </td>
                    <td className="hidden md:table-cell px-6 py-4 whitespace-nowrap">
                      <span className="text-sm text-gray-900">{page.depth}</span>
                    </td>
                    <td className="hidden lg:table-cell px-6 py-4 whitespace-nowrap">
                      <span className="text-sm text-gray-900">
                        {page.elementCount || '-'}
                      </span>
                    </td>
                    <td className="hidden md:table-cell px-6 py-4 whitespace-nowrap">
                      <span className="text-sm text-gray-500">
                        {formatRelativeTime(page.lastAnalyzedAt)}
                      </span>
                    </td>
                  </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>

      {/* Pagination */}
      {filteredPages.length > 0 && (
        <Pagination
          currentPage={currentPage}
          pageSize={pageSize}
          totalItems={filteredPages.length}
          onPageChange={setCurrentPage}
          onPageSizeChange={(size) => {
            setPageSize(size);
            resetPagination();
          }}
        />
      )}
    </div>
  );
}
