/**
 * SitePagesSection Component
 *
 * Combined view of site hierarchy and analysed pages with rescan functionality.
 * Features:
 * - Tree view with hierarchy visualization
 * - Rescan all pages button
 * - Add specific URL to scan
 * - Rescan individual pages
 * - Analysis status per page
 *
 * @component
 * @layer Presentation
 */

import { useState, useMemo } from 'react';
import {
  ChevronRight,
  ChevronDown,
  Globe,
  FileText,
  ExternalLink,
  RefreshCw,
  Plus,
  Loader2,
  Database,
  CheckCircle2,
  AlertCircle,
} from 'lucide-react';
import type { DiscoveredPage, PageAnalysis, PageElement } from '@domain/entities';
import { AnalysisStatus, PageStatus } from '@domain/entities';
import { ANALYSIS_STATUS_CONFIG, PAGE_STATUS_CONFIG } from '@domain/constants';
import { PageTrainingDataModal } from './PageTrainingDataModal';
import { Pagination } from '@/components/ui/Pagination';
import type { ScanProgress } from '../../presentation/features/info-center/hooks';
import type { PaginationInfo } from '../../presentation/features/info-center/hooks/useInfoCenter';

interface SitePagesSectionProps {
  pages: DiscoveredPage[];
  tenantId: string;
  pageAnalyses: PageAnalysis[];
  scanProgress: ScanProgress;
  pagination: PaginationInfo;
  onRescanAll: (tenantId: string) => void;
  onRescanPage: (pageId: string) => void;
  onAddUrl: (tenantId: string, url: string) => void;
  onElementUpdate: (analysisId: string, elementId: string, updatedElement: PageElement) => void;
  onPageChange: (page: number) => void;
  onPageSizeChange: (pageSize: number) => void;
}

/**
 * Build tree structure from flat page list
 */
function buildTree(pages: DiscoveredPage[]): TreeNode[] {
  // Create map of pages by ID
  const pageMap = new Map<string, DiscoveredPage>();
  pages.forEach((page) => {
    pageMap.set(page.id, page);
  });

  // Find root pages (no parent)
  const rootPages = pages.filter((page) => !page.parentPageId);

  // Build tree recursively
  function buildNode(page: DiscoveredPage): TreeNode {
    const children = pages
      .filter((p) => p.parentPageId === page.id)
      .map((child) => buildNode(child))
      .sort((a, b) => a.page.url.localeCompare(b.page.url));

    return {
      page,
      children,
    };
  }

  return rootPages.map((page) => buildNode(page)).sort((a, b) => a.page.depth - b.page.depth);
}

/**
 * Tree Node Interface
 */
interface TreeNode {
  page: DiscoveredPage;
  children: TreeNode[];
}

/**
 * Analysis Status Badge
 */
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 py-0.5 rounded-full text-xs font-medium border ${colorClasses[colorName] || colorClasses.gray}`}
    >
      {config.label}
    </span>
  );
}

/**
 * Page Status Badge
 */
function PageStatusBadge({ status }: { status: PageStatus }) {
  const config = PAGE_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',
    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 py-0.5 rounded-full text-xs font-medium border ${colorClasses[colorName] || colorClasses.gray}`}
    >
      {config.label}
    </span>
  );
}

/**
 * TreeNode Component (Recursive)
 */
