import { useRef, useEffect, useState } from 'react';
import { PreviewMode, TilesetSettings } from '../lib/imageProcessor';

type Tab = 'original' | 'tile' | 'repeat';

interface Props {
  sourceFile: File | null;
  resultCanvas: HTMLCanvasElement | null;
  settings: TilesetSettings;
  isProcessing: boolean;
  processingStep: string;
}

export default function PreviewPanel({
  sourceFile,
  resultCanvas,
  settings,
  isProcessing,
  processingStep,
}: Props) {
  const [tab, setTab] = useState<Tab>('original');
  const [sourceUrl, setSourceUrl] = useState<string | null>(null);
  const [resultUrl, setResultUrl] = useState<string | null>(null);
  const repeatRef = useRef<HTMLDivElement>(null);

  // Generate object URL for source image
  useEffect(() => {
    if (!sourceFile) { setSourceUrl(null); return; }
    const url = URL.createObjectURL(sourceFile);
    setSourceUrl(url);
    return () => URL.revokeObjectURL(url);
  }, [sourceFile]);

  // Generate data URL for result canvas
  useEffect(() => {
    if (!resultCanvas) { setResultUrl(null); return; }
    setResultUrl(resultCanvas.toDataURL('image/png'));
    // Switch to tile tab automatically when result arrives
    setTab('tile');
  }, [resultCanvas]);

  // Update repeated preview background
  useEffect(() => {
    if (!repeatRef.current || !resultUrl) return;
    const gridCount = previewModeToGrid(settings.previewMode);
    const tileSize = Math.floor(400 / gridCount);
    repeatRef.current.style.backgroundImage = `url(${resultUrl})`;
    repeatRef.current.style.backgroundSize = `${tileSize}px ${tileSize}px`;
    repeatRef.current.style.backgroundRepeat = 'repeat';
    repeatRef.current.style.width = `${tileSize * gridCount}px`;
    repeatRef.current.style.height = `${tileSize * gridCount}px`;
  }, [resultUrl, settings.previewMode]);

  const hasResult = !!resultCanvas;
  const hasSource = !!sourceFile;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Tab bar */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 10 }}>
        <div className="preview-tabs">
          <button
            id="preview-tab-original"
            className={`preview-tab ${tab === 'original' ? 'active' : ''}`}
            onClick={() => setTab('original')}
          >
            Original
          </button>
          <button
            id="preview-tab-tile"
            className={`preview-tab ${tab === 'tile' ? 'active' : ''}`}
            onClick={() => setTab('tile')}
            disabled={!hasResult}
          >
            Tileable
          </button>
          <button
            id="preview-tab-repeat"
            className={`preview-tab ${tab === 'repeat' ? 'active' : ''}`}
            onClick={() => setTab('repeat')}
            disabled={!hasResult}
          >
            Repeated
          </button>
        </div>

        {hasResult && (
          <div className="preview-stats">
            <span className="preview-stat">
              <strong>{settings.outputWidth}</strong>×<strong>{settings.outputHeight}</strong> px
            </span>
            <span className="preview-stat">WebP <strong>{settings.webpQuality}%</strong></span>
          </div>
        )}
      </div>

      {/* Content */}
      {tab === 'original' && (
        <div className="preview-canvas-wrap fade-in" style={{ position: 'relative' }}>
          {hasSource ? (
            <img src={sourceUrl!} alt="Original uploaded image" />
          ) : (
            <EmptyState label="Upload an image to preview it here" />
          )}
        </div>
      )}

      {tab === 'tile' && (
        <div className="preview-canvas-wrap fade-in" style={{ position: 'relative' }}>
          {isProcessing && (
            <div className="spinner-overlay">
              <div className="spinner" />
              <span className="spinner-text">{processingStep}</span>
            </div>
          )}
          {hasResult ? (
            <img src={resultUrl!} alt="Generated tileable texture" />
          ) : (
            <EmptyState label={hasSource ? 'Press Generate to process' : 'Upload an image first'} />
          )}
        </div>
      )}

      {tab === 'repeat' && (
        <div className="fade-in" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          {hasResult ? (
            <div style={{ position: 'relative' }}>
              <div
                className="preview-repeat-wrap"
                ref={repeatRef}
                aria-label="Repeated texture preview"
              />
              <div style={{
                position: 'absolute',
                bottom: 8,
                right: 8,
                background: 'rgba(0,0,0,0.6)',
                borderRadius: 4,
                padding: '2px 8px',
                fontSize: '0.7rem',
                color: 'var(--text-secondary)',
                backdropFilter: 'blur(4px)',
              }}>
                {previewModeLabel(settings.previewMode)} repeat
              </div>
            </div>
          ) : (
            <div className="preview-canvas-wrap" style={{ width: '100%' }}>
              <EmptyState label={hasSource ? 'Press Generate to preview tiling' : 'Upload an image first'} />
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function EmptyState({ label }: { label: string }) {
  return (
    <div className="preview-empty">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <rect x="3" y="3" width="18" height="18" rx="2" />
        <circle cx="8.5" cy="8.5" r="1.5" />
        <polyline points="21 15 16 10 5 21" />
      </svg>
      <p className="preview-empty-text">{label}</p>
    </div>
  );
}

function previewModeToGrid(mode: PreviewMode): number {
  switch (mode) {
    case 'single':   return 1;
    case 'repeat-2': return 2;
    case 'repeat-3': return 3;
    case 'repeat-4': return 4;
  }
}

function previewModeLabel(mode: PreviewMode): string {
  switch (mode) {
    case 'single':   return '1×1';
    case 'repeat-2': return '2×2';
    case 'repeat-3': return '3×3';
    case 'repeat-4': return '4×4';
  }
}
