// File: src/pages/User/FileManager/Search/SearchResults.jsx
// UIX version - Theme-aware Search Results with Layout
import React, { useState, useEffect, useCallback, useRef, useMemo, memo } from "react";
import { useNavigate, useSearchParams } from "react-router";
import { useFiles, useCrypto, useAuth } from "../../../../services/Services";
import withPasswordProtection from "../../../../hocs/withPasswordProtection";
import Layout from "../../../../components/Layout/Layout";
import {
  Button,
  Input,
  Alert,
  useUIXTheme,
  Breadcrumb,
  Card,
  EmptyState,
  Modal,
  InfoNotice
} from "../../../../components/UIX";
import {
  MagnifyingGlassIcon,
  FolderIcon,
  DocumentIcon,
  PhotoIcon,
  ArrowDownTrayIcon,
  HomeIcon,
  ShieldCheckIcon,
  ExclamationTriangleIcon,
} from "@heroicons/react/24/outline";

// Search configuration constants
const MAX_SEARCH_LENGTH = 100;
const MIN_SEARCH_LENGTH = 2;
const SEARCH_DEBOUNCE_MS = 300;
const RESULTS_PER_PAGE = 20;
const LARGE_FILE_SIZE_MB = 50;

const SearchResults = memo(function SearchResults() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const query = searchParams.get("q") || "";
  const { getThemeClasses } = useUIXTheme();
  const isMountedRef = useRef(true);

  const { listFileManager, listCollectionManager, downloadFileManager } =
    useFiles();
  const { CollectionCryptoService } = useCrypto();
  const { authManager } = useAuth();

  // GDPR-compliant logging - sanitize PII
  const logError = useCallback((context, error) => {
    if (import.meta.env.DEV) {
      console.error(`[SearchResults] ${context}:`, error?.message || 'Unknown error');
    }
  }, []);

  // Search query validation
  const validateSearchQuery = useCallback((searchTerm) => {
    if (!searchTerm || !searchTerm.trim()) {
      return { valid: false, error: "Please enter a search term" };
    }
    if (searchTerm.length < MIN_SEARCH_LENGTH) {
      return { valid: false, error: `Search must be at least ${MIN_SEARCH_LENGTH} characters` };
    }
    if (searchTerm.length > MAX_SEARCH_LENGTH) {
      return { valid: false, error: `Search must be less than ${MAX_SEARCH_LENGTH} characters` };
    }
    // Basic XSS prevention - check for suspicious patterns
    if (/<script|javascript:|onerror=/i.test(searchTerm)) {
      return { valid: false, error: "Invalid search query" };
    }
    return { valid: true };
  }, []);

  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState("");
  const [searchQuery, setSearchQuery] = useState(query);
  const [results, setResults] = useState({ files: [], collections: [] });
  const [downloadingFiles, setDownloadingFiles] = useState(new Set());
  const [showDownloadModal, setShowDownloadModal] = useState(false);
  const [fileToDownload, setFileToDownload] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [searchCache, setSearchCache] = useState(new Map());

  // Refs for cleanup and debouncing
  const searchDebounceRef = useRef(null);

  // Ref to hold cache for cleanup (avoids stale closure)
  const searchCacheRef = useRef(searchCache);
  searchCacheRef.current = searchCache;

  useEffect(() => {
    isMountedRef.current = true;
    return () => {
      isMountedRef.current = false;
      if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);
      // Clear search cache on unmount to prevent memory leaks
      searchCacheRef.current.clear();
    };
  }, []);

  // Sanitize filename to prevent path traversal and special character issues
  const sanitizeFilename = useCallback((filename) => {
    return filename
      .replace(/[^a-z0-9_-]/gi, '_')  // Replace non-alphanumeric with underscore
      .replace(/_+/g, '_')             // Collapse multiple underscores
      .substring(0, 50);               // Limit length
  }, []);

  // Export search results (GDPR Article 20 - Data Portability)
  const handleExportResults = useCallback(() => {
    const exportData = {
      search_query: query,
      exported_at: new Date().toISOString(),
      total_results: results.collections.length + results.files.length,
      collections: results.collections.map(c => ({
        name: c.name,
        file_count: c.file_count
      })),
      files: results.files.map(f => ({
        name: f.name,
        size: f.size,
        mime_type: f.mime_type
      }))
    };

    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    // Sanitize query for safe filename
    const safeQuery = sanitizeFilename(query || 'export');
    a.download = `search_results_${safeQuery}_${Date.now()}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, [query, results, sanitizeFilename]);

  // Search function with caching and validation
  const performSearch = useCallback(
    async (searchTerm) => {
      // Validate search query
      const validation = validateSearchQuery(searchTerm);
      if (!validation.valid) {
        setError(validation.error);
        return;
      }

      if (!listFileManager || !listCollectionManager) return;

      // Check cache first
      const cacheKey = searchTerm.toLowerCase().trim();
      if (searchCache.has(cacheKey)) {
        const cachedResults = searchCache.get(cacheKey);
        setResults(cachedResults);
        setCurrentPage(1);
        return;
      }

      setIsLoading(true);
      setError("");
      setCurrentPage(1);

      try {
        // Search in collections
        const collectionsResult =
          await listCollectionManager.listCollections(false);
        let matchedCollections = [];

        if (collectionsResult.collections) {
          const searchLower = searchTerm.toLowerCase();
          matchedCollections = collectionsResult.collections.filter(
            (collection) => {
              const name = collection.name || "";
              return name.toLowerCase().includes(searchLower);
            },
          );
        }

        // Search in files across all collections
        const filesResult = await listFileManager.listFiles({
          states: ["active"],
          force_refresh: false,
        });

        let matchedFiles = [];
        if (filesResult.files) {
          const searchLower = searchTerm.toLowerCase();
          matchedFiles = filesResult.files.filter((file) => {
            const name = file.name || "";
            return name.toLowerCase().includes(searchLower);
          });
        }

        const searchResults = {
          collections: matchedCollections,
          files: matchedFiles,
        };

        if (isMountedRef.current) {
          setResults(searchResults);
          // Cache results
          setSearchCache(prev => {
            const newCache = new Map(prev);
            newCache.set(cacheKey, searchResults);
            // Limit cache size to 10 recent searches
            if (newCache.size > 10) {
              const firstKey = newCache.keys().next().value;
              newCache.delete(firstKey);
            }
            return newCache;
          });
        }
      } catch (err) {
        if (isMountedRef.current) {
          setError("Search failed. Please try again.");
        }
        logError("Search error", err);
      } finally {
        if (isMountedRef.current) {
          setIsLoading(false);
        }
      }
    },
    [listFileManager, listCollectionManager, validateSearchQuery, searchCache, logError],
  );

  // Perform initial search
  useEffect(() => {
    if (
      query &&
      listFileManager &&
      listCollectionManager &&
      authManager?.isAuthenticated()
    ) {
      performSearch(query);
    }
  }, [
    query,
    listFileManager,
    listCollectionManager,
    authManager,
    performSearch,
  ]);

  // Handle new search with debouncing
  const handleSearch = useCallback((e) => {
    e?.preventDefault();

    // Clear any pending debounce
    if (searchDebounceRef.current) {
      clearTimeout(searchDebounceRef.current);
    }

    const trimmedQuery = searchQuery.trim();
    if (!trimmedQuery) {
      setError("Please enter a search term");
      return;
    }

    // Debounce search (300ms) to prevent spam
    searchDebounceRef.current = setTimeout(() => {
      navigate(`/file-manager/search?q=${encodeURIComponent(trimmedQuery)}`);
      performSearch(trimmedQuery);
    }, SEARCH_DEBOUNCE_MS);
  }, [navigate, searchQuery, performSearch]);

  // Initiate file download
  const initiateDownload = useCallback((file) => {
    const fileSizeMB = file.size / 1024 / 1024;

    // Show confirmation modal for large files
    if (fileSizeMB > LARGE_FILE_SIZE_MB) {
      setFileToDownload(file);
      setShowDownloadModal(true);
    } else {
      handleDownloadFile(file.id, file.name);
    }
  }, []);

  // Handle file download
  const handleDownloadFile = useCallback(async (fileId, fileName) => {
    if (!downloadFileManager) return;

    setShowDownloadModal(false);
    setFileToDownload(null);

    try {
      setDownloadingFiles((prev) => new Set(prev).add(fileId));
      await downloadFileManager.downloadFile(fileId, { saveToDisk: true });
    } catch (err) {
      if (isMountedRef.current) {
        setError("Could not download file");
      }
      logError("Download failed", err);
    } finally {
      if (isMountedRef.current) {
        setDownloadingFiles((prev) => {
          const next = new Set(prev);
          next.delete(fileId);
          return next;
        });
      }
    }
  }, [downloadFileManager, logError]);

  // Get file icon
  const getFileIcon = useCallback((file) => {
    const mimeType = file.mime_type || "";
    if (mimeType.startsWith("image/"))
      return <PhotoIcon className={`h-5 w-5 ${getThemeClasses("text-accent")}`} />;
    return <DocumentIcon className={`h-5 w-5 ${getThemeClasses("text-secondary")}`} />;
  }, [getThemeClasses]);

  const totalResults = results.collections.length + results.files.length;

  // Memoize breadcrumb items
  const breadcrumbItems = useMemo(() => [
    {
      label: "My Files",
      to: "/file-manager",
      icon: HomeIcon,
    },
    {
      label: "Search",
      isActive: true,
    },
  ], []);

  // Paginated results
  const paginatedResults = useMemo(() => {
    const allItems = [
      ...results.collections.map(c => ({ ...c, type: 'collection' })),
      ...results.files.map(f => ({ ...f, type: 'file' }))
    ];

    const startIndex = (currentPage - 1) * RESULTS_PER_PAGE;
    const endIndex = startIndex + RESULTS_PER_PAGE;

    return {
      items: allItems.slice(startIndex, endIndex),
      totalPages: Math.ceil(allItems.length / RESULTS_PER_PAGE),
      totalItems: allItems.length
    };
  }, [results, currentPage]);

  // Handle page change
  const handlePageChange = useCallback((newPage) => {
    setCurrentPage(newPage);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }, []);

  return (
    <Layout>
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        {/* Breadcrumb Navigation */}
        <Breadcrumb items={breadcrumbItems} />

        {/* Main Card */}
        <Card>
          {/* Header */}
          <div className={`p-6 border-b ${getThemeClasses("border-secondary")}`}>
            <div className="flex items-center">
              <div className={`h-12 w-12 ${getThemeClasses("bg-gradient-secondary")} rounded-xl flex items-center justify-center mr-4`}>
                <MagnifyingGlassIcon className="h-6 w-6 text-white" />
              </div>
              <div>
                <h1 className={`text-2xl font-bold ${getThemeClasses("text-primary")}`}>
                  Search Files & Folders
                </h1>
                <p className={`${getThemeClasses("text-secondary")} mt-1`}>
                  Search across all your encrypted files and folders
                </p>
              </div>
            </div>
          </div>

          {/* Search Bar */}
          <div className="px-6 pt-6">
            <form onSubmit={handleSearch} className="mb-6">
              <div className="flex items-center space-x-3">
                <div className="flex-1">
                  <Input
                    type="text"
                    value={searchQuery}
                    onChange={setSearchQuery}
                    placeholder="Search files and folders..."
                    icon={MagnifyingGlassIcon}
                    autoFocus
                    size="md"
                    maxLength={MAX_SEARCH_LENGTH}
                  />
                </div>
                <Button
                  type="submit"
                  disabled={isLoading || !searchQuery.trim()}
                  variant="primary"
                  size="md"
                >
                  {isLoading ? "Searching..." : "Search"}
                </Button>
              </div>
            </form>

            {/* Privacy Notice - GDPR Article 13 */}
            <InfoNotice
              variant="security"
              icon={ShieldCheckIcon}
              compact
              className="mb-4"
            >
              Your searches are processed locally and encrypted. File and folder names may contain personal information. Search queries are not stored permanently.
            </InfoNotice>
          </div>

          {/* Content */}
          <div className="px-6 pb-6">
            {/* Error Message */}
            {error && (
              <Alert type="error" className="mb-6">
                {error}
              </Alert>
            )}

            {/* Results */}
            {isLoading ? (
              <div className="flex items-center justify-center py-12">
                <div className="text-center">
                  <div className={`animate-spin rounded-full h-8 w-8 border-b-2 mx-auto mb-4 ${getThemeClasses("border-accent")}`}></div>
                  <p className={getThemeClasses("text-secondary")}>Searching...</p>
                </div>
              </div>
            ) : query && totalResults === 0 ? (
              <EmptyState
                icon={MagnifyingGlassIcon}
                title="No results found"
                message={`No files or folders match "${query}". Try different keywords or check your spelling.`}
              />
            ) : query ? (
              <div className="space-y-6">
                {/* Results Summary with Export */}
                <div className="flex items-center justify-between">
                  <div className={`flex-1 p-4 ${getThemeClasses("bg-accent-light")} border ${getThemeClasses("border-accent")} rounded-lg`}>
                    <p className={`text-sm font-medium ${getThemeClasses("text-accent")}`}>
                      Found {totalResults} result{totalResults !== 1 ? "s" : ""} for "{query}"
                      {paginatedResults.totalPages > 1 && ` (Page ${currentPage} of ${paginatedResults.totalPages})`}
                    </p>
                  </div>
                  {totalResults > 0 && (
                    <Button
                      onClick={handleExportResults}
                      variant="secondary"
                      size="sm"
                      className="ml-3"
                      title="Export search results (GDPR Article 20)"
                    >
                      Export
                    </Button>
                  )}
                </div>

                {/* Paginated Results */}
                {paginatedResults.items.length > 0 && (
                  <div>
                    <h2 className={`text-lg font-semibold mb-4 ${getThemeClasses("text-primary")}`}>
                      Results
                    </h2>
                    <div className="space-y-2">
                      {paginatedResults.items.map((item) => (
                        item.type === 'collection' ? (
                          // Collection Card
                          <div
                            key={`collection-${item.id}`}
                            onClick={() =>
                              navigate(`/file-manager/collections/${item.id}`)
                            }
                            className={`${getThemeClasses("bg-card")} rounded-lg border ${getThemeClasses("border-secondary")} p-4 hover:shadow-md hover:border-2 ${getThemeClasses("hover:border-accent")} cursor-pointer transition-all duration-200`}
                          >
                            <div className="flex items-center space-x-3">
                              <div className={`flex items-center justify-center h-12 w-12 rounded-lg ${getThemeClasses("bg-gradient-accent")}`}>
                                <FolderIcon className="h-6 w-6 text-white" />
                              </div>
                              <div className="flex-1 min-w-0">
                                <div className="flex items-center space-x-2">
                                  <h3 className={`font-semibold truncate ${getThemeClasses("text-primary")}`}>
                                    {item.name || "Encrypted Folder"}
                                  </h3>
                                  <span className={`text-xs px-2 py-0.5 rounded-full ${getThemeClasses("bg-accent-light")} ${getThemeClasses("text-accent")}`}>
                                    Folder
                                  </span>
                                </div>
                                <p className={`text-sm ${getThemeClasses("text-secondary")}`}>
                                  {(item.file_count || 0) === 1 ? "1 file" : `${item.file_count || 0} files`}
                                </p>
                              </div>
                            </div>
                          </div>
                        ) : (
                          // File Item
                          <div
                            key={`file-${item.id}`}
                            className={`${getThemeClasses("bg-card")} rounded-lg border ${getThemeClasses("border-secondary")} p-4 ${getThemeClasses("hover:bg-muted")} transition-colors duration-200`}
                          >
                            <div className="flex items-center justify-between">
                              <div
                                className="flex items-center space-x-3 flex-1 cursor-pointer"
                                onClick={() =>
                                  navigate(`/file-manager/files/${item.id}`)
                                }
                              >
                                <div className={`flex items-center justify-center h-12 w-12 rounded-lg ${getThemeClasses("bg-muted")}`}>
                                  {getFileIcon(item)}
                                </div>
                                <div className="flex-1 min-w-0">
                                  <div className="flex items-center space-x-2">
                                    <h3 className={`font-medium truncate ${getThemeClasses("text-primary")}`}>
                                      {item.name || "Encrypted File"}
                                    </h3>
                                    <span className={`text-xs px-2 py-0.5 rounded-full ${getThemeClasses("bg-muted")} ${getThemeClasses("text-secondary")}`}>
                                      File
                                    </span>
                                  </div>
                                  <p className={`text-sm ${getThemeClasses("text-secondary")}`}>
                                    {item.size
                                      ? `${(item.size / 1024 / 1024).toFixed(2)} MB`
                                      : "Unknown size"}
                                  </p>
                                </div>
                              </div>
                              <button
                                onClick={(e) => {
                                  e.stopPropagation();
                                  initiateDownload(item);
                                }}
                                disabled={
                                  !item._isDecrypted || downloadingFiles.has(item.id)
                                }
                                className={`p-2 rounded-lg ${getThemeClasses("text-muted")} ${getThemeClasses("hover:text-primary")} ${getThemeClasses("hover:bg-accent-light")} disabled:opacity-50 transition-all duration-200`}
                                title="Download file"
                              >
                                {downloadingFiles.has(item.id) ? (
                                  <div className={`animate-spin rounded-full h-5 w-5 border-b-2 ${getThemeClasses("border-accent")}`}></div>
                                ) : (
                                  <ArrowDownTrayIcon className="h-5 w-5" />
                                )}
                              </button>
                            </div>
                          </div>
                        )
                      ))}
                    </div>

                    {/* Pagination Controls */}
                    {paginatedResults.totalPages > 1 && (
                      <div className="flex items-center justify-center space-x-2 mt-6">
                        <Button
                          onClick={() => handlePageChange(currentPage - 1)}
                          disabled={currentPage === 1}
                          variant="secondary"
                          size="sm"
                        >
                          Previous
                        </Button>
                        <div className="flex items-center space-x-1">
                          {Array.from({ length: paginatedResults.totalPages }, (_, i) => i + 1)
                            .filter(page => {
                              // Show first page, last page, current page, and pages around current
                              return page === 1 ||
                                     page === paginatedResults.totalPages ||
                                     Math.abs(page - currentPage) <= 1;
                            })
                            .map((page, index, array) => (
                              <React.Fragment key={page}>
                                {index > 0 && array[index - 1] !== page - 1 && (
                                  <span className={getThemeClasses("text-secondary")}>...</span>
                                )}
                                <Button
                                  onClick={() => handlePageChange(page)}
                                  variant={page === currentPage ? "primary" : "secondary"}
                                  size="sm"
                                  className="min-w-[40px]"
                                >
                                  {page}
                                </Button>
                              </React.Fragment>
                            ))}
                        </div>
                        <Button
                          onClick={() => handlePageChange(currentPage + 1)}
                          disabled={currentPage === paginatedResults.totalPages}
                          variant="secondary"
                          size="sm"
                        >
                          Next
                        </Button>
                      </div>
                    )}
                  </div>
                )}
              </div>
            ) : (
              <EmptyState
                icon={MagnifyingGlassIcon}
                title="Start Searching"
                message="Enter keywords above to search across all your encrypted files and folders."
              />
            )}
          </div>
        </Card>
      </div>

      {/* Download Confirmation Modal for Large Files */}
      <Modal
        isOpen={showDownloadModal}
        onClose={() => setShowDownloadModal(false)}
        title="Download Large File"
        footer={
          <div className="flex justify-end space-x-3">
            <Button
              onClick={() => setShowDownloadModal(false)}
              variant="secondary"
              disabled={downloadingFiles.has(fileToDownload?.id)}
            >
              Cancel
            </Button>
            <Button
              onClick={() => handleDownloadFile(fileToDownload?.id, fileToDownload?.name)}
              variant="primary"
              disabled={downloadingFiles.has(fileToDownload?.id)}
            >
              {downloadingFiles.has(fileToDownload?.id) ? (
                <>
                  <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2"></div>
                  Downloading...
                </>
              ) : (
                "Download"
              )}
            </Button>
          </div>
        }
      >
        <div className="py-4">
          <div className="flex items-start space-x-3 mb-4">
            <ExclamationTriangleIcon className={`h-6 w-6 ${getThemeClasses("text-warning")} flex-shrink-0 mt-0.5`} />
            <div>
              <p className={`text-base ${getThemeClasses("text-primary")} font-medium mb-2`}>
                This is a large file ({fileToDownload ? (fileToDownload.size / 1024 / 1024).toFixed(2) : 0} MB)
              </p>
              <p className={`text-sm ${getThemeClasses("text-secondary")}`}>
                Downloading large files may consume significant bandwidth and storage space. Are you sure you want to proceed?
              </p>
            </div>
          </div>
          <p className={`text-sm ${getThemeClasses("text-secondary")}`}>
            <strong>File:</strong> {fileToDownload?.name || "Unknown"}
          </p>
        </div>
      </Modal>
    </Layout>
  );
});

export default withPasswordProtection(SearchResults);
