import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { resolveDocumentAssetUrl } from '../asset_manager';
import { getTagColorStyle } from '../utils/colors';
import { DownloadIcon, FolderIcon } from '../ui/icons';

const FilterBar = ({
  query,
  onQueryChange,
  tags,
  activeTagIds,
  onToggleTag,
  onClear,
  hasFilters,
}) => (
  <div className="filter-bar">
    <input
      type="search"
      placeholder="Search documents"
      value={query}
      onChange={(event) => onQueryChange(event.target.value)}
    />
    <div className="tag-filters">
      {tags.length ? (
        tags.map((tag) => {
          const isActive = activeTagIds.includes(tag.id);
          const style = getTagColorStyle(tag.color);
          const buttonStyle = style
            ? {
                ...style,
                opacity: isActive ? 1 : 0.95,
                boxShadow: isActive ? '0 0 0 1px var(--shadow-soft)' : undefined,
              }
            : undefined;
          return (
            <button
              key={tag.id}
              type="button"
              className={`tag-filter${isActive ? ' active' : ''}`}
              onClick={() => onToggleTag(tag.id)}
              style={buttonStyle}
            >
              {tag.label}
            </button>
          );
        })
      ) : (
        <span className="meta">No tags yet</span>
      )}
    </div>
    <div className="filter-actions">
      {hasFilters && (
        <button type="button" className="secondary" onClick={onClear}>
          Clear
        </button>
      )}
    </div>
  </div>
);

const DocumentThumbnailImage = ({ document, ensureAssetUrl, getDocumentAsset, alt }) => {
  const url = useMemo(
    () =>
      resolveDocumentAssetUrl(document, 'thumbnail', {
        ensureAssetUrl,
        getAsset: getDocumentAsset,
      }),
    [document, ensureAssetUrl, getDocumentAsset],
  );

  if (url) {
    return (
      <img
        src={url}
        alt={alt || ''}
        className="document-thumbnail"
      />
    );
  }

  return <div className="thumb-placeholder">DOC</div>;
};

