/**
 * Card view for displaying document summary, preview, and metadata.
 */
import { useState } from 'react';
import { Download, FileText, Trash2 } from 'lucide-react';

import type { DmsDocument } from '../types';
import { contentMarkdownUrl, downloadUrl, thumbnailUrl } from '../lib/api';

/**
 * Defines properties accepted by the document card component.
 */
interface DocumentCardProps {
  document: DmsDocument;
  isSelected: boolean;
  isChecked: boolean;
  isTrashView: boolean;
  onSelect: (document: DmsDocument) => void;
  onToggleChecked: (documentId: string, checked: boolean) => void;
  onTrashDocument: (documentId: string) => Promise<void>;
  onFilterPath: (path: string) => void;
  onFilterTag: (tag: string) => void;
}

/**
 * Defines visual processing status variants rendered in the card header indicator.
 */
type StatusTone = 'success' | 'progress' | 'failed';

/**
 * Resolves status tone and tooltip text from backend document status values.
 */
function statusPresentation(status: DmsDocument['status']): { tone: StatusTone; tooltip: string } {
  if (status === 'processed') {
    return { tone: 'success', tooltip: 'Processing status: success' };
  }
  if (status === 'queued') {
    return { tone: 'progress', tooltip: 'Processing status: in progress' };
  }
  if (status === 'error') {
    return { tone: 'failed', tooltip: 'Processing status: failed' };
  }
  if (status === 'unsupported') {
    return { tone: 'failed', tooltip: 'Processing status: failed (unsupported type)' };
  }
  return { tone: 'success', tooltip: 'Processing status: success (moved to trash)' };
}

/**
 * Limits logical-path length while preserving start and end context with middle ellipsis.
 */
function compactLogicalPath(path: string, maxChars = 180): string {
  const normalized = path.trim();
  if (!normalized) {
    return '';
  }
  if (normalized.length <= maxChars) {
    return normalized;
  }
  const keepChars = Math.max(12, maxChars - 3);
  const headChars = Math.ceil(keepChars * 0.6);
  const tailChars = keepChars - headChars;
  return `${normalized.slice(0, headChars)}...${normalized.slice(-tailChars)}`;
}

/**
 * Renders one document card with optional image preview and searchable metadata.
 */
export default function DocumentCard({
  document,
  isSelected,
  isChecked,
  isTrashView,
  onSelect,
  onToggleChecked,
  onTrashDocument,
  onFilterPath,
  onFilterTag,
}: DocumentCardProps): JSX.Element {
  const [isTrashing, setIsTrashing] = useState<boolean>(false);
  const createdDate = new Date(document.created_at).toLocaleString();
  const status = statusPresentation(document.status);
  const compactPath = compactLogicalPath(document.logical_path, 180);
  const trashDisabled = isTrashView || document.status === 'trashed' || isTrashing;
  const trashTitle = trashDisabled ? 'Already in trash' : 'Move to trash';

  return (
    <article
      className={`document-card ${isSelected ? 'selected' : ''}`}
      role="button"
      tabIndex={0}
      onClick={() => onSelect(document)}
      onKeyDown={(event) => {
        if (event.currentTarget !== event.target) {
          return;
        }
        if (event.key === 'Enter' || event.key === ' ') {
          event.preventDefault();
          onSelect(document);
        }
      }}
    >
      <header className="document-card-header">
        <div
          className={`card-status-indicator ${status.tone}`}
          title={status.tooltip}
          aria-label={status.tooltip}
        />
        <label className="card-checkbox card-checkbox-compact" onClick={(event) => event.stopPropagation()}>
          <input
            type="checkbox"
            checked={isChecked}
            onChange={(event) => onToggleChecked(document.id, event.target.checked)}
            onClick={(event) => event.stopPropagation()}
            aria-label={`Select ${document.original_filename}`}
            title="Select document"
          />
        </label>
      </header>
      <div className="document-preview">
        {document.preview_available ? (
          <img src={thumbnailUrl(document.id)} alt={document.original_filename} loading="lazy" />
        ) : (
          <div className="document-preview-fallback">{document.extension || 'file'}</div>
        )}
      </div>
      <div className="document-content document-card-body">
        <h3 title={`${document.logical_path}/${document.original_filename}`}>
          <span className="document-title-path">{compactPath}/</span>
          <span className="document-title-name">{document.original_filename}</span>
        </h3>
        <p className="document-date">{createdDate}</p>
      </div>
      <footer className="document-card-footer">
        <div className="card-footer-discovery">
          <button
            type="button"
            className="card-chip path-chip"
            onClick={(event) => {
              event.preventDefault();
              event.stopPropagation();
              onFilterPath(document.logical_path);
            }}
            title={`Filter by path: ${document.logical_path}`}
          >
            {document.logical_path}
          </button>
          <div className="card-chip-row">
            {document.tags.slice(0, 4).map((tag) => (
              <button
                key={`${document.id}-${tag}`}
                type="button"
                className="card-chip"
                onClick={(event) => {
                  event.preventDefault();
                  event.stopPropagation();
                  onFilterTag(tag);
                }}
                title={`Filter by tag: ${tag}`}
              >
                #{tag}
              </button>
            ))}
          </div>
        </div>
        <div className="card-action-row">
          <button
            type="button"
            className="card-icon-button"
            aria-label="Download original"
            title="Download original"
            onClick={(event) => {
              event.preventDefault();
              event.stopPropagation();
              window.open(downloadUrl(document.id), '_blank', 'noopener,noreferrer');
            }}
          >
            <Download aria-hidden="true" />
          </button>
          <button
            type="button"
            className="card-icon-button"
            aria-label="Export recognized text as markdown"
            title="Export recognized text as markdown"
            onClick={(event) => {
              event.preventDefault();
              event.stopPropagation();
              window.open(contentMarkdownUrl(document.id), '_blank', 'noopener,noreferrer');
            }}
          >
            <FileText aria-hidden="true" />
          </button>
          <button
            type="button"
            className="card-icon-button danger"
            aria-label={trashTitle}
            title={trashTitle}
            disabled={trashDisabled}
            onClick={async (event) => {
              event.preventDefault();
              event.stopPropagation();
              if (trashDisabled) {
                return;
              }
              setIsTrashing(true);
              try {
                await onTrashDocument(document.id);
              } catch {
              } finally {
                setIsTrashing(false);
              }
            }}
          >
            <Trash2 aria-hidden="true" />
          </button>
        </div>
      </footer>
    </article>
  );
}
