import React, { useState, useEffect, useRef } from 'react';
import {
  IPaper,
  getLibrary,
  searchLibrary,
  importPDF,
  exportLibrary,
  deletePapers
} from '../api';
import { PaperCard } from './PaperCard';
import { showError, showSuccess } from '../utils/notifications';
import { SearchBar } from './SearchBar';
import { ErrorDisplay } from './ErrorDisplay';
import { LoadingState } from './LoadingState';
import { DetailView } from './DetailView';
import { getPaperKey, hasFullPDF } from '../utils/paper';
import { AppEvents } from '../utils/events';

export const LibraryTab: React.FC = () => {
  const [papers, setPapers] = useState<IPaper[]>([]);
  const [searchQuery, setSearchQuery] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [isUploading, setIsUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedPaper, setSelectedPaper] = useState<IPaper | null>(null);
  const [selectedPapers, setSelectedPapers] = useState<Set<number>>(new Set());
  const fileInputRef = useRef<HTMLInputElement>(null);

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

  const loadLibrary = async () => {
    setIsLoading(true);
    setError(null);
    try {
      const data = await getLibrary();
      setPapers(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load library');
    } finally {
      setIsLoading(false);
    }
  };

  const handleFileSelect = async (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = event.target.files?.[0];
    if (!file) {
      return;
    }

    // Validate file type
    if (file.type !== 'application/pdf' && !file.name.endsWith('.pdf')) {
      setError('Please select a PDF file');
      return;
    }

    // Validate file size (max 50MB)
    if (file.size > 50 * 1024 * 1024) {
      setError('File size must be less than 50MB');
      return;
    }

    setIsUploading(true);
    setError(null);

    try {
      // Get AI config from settings if available
      // For now, pass undefined - settings will be read on backend
      const result = await importPDF(file);
      // Refresh library to show new paper
      await loadLibrary();
      if (result.is_duplicate) {
        if (result.already_has_pdf) {
          showSuccess(
            'PDF Already in Library',
            `"${result.paper.title}" already exists in your library with a full PDF.`
          );
        } else {
          showSuccess(
            'PDF Updated Existing Paper',
            `"${result.paper.title}" was already in your library (metadata-only). The PDF has been added and the entry updated.`
          );
        }
      } else {
        showSuccess(
          'PDF Uploaded',
          `Successfully imported: ${result.paper.title}`
        );
      }
      // Reset file input
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    } catch (err) {
      const errorMessage =
        err instanceof Error ? err.message : 'PDF upload failed';
      setError(errorMessage);
      showError(
        'PDF Upload Failed',
        errorMessage,
        err instanceof Error ? err : undefined
      );
    } finally {
      setIsUploading(false);
    }
  };

  const handleSearch = async () => {
    if (!searchQuery.trim()) {
      loadLibrary();
      return;
    }

    setIsLoading(true);
    setError(null);
    try {
      const results = await searchLibrary(searchQuery);
      setPapers(results);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Search failed');
    } finally {
      setIsLoading(false);
    }
  };

  const handleToggleSelection = (paperId: number) => {
    const newSelection = new Set(selectedPapers);
    if (newSelection.has(paperId)) {
      newSelection.delete(paperId);
    } else {
      newSelection.add(paperId);
    }
    setSelectedPapers(newSelection);
  };

  const handleOpenSynthesis = () => {
    const paperIds = Array.from(selectedPapers);
    if (paperIds.length < 2) {
      return;
    }

    // Check if all selected papers have full PDFs
    const selectedPaperObjects = papers.filter(
      p => p.id !== undefined && paperIds.includes(p.id)
    );
    const metadataOnlyPapers = selectedPaperObjects.filter(p => !hasFullPDF(p));

    if (metadataOnlyPapers.length > 0) {
      const titles = metadataOnlyPapers
        .map(p => p.title)
        .slice(0, 3)
        .join(', ');
      const moreText =
        metadataOnlyPapers.length > 3
          ? ` and ${metadataOnlyPapers.length - 3} more`
          : '';
      showError(
        'Cannot Synthesize Metadata-Only Papers',
        `The following papers are metadata-only (no PDF): ${titles}${moreText}. ` +
          'Please upload PDFs for these papers or only select papers with full PDFs. ' +
          'Papers with full PDFs are marked with "📄 Full PDF" badge.'
      );
      return;
    }

    AppEvents.dispatchOpenSynthesisWorkbench(paperIds);
  };

  const handleSelectAll = () => {
    if (selectedPapers.size === papers.length) {
      // Deselect all
      setSelectedPapers(new Set());
    } else {
      // Select all
      setSelectedPapers(
        new Set(papers.filter(p => p.id !== undefined).map(p => p.id!))
      );
    }
  };

  const handleDelete = async () => {
    if (selectedPapers.size === 0) {
      return;
    }

    const paperIds = Array.from(selectedPapers);

    try {
      const result = await deletePapers(paperIds);
      showSuccess(
        'Papers Deleted',
        `Successfully deleted ${result.deleted_count} paper(s)`
      );

      // Refresh library to remove deleted papers
      await loadLibrary();
      // Clear selections
      setSelectedPapers(new Set());
    } catch (err) {
      showError(
        'Delete Failed',
        err instanceof Error ? err.message : 'Unknown error occurred',
        err instanceof Error ? err : undefined
      );
    }
  };

  if (selectedPaper) {
    return (
      <DetailView
        paper={selectedPaper}
        onClose={() => setSelectedPaper(null)}
      />
    );
  }

  return (
    <div className="jp-WWCExtension-library">
      <div style={{ marginBottom: '0' }}>
        <SearchBar
          query={searchQuery}
          onQueryChange={setSearchQuery}
          onSearch={handleSearch}
          isLoading={isLoading}
          placeholder="Search your library..."
          additionalInputs={
            <select
              onChange={async e => {
                const format = e.target.value as 'json' | 'csv' | 'bibtex' | '';
                if (format) {
                  try {
                    await exportLibrary(format);
                    showSuccess(
                      'Export Complete',
                      `Library exported as ${format.toUpperCase()}`
                    );
                  } catch (err) {
                    showError(
                      'Export Failed',
                      err instanceof Error ? err.message : 'Unknown error'
                    );
                  }
                  e.target.value = ''; // Reset
                }
              }}
              className="jp-WWCExtension-select"
            >
              <option value="">Export...</option>
              <option value="json">Export as JSON</option>
              <option value="csv">Export as CSV</option>
              <option value="bibtex">Export as BibTeX</option>
            </select>
          }
        />
      </div>

      {/* Upload PDF and Synthesize buttons - same line */}
      <div
        style={{
          display: 'flex',
          gap: '10px',
          alignItems: 'center',
          marginBottom: '10px',
          marginLeft: '8px'
        }}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept=".pdf,application/pdf"
          onChange={handleFileSelect}
          className="jp-WWCExtension-file-input"
          id="pdf-upload-input"
          style={{ display: 'none' }}
        />
        <label
          htmlFor="pdf-upload-input"
          className="jp-WWCExtension-button jp-WWCExtension-synthesis-button"
          style={{ cursor: 'pointer' }}
        >
          {isUploading ? 'Uploading...' : 'Upload PDF'}
        </label>
        {(() => {
          // Get all selected papers
          const selectedPaperObjects = papers.filter(
            p => p.id !== undefined && selectedPapers.has(p.id)
          );
          // Count selected papers with full PDFs
          const selectedWithPDFs = selectedPaperObjects.filter(p =>
            hasFullPDF(p)
          );
          // Check if any metadata-only papers are selected
          const selectedMetadataOnly = selectedPaperObjects.filter(
            p => !hasFullPDF(p)
          );

          // Show button only if: 2+ full-PDF papers selected AND no metadata-only papers selected
          return selectedWithPDFs.length >= 2 &&
            selectedMetadataOnly.length === 0 ? (
            <button
              onClick={handleOpenSynthesis}
              className="jp-WWCExtension-button jp-WWCExtension-synthesis-button"
            >
              Synthesize {selectedWithPDFs.length} Studies
            </button>
          ) : null;
        })()}
      </div>

      <ErrorDisplay error={error} />

      {/* Select All and Delete buttons - on their own line */}
      {papers.length > 0 && (
        <div
          style={{
            display: 'flex',
            gap: '10px',
            alignItems: 'center',
            marginBottom: '16px',
            marginLeft: '8px'
          }}
        >
          <button onClick={handleSelectAll} className="jp-WWCExtension-button">
            {selectedPapers.size === papers.length
              ? 'Deselect All'
              : 'Select All'}
          </button>
          {selectedPapers.size > 0 && (
            <button
              onClick={handleDelete}
              className="jp-WWCExtension-button jp-mod-warn"
            >
              Delete {selectedPapers.size} from Library
            </button>
          )}
        </div>
      )}

      {isLoading && <LoadingState />}

      <div className="jp-WWCExtension-papers">
        {papers.length === 0 && !isLoading && (
          <div className="jp-WWCExtension-empty">
            No papers found. Use the Discovery tab to search and import papers,
            or upload a PDF above.
          </div>
        )}
        {papers.map(paper => (
          <PaperCard
            key={getPaperKey(paper)}
            paper={paper}
            onViewDetails={() => setSelectedPaper(paper)}
            selected={paper.id !== undefined && selectedPapers.has(paper.id)}
            onToggleSelection={
              paper.id !== undefined
                ? () => handleToggleSelection(paper.id!)
                : undefined
            }
          />
        ))}
      </div>
    </div>
  );
};
