import React, { useEffect, useState } from 'react';

interface ReorderPanelProps {
  pageCount: number;
  thumbnails: string[] | null;
  isBusy: boolean;
  hasPdf: boolean;
  rotations: Record<number, number>;
  onRotate: (pageIndex: number) => void;
  onExportReordered: (order: number[]) => void;
  reorderDownloadUrl: string | null;
  reorderFilename: string | null;
}

const ReorderPanel: React.FC<ReorderPanelProps> = ({
  pageCount,
  thumbnails,
  isBusy,
  hasPdf,
  rotations,
  onRotate,
  onExportReordered,
  reorderDownloadUrl,
  reorderFilename,
}) => {
  const [order, setOrder] = useState<number[]>([]);
  const [draggingIndex, setDraggingIndex] = useState<number | null>(null);
  const [dropIndex, setDropIndex] = useState<number | null>(null); // slot 0..order.length

  useEffect(() => {
    if (pageCount > 0) {
      setOrder(Array.from({ length: pageCount }, (_, i) => i));
    } else {
      setOrder([]);
      setDraggingIndex(null);
      setDropIndex(null);
    }
  }, [pageCount]);

  const handleDragStart = (index: number) => (e: React.DragEvent) => {
    setDraggingIndex(index);
    setDropIndex(index); // initial assumption: before itself
    e.dataTransfer.effectAllowed = 'move';
    // Firefox needs some data
    e.dataTransfer.setData('text/plain', String(index));
  };

  const handleDragEnd = () => {
    setDraggingIndex(null);
    setDropIndex(null);
  };

  const handleCardDragOver = (cardIndex: number) => (e: React.DragEvent) => {
    if (draggingIndex == null) return;
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';

    const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();
    const x = e.clientX - rect.left;

    // left half => slot BEFORE this card
    // right half => slot AFTER this card
    const slot = x < rect.width / 2 ? cardIndex : cardIndex + 1;
    setDropIndex(slot);
  };

  const handleEndSlotDragOver = (e: React.DragEvent) => {
    if (draggingIndex == null) return;
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    setDropIndex(order.length); // slot at the very end
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    if (draggingIndex == null || dropIndex == null) return;

    setOrder((prev) => {
      const updated = [...prev];
      const [moved] = updated.splice(draggingIndex, 1);

      const adjustedSlot = dropIndex > draggingIndex ? dropIndex - 1 : dropIndex;
      updated.splice(adjustedSlot, 0, moved);
      return updated;
    });

    setDraggingIndex(null);
    setDropIndex(null);
  };

  const handleDelete = (visualIndex: number) => () => {
    setOrder((prev) => prev.filter((_, idx) => idx !== visualIndex));
    setDraggingIndex(null);
    setDropIndex(null);
  };

  const handleRotateClick = (pageIndex: number) => () => {
    onRotate(pageIndex);
  };

  const handleExport = () => {
    if (!hasPdf || order.length === 0) return;
    onExportReordered(order);
  };

  if (!hasPdf) {
    return (
      <div className="card">
        <h2>Reorder pages</h2>
        <p>Load a PDF first to reorder, delete, or rotate its pages.</p>
      </div>
    );
  }

  const showLeftLine = (cardIndex: number) =>
    dropIndex !== null && dropIndex === cardIndex && draggingIndex !== null;

  const showRightLine = (cardIndex: number) =>
    dropIndex !== null && dropIndex === cardIndex + 1 && draggingIndex !== null;

  const showEndLine = () =>
    dropIndex !== null && dropIndex === order.length && draggingIndex !== null;

  return (
    <div className="card">
      <h2>Reorder / delete / rotate</h2>
      <p>
        Drag pages to reorder them. A vertical blue line shows where the page
        will be inserted. Use rotate and delete controls below each thumbnail.
      </p>

      <div
        style={{
          display: 'flex',
          flexWrap: 'wrap',
          gap: '0.5rem',
          alignItems: 'flex-start',
          marginBottom: '0.75rem',
        }}
        onDrop={handleDrop}
      >
        {order.map((pageIndex, visualIndex) => {
          const thumb = thumbnails?.[pageIndex];
          const isDragging = visualIndex === draggingIndex;
          const rotation = rotations[pageIndex] ?? 0;

          return (
            <div
              key={`${pageIndex}-${visualIndex}`}
              draggable
              onDragStart={handleDragStart(visualIndex)}
              onDragEnd={handleDragEnd}
              onDragOver={handleCardDragOver(visualIndex)}
              style={{
                position: 'relative',
                width: '130px',
                padding: '0.4rem',
                borderRadius: '0.5rem',
                border: isDragging ? '2px solid #2563eb' : '1px solid #e5e7eb',
                background: isDragging ? '#dbeafe' : '#f9fafb',
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                gap: '0.25rem',
                cursor: 'grab',
              }}
            >
              {/* left drop indicator */}
              {showLeftLine(visualIndex) && (
                <div
                  style={{
                    position: 'absolute',
                    left: '-4px',
                    top: '4px',
                    bottom: '4px',
                    width: '3px',
                    borderRadius: '999px',
                    background: '#2563eb',
                  }}
                />
              )}

              {/* right drop indicator */}
              {showRightLine(visualIndex) && (
                <div
                  style={{
                    position: 'absolute',
                    right: '-4px',
                    top: '4px',
                    bottom: '4px',
                    width: '3px',
                    borderRadius: '999px',
                    background: '#2563eb',
                  }}
                />
              )}

              {thumb ? (
                <img
                  src={thumb}
                  alt={`Page ${pageIndex + 1}`}
                  style={{
                    maxHeight: '90px',
                    width: 'auto',
                    borderRadius: '0.25rem',
                    border: '1px solid #e5e7eb',
                    background: 'white',
                  }}
                />
              ) : (
                <div
                  style={{
                    width: '60px',
                    height: '80px',
                    borderRadius: '0.25rem',
                    border: '1px dashed #d1d5db',
                    background: '#f3f4f6',
                  }}
                />
              )}
              <span style={{ fontSize: '0.8rem' }}>Page {pageIndex + 1}</span>
              <span style={{ fontSize: '0.7rem', color: '#6b7280' }}>
                Pos {visualIndex + 1} · Rot {rotation}°
              </span>

              <div
                style={{
                  display: 'flex',
                  gap: '0.25rem',
                  marginTop: '0.25rem',
                }}
              >
                <button
                  type="button"
                  onClick={handleRotateClick(pageIndex)}
                  style={{
                    border: 'none',
                    borderRadius: '999px',
                    padding: '0.15rem 0.4rem',
                    fontSize: '0.75rem',
                    background: '#e5e7eb',
                    cursor: 'pointer',
                  }}
                >
                  ↻ 90°
                </button>
                <button
                  type="button"
                  onClick={handleDelete(visualIndex)}
                  style={{
                    border: 'none',
                    borderRadius: '999px',
                    padding: '0.15rem 0.4rem',
                    fontSize: '0.75rem',
                    background: '#fecaca',
                    color: '#b91c1c',
                    cursor: 'pointer',
                  }}
                  title="Remove this page from the exported PDF"
                >
                  ✕
                </button>
              </div>
            </div>
          );
        })}

        {/* invisible end slot to allow dropping after the last card */}
        <div
          onDragOver={handleEndSlotDragOver}
          onDrop={handleDrop}
          style={{
            width: '20px',
            height: '120px',
            position: 'relative',
            alignSelf: 'stretch',
          }}
        >
          {showEndLine() && (
            <div
              style={{
                position: 'absolute',
                left: '8px',
                top: '4px',
                bottom: '4px',
                width: '3px',
                borderRadius: '999px',
                background: '#2563eb',
              }}
            />
          )}
        </div>
      </div>

      <div className="button-row">
        <button
          className="primary"
          disabled={!hasPdf || isBusy || order.length === 0}
          onClick={handleExport}
        >
          {isBusy ? 'Exporting…' : 'Export reordered PDF'}
        </button>
      </div>

      {reorderDownloadUrl && reorderFilename && (
        <div style={{ marginTop: '0.5rem', fontSize: '0.9rem' }}>
          <strong>Reordered result:</strong>{' '}
          <a
            href={reorderDownloadUrl}
            download={reorderFilename}
            className="download-link"
          >
            Download {reorderFilename}
          </a>
        </div>
      )}
    </div>
  );
};

export default ReorderPanel;
