import React, { useMemo } from 'react';
import DesktopPreviewCard from './DesktopPreviewCard';
import { resolveCorrespondents } from '../documents/correspondents';
import { getTagColorStyle } from '../utils/colors';
import type { DocumentId } from '../types/identifiers';
import type { Document } from '../types/documents';
import { LayoutCard } from './LayoutSystem';

const preventAll = (event?: React.SyntheticEvent | Event | null) => {
  if (!event) return;
  if (typeof event.preventDefault === 'function') event.preventDefault();
  if (typeof event.stopPropagation === 'function') event.stopPropagation();
};

interface DesktopDocumentCardProps {
  doc: Document;
  style?: React.CSSProperties;
  shouldLoad?: boolean;
  matchesFilter?: boolean;
  selected?: boolean;
  docTagTokens?: string;
  ensureAssetUrl?: (...args: any[]) => Promise<unknown>;
  getDocumentAsset?: (...args: any[]) => unknown;
  handleNavigatorSnapshot?: (...args: any[]) => void;
  cardPointerHandlers?: React.HTMLAttributes<HTMLDivElement>;
  onDocumentActivate?: (id: string, event?: any) => void;
  onTagDragEnter?: (event: React.DragEvent<HTMLDivElement>, docId: DocumentId) => void;
  onTagDragOver?: (event: React.DragEvent<HTMLDivElement>, docId: DocumentId) => void;
  onTagDragLeave?: (event: React.DragEvent<HTMLDivElement>, docId: DocumentId) => void;
  onTagDrop?: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
  onDocTagDragStart?: (event: React.DragEvent<HTMLElement>, doc: Document, tag: any) => void;
  onDocTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
  layoutCard?: LayoutCard;
}

const DesktopDocumentCard: React.FC<DesktopDocumentCardProps> = ({
  doc,
  style,
  shouldLoad,
  matchesFilter,
  selected,
  docTagTokens,
  ensureAssetUrl,
  getDocumentAsset,
  handleNavigatorSnapshot,
  cardPointerHandlers,
  onDocumentActivate,
  onTagDragEnter,
  onTagDragOver,
  onTagDragLeave,
  onTagDrop,
  onDocTagDragStart,
  onDocTagDragEnd,
  layoutCard,
}) => {
  const correspondents = useMemo(() => resolveCorrespondents(doc), [doc]);
  const tags = Array.isArray(doc?.tags) ? doc.tags : [];

  const itemClasses = ['desk-item'];
  if (!matchesFilter) itemClasses.push('is-filtered-out');
  if (selected) itemClasses.push('is-selected');

  const ariaHidden = matchesFilter ? undefined : 'true';
  const dataTagIds = docTagTokens || undefined;

  return (
    <div
      key={doc.id}
      className={itemClasses.join(' ')}
      style={style}
      role="button"
      data-doc-id={doc.id}
      data-tag-ids={dataTagIds}
      aria-hidden={ariaHidden}
      ref={(node) => layoutCard?.setRef(node)}
      {...cardPointerHandlers}
      onDragEnter={(event) => {
        if (doc?.id == null) {
          return;
        }
        onTagDragEnter?.(event, doc.id);
      }}
      onDragOver={(event) => {
        if (doc?.id == null) {
          return;
        }
        onTagDragOver?.(event, doc.id);
      }}
      onDragLeave={(event) => {
        if (doc?.id == null) {
          return;
        }
        onTagDragLeave?.(event, doc.id);
      }}
      onDrop={(event) => {
        onTagDrop?.(event, doc);
      }}
      onKeyDown={(event) => {
        if (event.key === 'Enter' || event.key === ' ') {
          preventAll(event);
          onDocumentActivate?.(doc.id, event);
        }
      }}
    >
      <div className="desk-item__body">
        <DesktopPreviewCard
          doc={doc}
          title={doc.title}
          ensureAssetUrl={ensureAssetUrl}
          getDocumentAsset={getDocumentAsset}
          onNavigatorSnapshot={handleNavigatorSnapshot}
          shouldLoad={shouldLoad}
        />
        {correspondents.length > 0 && (
          <div className="desk-item__correspondents" aria-hidden="true">
            {correspondents.map((correspondent) => (
              <span
                key={correspondent.key}
                className="badge desk-correspondent-chip"
                title={correspondent.name}
              >
                <span className="desk-correspondent-chip__label">{correspondent.name}</span>
              </span>
            ))}
          </div>
        )}
        {tags.length > 0 && (
          <div className="desk-item__tags" aria-hidden="true">
            {tags.map((tag) => {
              const colorStyle = getTagColorStyle(tag.color);
              const tagClasses = ['badge', 'tag-chip', 'tag-chip--draggable'];
              return (
                <span
                  key={tag.id}
                  className={tagClasses.join(' ')}
                  style={colorStyle || undefined}
                  title={tag.label}
                  draggable
                  data-desk-tag-chip="true"
                  onDragStart={(event) => onDocTagDragStart?.(event, doc, tag)}
                  onDragEnd={(event) => onDocTagDragEnd?.(event)}
                >
                  <span className="tag-chip__label">{tag.label}</span>
                </span>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
};

export default React.memo(DesktopDocumentCard);