const DocumentsTable = ({
  currentFolderName,
  breadcrumbs,
  onRefresh,
  onShowSkeuoWorkspace = () => {},
  onRequestCreateFolder,
  creatingFolder = false,
  subfolders,
  documents,
  searchResults,
  isFilterActive,
  onFolderSelect,
  onFolderDrop,
  onFolderDragOver,
  onFolderDragLeave,
  onFolderDragStart,
  onFolderDragEnd,
  draggedFolderId,
  onFolderDelete,
  onDocumentRowClick,
  onDocumentOpen,
  selectedDocumentIds,
  focusedDocumentId,
  focusedRowKey,
  draggingDocumentIds = [],
  onDocumentDragStart,
  onDocumentDragEnd,
  onDocumentDelete,
  filterBar,
  tagLookupById,
  onDocumentListFocus,
  onDocumentListKeyDown,
  onFocusedRowChange,
  ensureAssetUrl = null,
  getDocumentAsset = () => null,
  getDownloadHref,
}) => {
  const showingSearchResults = searchResults !== null;
  const rows = showingSearchResults ? searchResults : documents;

  const selectedSet = useMemo(
    () => new Set(selectedDocumentIds),
    [selectedDocumentIds],
  );
  const draggingSet = useMemo(
    () => new Set(draggingDocumentIds || []),
    [draggingDocumentIds],
  );
  const scrollRef = useRef(null);
  const ensureFocusedRowVisible = useCallback(() => {
    if (!focusedRowKey) return;
    const container = scrollRef.current;
    if (!container) return;
    let selector = null;
    if (focusedRowKey.startsWith('document:')) {
      selector = `#document-row-${focusedRowKey.slice('document:'.length)}`;
    } else if (focusedRowKey.startsWith('folder:')) {
      selector = `#folder-row-${focusedRowKey.slice('folder:'.length)}`;
    }
    if (!selector) {
      return;
    }
    const row = container.querySelector(selector);
    if (!row || !container.contains(row)) {
      return;
    }

    const header = container.querySelector('thead');
    const headerHeight = header ? header.getBoundingClientRect().height : 0;
    const rowTop = row.offsetTop;
    const rowBottom = rowTop + row.offsetHeight;
    const visibleTop = container.scrollTop + headerHeight;
    const visibleBottom = container.scrollTop + container.clientHeight;

    if (rowTop < visibleTop) {
      container.scrollTop = Math.max(rowTop - headerHeight, 0);
      return;
    }

    if (rowBottom > visibleBottom) {
      const nextScrollTop = rowBottom - container.clientHeight;
      container.scrollTop = Math.max(nextScrollTop, 0);
    }
  }, [focusedRowKey]);

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

  const activeDescendantId = useMemo(() => {
    if (!focusedRowKey) return undefined;
    if (focusedRowKey.startsWith('document:')) {
      return `document-row-${focusedRowKey.slice('document:'.length)}`;
    }
    if (focusedRowKey.startsWith('folder:')) {
      return `folder-row-${focusedRowKey.slice('folder:'.length)}`;
    }
    return undefined;
  }, [focusedRowKey]);

  return (
    <section className="documents-panel column">
      <div className="column-header">
        <div className="column-header__titles">
          <nav className="breadcrumb" aria-label="Folder breadcrumbs">
            {breadcrumbs.map((crumb, index) => {
              const isLast = index === breadcrumbs.length - 1;
              return (
                <span key={crumb.id} className="breadcrumb-item">
                  {isLast ? (
                    <span className="breadcrumb-current">{crumb.name}</span>
                  ) : (
                    <a
                      href="#"
                      onClick={(event) => {
                        event.preventDefault();
                        onFolderSelect(crumb.id);
                      }}
                    >
                      {crumb.name}
                    </a>
                  )}
                  {!isLast && <span className="breadcrumb-separator">›</span>}
                </span>
              );
            })}
          </nav>
          {showingSearchResults && (
            <div className="column-subtitle">Search results</div>
          )}
        </div>
        <div className="header-actions">
          <button
            type="button"
            onClick={onRequestCreateFolder}
            disabled={creatingFolder}
          >
            {creatingFolder ? 'Creating…' : 'New folder'}
          </button>
          <button className="secondary" onClick={onRefresh}>
            Refresh
          </button>
          <button className="secondary" type="button" onClick={onShowSkeuoWorkspace}>
            Desk View
          </button>
        </div>
      </div>
      <div className="column-body">
        <div className="column-toolbar">{filterBar}</div>
        <div
          ref={scrollRef}
          className="documents-scroll"
          tabIndex={0}
          onFocus={(event) => {
            if (event.target === scrollRef.current) {
              onDocumentListFocus?.();
            }
          }}
          onKeyDown={(event) => {
            if (event.target !== scrollRef.current) {
              return;
            }
            if (onDocumentListKeyDown) {
              onDocumentListKeyDown(event);
            }
          }}
          aria-activedescendant={activeDescendantId}
        >
          {!showingSearchResults && !subfolders.length && rows.length === 0 ? (
            <div className="empty-state">
              Drop files anywhere or onto a folder to upload documents.
            </div>
          ) : (
            <table aria-multiselectable="true">
              <thead>
                <tr>
                  <th className="thumb-column">Preview</th>
                  <th>Name</th>
                  <th>Type</th>
                  <th>Updated</th>
                  <th className="actions-column">Actions</th>
                </tr>
              </thead>
              <tbody>
                {!showingSearchResults &&
                  subfolders.map((folder) => {
                    const canDragFolder = folder.id !== 'root';
                    const isDraggingFolder = draggedFolderId === folder.id;
                    return (
                      <tr
                        key={folder.id}
                        className={`folder${isDraggingFolder ? ' is-dragging' : ''}${
                          focusedRowKey === `folder:${folder.id}` ? ' focused' : ''
                        }`}
                        id={`folder-row-${folder.id}`}
                        onClick={() => {
                          onFolderSelect(folder.id);
                          if (scrollRef.current) {
                            scrollRef.current.focus({ preventScroll: true });
                          }
                          onFocusedRowChange?.(`folder:${folder.id}`);
                        }}
                        onDragOver={(event) => onFolderDragOver(event, folder.id)}
                        onDragLeave={onFolderDragLeave}
                        onDrop={(event) => onFolderDrop(event, folder.id)}
                        draggable={canDragFolder}
                        onDragStart={(event) => {
                          if (canDragFolder) {
                            onFolderDragStart(event, folder.id);
                          }
                        }}
                        onDragEnd={(event) => {
                          if (canDragFolder) {
                            onFolderDragEnd(event);
                          }
                        }}
                      >
                        <td className="thumb-cell">
                          <div className="thumb-placeholder icon">
                            <FolderIcon className="icon-inline" size={18} />
                          </div>
                        </td>
                        <td>{folder.name}</td>
                        <td>Folder</td>
                        <td>—</td>
                        <td className="actions">
                          <button
                            type="button"
                            className="icon-button danger"
                            onClick={(event) => {
                              event.stopPropagation();
                              onFolderDelete(folder.id);
                            }}
                          >
                            Delete
                          </button>
                        </td>
                      </tr>
                    );
                  })}
                {rows.map((doc) => {
                  const isSelected = selectedSet.has(doc.id);
                  const isDraggingDoc = draggingSet.has(doc.id);
                  const rowClasses = ['document'];
                  if (isSelected) rowClasses.push('selected');
                  if (isDraggingDoc) rowClasses.push('is-dragging');
                  const downloadHref = getDownloadHref?.(doc) || null;

                  return (
                    <tr
                      key={doc.id}
                      className={rowClasses.join(' ')}
                      id={`document-row-${doc.id}`}
                      onClick={(event) => onDocumentRowClick(doc.id, event)}
                      onDoubleClick={() => onDocumentOpen(doc.id)}
                      draggable
                      onDragStart={(event) => onDocumentDragStart(event, doc)}
                      onDragEnd={onDocumentDragEnd}
                    >
                      <td className="thumb-cell">
                        <DocumentThumbnailImage
                          document={doc}
                          ensureAssetUrl={ensureAssetUrl}
                          getDocumentAsset={getDocumentAsset}
                          alt={`Thumbnail for ${doc.title || doc.original_name}`}
                        />
                      </td>
                      <td>
                        <div className="doc-name">
                          <span className="doc-name__title">{doc.title || doc.original_name}</span>
                          {(doc.tags || []).length > 0 && (
                            <div className="doc-name__tags">
                              {(doc.tags || []).map((tag) => {
                                const colorSource = tag?.color || tagLookupById?.get(tag.id)?.color;
                                const style = getTagColorStyle(colorSource);
                                return (
                                  <span
                                    key={tag.id}
                                    className="badge tag-chip"
                                    style={style || undefined}
                                    title={tag.label}
                                  >
                                    {tag.label}
                                  </span>
                                );
                              })}
                            </div>
                          )}
                        </div>
                      </td>
                      <td>{doc.content_type || 'Document'}</td>
                      <td>
                        {doc.updated_at
                          ? new Date(doc.updated_at).toLocaleString()
                          : '—'}
                      </td>
                      <td className="actions">
                        <div className="action-buttons">
                          {downloadHref ? (
                            <a
                              className="button-link with-icon"
                              href={downloadHref}
                              target="_blank"
                              rel="noopener noreferrer"
                              onClick={(event) => event.stopPropagation()}
                              onAuxClick={(event) => event.stopPropagation()}
                              onContextMenu={(event) => event.stopPropagation()}
                            >
                              <DownloadIcon className="icon-inline" />
                              <span>Download</span>
                            </a>
                          ) : (
                            <span className="meta">No download</span>
                          )}
                          <button
                            type="button"
                            className="danger"
                            onClick={(event) => {
                              event.stopPropagation();
                              onDocumentDelete?.(doc.id);
                            }}
                          >
                            Delete
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>
        {rows.length === 0 && isFilterActive && (
          <div className="empty-state">No documents match the current filters.</div>
        )}
        {showingSearchResults && rows.length > 0 && (
          <div className="search-hint">
            Showing {rows.length} document{rows.length === 1 ? '' : 's'} in {currentFolderName} and subfolders.
          </div>
        )}
      </div>
    </section>
  );
};

export default DocumentsTable;
export { FilterBar, DocumentThumbnailImage };