function TreeNodeComponent({
  node,
  depth = 0,
  onRescanPage,
  rescanningPageId,
  onViewTrainingData,
}: {
  node: TreeNode;
  depth?: number;
  onRescanPage: (pageId: string) => void;
  rescanningPageId: string | null;
  onViewTrainingData: (url: string) => void;
}) {
  const [isExpanded, setIsExpanded] = useState(depth < 2); // Auto-expand first 2 levels
  const hasChildren = node.children.length > 0;
  const isRescanning = rescanningPageId === node.page.id;

  return (
    <div>
      <div
        className={`flex items-center gap-2 py-2 px-3 hover:bg-gray-50 rounded-lg transition-colors group`}
        style={{ paddingLeft: `${depth * 24 + 12}px` }}
      >
        {/* Expand/Collapse Icon */}
        <div className="flex-shrink-0 w-4">
          {hasChildren ? (
            <button
              onClick={() => setIsExpanded(!isExpanded)}
              className="hover:bg-gray-200 rounded p-0.5"
            >
              {isExpanded ? (
                <ChevronDown size={16} className="text-gray-500" />
              ) : (
                <ChevronRight size={16} className="text-gray-500" />
              )}
            </button>
          ) : null}
        </div>

        {/* Page Icon */}
        <div className="flex-shrink-0">
          {depth === 0 ? (
            <Globe size={16} className="text-blue-600" />
          ) : (
            <FileText size={16} className="text-gray-500" />
          )}
        </div>

        {/* Full URL */}
        <a
          href={node.page.url}
          target="_blank"
          rel="noopener noreferrer"
          className="text-sm text-cyan-600 hover:text-cyan-800 hover:underline flex items-center gap-1 flex-1 min-w-0"
          onClick={(e) => e.stopPropagation()}
          title={node.page.url}
        >
          <span className="truncate">{node.page.url}</span>
          <ExternalLink size={12} className="flex-shrink-0" />
        </a>

        {/* Page Title (if available) */}
        {node.page.title && (
          <span className="text-xs text-gray-600 truncate max-w-xs" title={node.page.title}>
            {node.page.title}
          </span>
        )}

        {/* Element Count */}
        {node.page.elementCount !== undefined && (
          <span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded flex-shrink-0">
            {node.page.elementCount} elements
          </span>
        )}

        {/* Page Status */}
        <PageStatusBadge status={node.page.status} />

        {/* Analysis Status */}
        <AnalysisStatusBadge status={node.page.analysisStatus} />

        {/* Depth Badge */}
        <span className="text-xs text-gray-400 flex-shrink-0">L{node.page.depth}</span>

        {/* View Training Data Button */}
        <button
          onClick={() => onViewTrainingData(node.page.url)}
          className="opacity-0 group-hover:opacity-100 transition-opacity p-1 hover:bg-purple-100 rounded text-purple-600 hover:text-purple-800 flex-shrink-0"
          title="View Training Data"
        >
          <Database size={14} />
        </button>

        {/* Rescan Button */}
        <button
          onClick={() => onRescanPage(node.page.id)}
          disabled={isRescanning}
          className="opacity-0 group-hover:opacity-100 transition-opacity p-1 hover:bg-cyan-100 rounded text-cyan-600 hover:text-cyan-800 disabled:opacity-50 disabled:cursor-not-allowed flex-shrink-0"
          title="Rescan this page"
        >
          {isRescanning ? (
            <Loader2 size={14} className="animate-spin" />
          ) : (
            <RefreshCw size={14} />
          )}
        </button>
      </div>

      {/* Children */}
      {hasChildren && isExpanded && (
        <div>
          {node.children.map((child) => (
            <TreeNodeComponent
              key={child.page.id}
              node={child}
              depth={depth + 1}
              onRescanPage={onRescanPage}
              rescanningPageId={rescanningPageId}
              onViewTrainingData={onViewTrainingData}
            />
          ))}
        </div>
      )}
    </div>
  );
}

/**
 * SitePagesSection Component
 */
