import { useState, useCallback, useRef } from 'react';
import UploadPanel from './components/UploadPanel';
import SettingsPanel from './components/SettingsPanel';
import PreviewPanel from './components/PreviewPanel';
import ErrorBanner, { Banner } from './components/ErrorBanner';
import {
  defaultSettings,
  TilesetSettings,
  generateTileableTexture,
  exportAsWebP,
} from './lib/imageProcessor';

let bannerCounter = 0;

export default function App() {
  const [sourceFile, setSourceFile] = useState<File | null>(null);
  const [settings, setSettings] = useState<TilesetSettings>(defaultSettings);
  const [resultCanvas, setResultCanvas] = useState<HTMLCanvasElement | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [processingStep, setProcessingStep] = useState('');
  const [banners, setBanners] = useState<Banner[]>([]);
  const processingRef = useRef(false);

  const addBanner = (type: Banner['type'], message: string) => {
    const id = String(++bannerCounter);
    setBanners((prev) => [...prev, { id, type, message }]);
  };

  const dismissBanner = (id: string) =>
    setBanners((prev) => prev.filter((b) => b.id !== id));

  const handleFileSelect = useCallback((file: File) => {
    setSourceFile(file);
    setResultCanvas(null); // Clear old result when new image loaded
  }, []);

  const handleGenerate = async () => {
    if (!sourceFile || processingRef.current) return;
    processingRef.current = true;
    setIsProcessing(true);
    setResultCanvas(null);

    try {
      const canvas = await generateTileableTexture(
        sourceFile,
        settings,
        (step) => setProcessingStep(step),
      );
      setResultCanvas(canvas);
    } catch (err) {
      const msg = err instanceof Error ? err.message : 'An unknown error occurred.';
      addBanner('error', `Processing failed: ${msg}`);
    } finally {
      setIsProcessing(false);
      processingRef.current = false;
      setProcessingStep('');
    }
  };

  const handleExport = async () => {
    if (!resultCanvas) return;
    try {
      await exportAsWebP(
        resultCanvas,
        settings.webpQuality,
        settings.outputWidth,
        settings.outputHeight,
      );
    } catch (err) {
      addBanner('error', 'Export failed. Your browser may not support WebP export.');
    }
  };

  return (
    <div className="app">
      {/* Header */}
      <header className="app-header">
        <div className="app-header-logo">
          <svg width="28" height="28" viewBox="0 0 28 28" fill="none">
            <rect width="28" height="28" rx="7" fill="url(#grad)" />
            <rect x="2" y="2" width="11" height="11" rx="2" fill="rgba(255,255,255,0.85)" />
            <rect x="15" y="2" width="11" height="11" rx="2" fill="rgba(255,255,255,0.45)" />
            <rect x="2" y="15" width="11" height="11" rx="2" fill="rgba(255,255,255,0.45)" />
            <rect x="15" y="15" width="11" height="11" rx="2" fill="rgba(255,255,255,0.85)" />
            <defs>
              <linearGradient id="grad" x1="0" y1="0" x2="28" y2="28">
                <stop stopColor="#3b82f6" />
                <stop offset="1" stopColor="#8b5cf6" />
              </linearGradient>
            </defs>
          </svg>
          <div>
            <h1>Tileset Generator</h1>
            <div className="app-header-subtitle">Upload image → Generate tileable WebP texture</div>
          </div>
        </div>
        <div className="app-badge">V1 · Client-Side</div>
      </header>

      {/* Body */}
      <div className="app-body">
        {/* Sidebar */}
        <aside className="sidebar">
          {banners.length > 0 && (
            <ErrorBanner banners={banners} onDismiss={dismissBanner} />
          )}

          <UploadPanel
            onFileSelect={handleFileSelect}
            onError={(msg) => addBanner('error', msg)}
            onWarning={(msg) => addBanner('warning', msg)}
            currentFile={sourceFile}
          />

          <SettingsPanel
            settings={settings}
            onChange={setSettings}
            onGenerate={handleGenerate}
            onExport={handleExport}
            canGenerate={!!sourceFile}
            canExport={!!resultCanvas && !isProcessing}
            isProcessing={isProcessing}
          />
        </aside>

        {/* Preview */}
        <main className="preview-area">
          <PreviewPanel
            sourceFile={sourceFile}
            resultCanvas={resultCanvas}
            settings={settings}
            isProcessing={isProcessing}
            processingStep={processingStep}
          />
        </main>
      </div>
    </div>
  );
}
