<script lang="ts">
  import { transformImage } from "./lib/api";
  import {
    generateClientPreview,
    estimateSize,
    formatFileSize,
    calculateSavings,
    debounce,
    type TransformOptions
  } from "./lib/preview";
  import { theme } from "./lib/theme";

  let file: File | null = null;
  let filePreviewUrl: string | null = null;
  let width: number | null = null;
  let height: number | null = null;
  let quality = 80;
  let format: "png" | "webp" | "jpeg" = "png";
  let fit: "inside" | "cover" = "inside";
  let position = "center";

  let processing = false;
  let error: string | null = null;
  
  // Preview state
  let previewUrl: string | null = null;
  let previewSize = 0;
  let originalSize = 0;
  let showPreview = false;

  // Generate preview with debounce
  const updatePreview = debounce(async () => {
    if (!file) {
      previewUrl = null;
      showPreview = false;
      return;
    }

    try {
      const options: TransformOptions = {
        width: width || undefined,
        height: height || undefined,
        quality,
        format,
        fit,
        position: fit === "cover" ? position : undefined
      };

      previewUrl = await generateClientPreview(file, options);
      previewSize = estimateSize(previewUrl);
      originalSize = file.size;
      showPreview = true;
    } catch (err) {
      console.error("Preview generation failed:", err);
    }
  }, 300);

  // Reactive preview updates
  $: if (file) {
    updatePreview();
  }
  $: if (width !== null || height !== null || quality || format || fit || position) {
    if (file) updatePreview();
  }

  async function onSubmit() {
    if (!file) {
      error = "Please select an image file";
      return;
    }
    error = null;
    processing = true;
    try {
      const blob = await transformImage(file, {
        width: width || undefined,
        height: height || undefined,
        quality,
        format,
        fit,
        position: fit === "cover" ? position : undefined
      });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `output.${format}`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (e) {
      error = "Processing failed";
      console.error(e);
    } finally {
      processing = false;
    }
  }

  function onFileChange(e: Event) {
    const target = e.target as HTMLInputElement;
    file = target.files?.[0] || null;
    if (file) {
      filePreviewUrl = URL.createObjectURL(file);
    } else {
      filePreviewUrl = null;
    }
  }

  function clearFile() {
    file = null;
    filePreviewUrl = null;
    previewUrl = null;
    showPreview = false;
    originalSize = 0;
    previewSize = 0;
  }

  const savings = showPreview ? calculateSavings(originalSize, previewSize) : null;
</script>

<div class="container">
  <!-- Header -->
  <header class="flex justify-between items-center" style="margin-bottom: var(--space-2xl);">
    <div>
      <h1 class="mb-0">PNGer</h1>
      <p class="text-sm mb-0">Modern PNG Editor & Resizer</p>
    </div>
    <button class="btn-outline" on:click={() => theme.toggle()}>
      {#if $theme === 'dark'}
        ☀️ Light
      {:else}
        🌙 Dark
      {/if}
    </button>
  </header>

  <div class="grid grid-cols-2 gap-lg">
    <!-- Left Column: Upload & Controls -->
    <div class="card fade-in">
      <h2>Upload & Transform</h2>

      <!-- File Upload -->
      <div style="margin-bottom: var(--space-xl);">
        <label style="display: block; margin-bottom: var(--space-sm); font-weight: 500;">
          Select Image
        </label>
        <input 
          type="file" 
          accept="image/*" 
          on:change={onFileChange}
          style="margin-bottom: var(--space-sm);"
        />
        {#if file}
          <div class="flex gap-sm items-center" style="margin-top: var(--space-sm);">
            <span class="text-sm">{file.name}</span>
            <span class="text-xs" style="color: var(--color-text-secondary);">
              ({formatFileSize(file.size)})
            </span>
            <button class="btn-secondary" style="padding: var(--space-xs) var(--space-sm); font-size: 0.875rem;" on:click={clearFile}>
              Clear
            </button>
          </div>
        {/if}
      </div>

      <!-- Dimensions -->
      <div style="margin-bottom: var(--space-lg);">
        <h3>Dimensions</h3>
        <div class="grid grid-cols-2 gap-md">
          <div>
            <label style="display: block; margin-bottom: var(--space-xs); font-size: 0.875rem;">
              Width (px)
            </label>
            <input type="number" bind:value={width} min="1" placeholder="Auto" />
          </div>
          <div>
            <label style="display: block; margin-bottom: var(--space-xs); font-size: 0.875rem;">
              Height (px)
            </label>
            <input type="number" bind:value={height} min="1" placeholder="Auto" />
          </div>
        </div>
      </div>

      <!-- Fit Mode -->
      <div style="margin-bottom: var(--space-lg);">
        <label style="display: block; margin-bottom: var(--space-sm); font-weight: 500;">
          Fit Mode
        </label>
        <select bind:value={fit}>
          <option value="inside">Resize only (no crop)</option>
          <option value="cover">Crop to fit box</option>
        </select>
      </div>

      <!-- Crop Position (if cover) -->
      {#if fit === "cover"}
        <div style="margin-bottom: var(--space-lg);" class="fade-in">
          <label style="display: block; margin-bottom: var(--space-sm); font-weight: 500;">
            Crop Position
          </label>
          <select bind:value={position}>
            <option value="center">Center</option>
            <option value="top">Top</option>
            <option value="bottom">Bottom</option>
            <option value="left">Left</option>
            <option value="right">Right</option>
            <option value="top-left">Top-left</option>
            <option value="top-right">Top-right</option>
            <option value="bottom-left">Bottom-left</option>
            <option value="bottom-right">Bottom-right</option>
          </select>
        </div>
      {/if}

      <!-- Quality -->
      <div style="margin-bottom: var(--space-lg);">
        <div class="flex justify-between" style="margin-bottom: var(--space-sm);">
          <label style="font-weight: 500;">Quality</label>
          <span style="color: var(--color-accent); font-weight: 600;">{quality}%</span>
        </div>
        <input type="range" min="10" max="100" bind:value={quality} />
      </div>

      <!-- Format -->
      <div style="margin-bottom: var(--space-xl);">
        <label style="display: block; margin-bottom: var(--space-sm); font-weight: 500;">
          Output Format
        </label>
        <select bind:value={format}>
          <option value="png">PNG</option>
          <option value="webp">WebP</option>
          <option value="jpeg">JPEG</option>
        </select>
      </div>

      <!-- Error Message -->
      {#if error}
        <p style="color: var(--color-error); padding: var(--space-md); background: var(--color-bg-tertiary); border-radius: var(--radius-md); margin-bottom: var(--space-lg);">
          {error}
        </p>
      {/if}

      <!-- Action Button -->
      <button 
        on:click|preventDefault={onSubmit} 
        disabled={processing || !file}
        style="width: 100%;"
      >
        {#if processing}
          <span class="spinner" style="width: 16px; height: 16px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%;"></span>
          Processing...
        {:else}
          ⬇️ Transform & Download
        {/if}
      </button>
    </div>

    <!-- Right Column: Preview -->
    <div class="card fade-in" style="display: flex; flex-direction: column;">
      <h2>Live Preview</h2>

      {#if !file}
        <div style="flex: 1; display: flex; align-items: center; justify-content: center; color: var(--color-text-secondary); text-align: center; padding: var(--space-2xl);">
          <div>
            <p style="font-size: 3rem; margin-bottom: var(--space-md)">🖼️</p>
            <p class="mb-0">Upload an image to see live preview</p>
          </div>
        </div>
      {:else if showPreview}
        <div style="flex: 1; display: flex; flex-direction: column; gap: var(--space-lg);">
          <!-- Image Comparison -->
          <div class="grid grid-cols-2 gap-md" style="flex: 1;">
            <!-- Original -->
            <div style="display: flex; flex-direction: column;">
              <h3 style="font-size: 1rem; margin-bottom: var(--space-sm);">Original</h3>
              <div style="flex: 1; border: 2px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--color-bg-tertiary);">
                <img 
                  src={filePreviewUrl} 
                  alt="Original" 
                  style="max-width: 100%; max-height: 300px; object-fit: contain;"
                />
              </div>
              <div style="margin-top: var(--space-sm); text-align: center;">
                <p class="text-sm mb-0">
                  {formatFileSize(originalSize)}
                </p>
              </div>
            </div>

            <!-- Preview -->
            <div style="display: flex; flex-direction: column;">
              <h3 style="font-size: 1rem; margin-bottom: var(--space-sm);">Preview</h3>
              <div style="flex: 1; border: 2px solid var(--color-accent); border-radius: var(--radius-md); overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--color-bg-tertiary);">
                <img 
                  src={previewUrl} 
                  alt="Preview" 
                  style="max-width: 100%; max-height: 300px; object-fit: contain;"
                />
              </div>
              <div style="margin-top: var(--space-sm); text-align: center;">
                <p class="text-sm mb-0">
                  {formatFileSize(previewSize)}
                </p>
              </div>
            </div>
          </div>

          <!-- Savings Info -->
          {#if savings}
            <div 
              class="fade-in" 
              style="
                padding: var(--space-lg); 
                background: {savings.isReduction ? 'var(--color-success)' : 'var(--color-warning)'}15; 
                border: 2px solid {savings.isReduction ? 'var(--color-success)' : 'var(--color-warning)'};
                border-radius: var(--radius-md);
                text-align: center;
              "
            >
              <p class="text-sm font-semibold mb-0" style="color: {savings.isReduction ? 'var(--color-success)' : 'var(--color-warning)'}; font-size: 1.125rem;">
                {savings.formatted}
              </p>
            </div>
          {/if}
        </div>
      {:else}
        <div style="flex: 1; display: flex; align-items: center; justify-content: center; color: var(--color-text-secondary);">
          <div class="spinner" style="width: 40px; height: 40px; border: 3px solid var(--color-border); border-top-color: var(--color-accent); border-radius: 50%;"></div>
        </div>
      {/if}
    </div>
  </div>
</div>