export function SitePagesSection({
  pages,
  tenantId,
  pageAnalyses,
  scanProgress,
  pagination,
  onRescanAll,
  onRescanPage,
  onAddUrl,
  onElementUpdate,
  onPageChange,
  onPageSizeChange,
}: SitePagesSectionProps) {
  const [newUrl, setNewUrl] = useState('');
  const [rescanningPageId, setRescanningPageId] = useState<string | null>(null);
  const [viewingPageUrl, setViewingPageUrl] = useState<string | null>(null);

  // Derive scanning state from scanProgress prop
  const isScanning = scanProgress.status === 'scanning';
  const isScanCompleted = scanProgress.status === 'completed';
  const isScanError = scanProgress.status === 'error';

  // Build tree structure
  const tree = useMemo(() => buildTree(pages), [pages]);

  // Calculate stats
  const stats = useMemo(() => {
    const depthCounts: Record<number, number> = {};
    let maxDepth = 0;

    pages.forEach((page) => {
      depthCounts[page.depth] = (depthCounts[page.depth] || 0) + 1;
      maxDepth = Math.max(maxDepth, page.depth);
    });

    return { depthCounts, maxDepth };
  }, [pages]);

  /**
   * Handle rescan all - delegates to parent hook which manages scan state
   */
  const handleRescanAll = () => {
    // Prevent multiple scans - button should be disabled but double check
    if (isScanning) return;
    onRescanAll(tenantId);
  };

  /**
   * Handle rescan page
   */
  const handleRescanPage = async (pageId: string) => {
    setRescanningPageId(pageId);
    try {
      await onRescanPage(pageId);
    } finally {
      setRescanningPageId(null);
    }
  };

  /**
   * Handle add URL
   */
  const handleAddUrl = () => {
    if (!newUrl.trim()) return;

    // Validate URL
    try {
      new URL(newUrl);
      onAddUrl(tenantId, newUrl.trim());
      setNewUrl('');
    } catch (error) {
      alert('Please enter a valid URL (e.g., https://example.com/page)');
    }
  };

  /**
   * Handle view training data
   */
  const handleViewTrainingData = (url: string) => {
    setViewingPageUrl(url);
  };

  return (
    <div className="space-y-4">
      {/* Header with Actions */}
      <div className="flex items-center justify-between gap-4">
        <div className="flex items-center gap-3">
          <div className="flex-shrink-0 w-10 h-10 rounded-lg bg-purple-100 flex items-center justify-center">
            <Globe className="w-5 h-5 text-purple-600" />
          </div>
          <div>
            <h3 className="text-lg font-semibold text-gray-900">Site Pages & Hierarchy</h3>
            <p className="text-sm text-gray-500">
              {pages.length} pages (max depth: {stats.maxDepth})
            </p>
          </div>
        </div>

        {/* Rescan All Button */}
        <button
          onClick={handleRescanAll}
          disabled={isScanning}
          className="px-4 py-2 text-sm font-medium text-white bg-cyan-600 hover:bg-cyan-700 disabled:bg-gray-400 disabled:cursor-not-allowed rounded-lg transition-all shadow-md hover:shadow-lg flex items-center gap-2"
        >
          {isScanning ? (
            <Loader2 size={16} className="animate-spin" />
          ) : isScanCompleted ? (
            <CheckCircle2 size={16} />
          ) : isScanError ? (
            <AlertCircle size={16} />
          ) : (
            <RefreshCw size={16} />
          )}
          {isScanning ? 'Scanning...' : isScanCompleted ? 'Completed!' : isScanError ? 'Error' : 'Rescan All'}
        </button>
      </div>

      {/* Scan Progress Indicator */}
      {(isScanning || isScanCompleted || isScanError) && (
        <div className={`rounded-lg p-4 border ${
          isScanning ? 'bg-blue-50 border-blue-200' :
          isScanCompleted ? 'bg-green-50 border-green-200' :
          'bg-red-50 border-red-200'
        }`}>
          <div className="flex items-center gap-3">
            {isScanning ? (
              <Loader2 size={20} className="animate-spin text-blue-600" />
            ) : isScanCompleted ? (
              <CheckCircle2 size={20} className="text-green-600" />
            ) : (
              <AlertCircle size={20} className="text-red-600" />
            )}
            <div className="flex-1">
              <div className="flex items-center justify-between">
                <span className={`font-medium ${
                  isScanning ? 'text-blue-900' :
                  isScanCompleted ? 'text-green-900' :
                  'text-red-900'
                }`}>
                  {isScanning ? 'Analysis in Progress' :
                   isScanCompleted ? 'Analysis Jobs Queued' :
                   'Analysis Failed'}
                </span>
                <span className="text-sm text-gray-600">
                  {scanProgress.completedPages} / {scanProgress.totalPages} pages
                  {scanProgress.failedPages > 0 && (
                    <span className="text-red-600 ml-2">
                      ({scanProgress.failedPages} failed)
                    </span>
                  )}
                </span>
              </div>
              {isScanning && scanProgress.currentPage && (
                <p className="text-sm text-gray-600 mt-1">
                  {scanProgress.currentPage}
                </p>
              )}
              {isScanCompleted && (
                <p className="text-sm text-green-700 mt-1">
                  Full site scan has been scheduled. The Scout crawler will crawl your website, discover pages, and analyze training data. Refresh to see updates.
                </p>
              )}
              {isScanError && scanProgress.errorMessage && (
                <p className="text-sm text-red-700 mt-1">
                  {scanProgress.errorMessage}
                </p>
              )}
            </div>
          </div>
          {/* Progress bar */}
          {isScanning && (
            <div className="mt-3">
              <div className="h-2 bg-gray-200 rounded-full overflow-hidden">
                <div
                  className="h-full bg-blue-600 transition-all duration-300"
                  style={{ width: `${scanProgress.progress}%` }}
                />
              </div>
              <div className="text-xs text-gray-500 mt-1 text-right">
                {scanProgress.progress}% complete
              </div>
            </div>
          )}
        </div>
      )}

      {/* Add URL Input */}
      <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
        <div className="flex items-center gap-3">
          <div className="flex-1">
            <label htmlFor="newUrl" className="block text-sm font-medium text-gray-700 mb-2">
              Add URL to scan
            </label>
            <input
              id="newUrl"
              type="url"
              value={newUrl}
              onChange={(e) => setNewUrl(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && handleAddUrl()}
              placeholder="https://example.com/page"
              className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent"
            />
          </div>
          <button
            onClick={handleAddUrl}
            disabled={!newUrl.trim()}
            className="mt-7 px-4 py-2 text-sm font-medium text-white bg-green-600 hover:bg-green-700 disabled:bg-gray-400 rounded-lg transition-all shadow-md hover:shadow-lg flex items-center gap-2"
          >
            <Plus size={16} />
            Add & Scan
          </button>
        </div>
      </div>

      {/* Depth Distribution */}
      <div className="flex items-center gap-4 px-4">
        <span className="text-sm font-medium text-gray-700">Depth distribution:</span>
        {Object.entries(stats.depthCounts)
          .sort(([a], [b]) => Number(a) - Number(b))
          .map(([depth, count]) => (
            <div key={depth} className="text-sm">
              <span className="text-gray-500">L{depth}:</span>{' '}
              <span className="font-medium text-gray-900">{count}</span>
            </div>
          ))}
      </div>

      {/* Tree View */}
      <div className="bg-card rounded-lg border border-border shadow-sm p-4">
        {tree.length === 0 ? (
          <div className="text-center py-12 text-gray-500">
            <Globe className="mx-auto h-12 w-12 text-gray-400 mb-4" />
            <p>No pages to display</p>
            <p className="text-sm mt-2">Add a URL above to start scanning</p>
          </div>
        ) : (
          <div className="space-y-1">
            {tree.map((node) => (
              <TreeNodeComponent
                key={node.page.id}
                node={node}
                onRescanPage={handleRescanPage}
                rescanningPageId={rescanningPageId}
                onViewTrainingData={handleViewTrainingData}
              />
            ))}
          </div>
        )}
      </div>

      {/* Pagination Controls */}
      {pagination.total > 0 && (
        <div className="bg-card rounded-lg border border-border shadow-sm">
          <Pagination
            currentPage={pagination.page}
            pageSize={pagination.limit}
            totalItems={pagination.total}
            onPageChange={onPageChange}
            onPageSizeChange={onPageSizeChange}
          />
        </div>
      )}

      {/* Legend */}
      <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
        <div className="text-sm font-medium text-gray-700 mb-2">Legend:</div>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-xs text-gray-600">
          <div className="flex items-center gap-1">
            <Globe size={14} className="text-blue-600" />
            <span>Root page</span>
          </div>
          <div className="flex items-center gap-1">
            <FileText size={14} className="text-gray-500" />
            <span>Child page</span>
          </div>
          <div className="flex items-center gap-1">
            <span className="text-gray-400">L0, L1, L2...</span>
            <span>Depth level</span>
          </div>
          <div className="flex items-center gap-1">
            <Database size={14} className="text-purple-600" />
            <span>Training Data (hover)</span>
          </div>
          <div className="flex items-center gap-1">
            <RefreshCw size={14} className="text-cyan-600" />
            <span>Rescan (hover to show)</span>
          </div>
        </div>
      </div>

      {/* PageTrainingDataModal */}
      {viewingPageUrl && (
        <PageTrainingDataModal
          pageUrl={viewingPageUrl}
          analysis={pageAnalyses.find((a) => a.url === viewingPageUrl) || null}
          onClose={() => setViewingPageUrl(null)}
          onElementUpdate={onElementUpdate}
        />
      )}
    </div>
  );
}
