<script lang="ts">
  import type { GradioClient, FluxGenerationParams, FluxGenerationResult } from '$lib/types';
  
  interface Props {
    client: GradioClient | null;
    onImageGenerated?: ((result: FluxGenerationResult, imageBlob: Blob) => void) | null;
  }
  
  let { client = null, onImageGenerated = null }: Props = $props();
  
  let params: FluxGenerationParams = $state({
    prompt: "",
    seed: 0,
    randomizeSeed: true,
    width: 1024,
    height: 1024,
    steps: 4
  });
  
  let isGenerating = $state(false);
  let result: FluxGenerationResult | null = $state(null);
  let error: string | null = $state(null);
  
  async function handleSubmit(e: Event) {
    e.preventDefault();
    if (!client || !params.prompt.trim()) return;
    
    isGenerating = true;
    error = null;
    
    try {
      const output = await client.predict("/infer", [
        params.prompt,
        params.seed,
        params.randomizeSeed,
        params.width,
        params.height,
        params.steps
      ]);
      
      const [image, usedSeed] = output.data;
      let url: string | undefined;
      
      if (typeof image === "string") url = image;
      else if (image && image.url) url = image.url;
      else if (image && image.path) url = image.path;
      
      if (url) {
        result = {
          imageUrl: url,
          seed: usedSeed,
          prompt: params.prompt
        };
        
        // Fetch image as blob for captioning
        if (onImageGenerated) {
          try {
            const response = await fetch(url);
            const blob = await response.blob();
            onImageGenerated(result, blob);
          } catch (err) {
            console.warn("Could not fetch generated image for captioning:", err);
          }
        }
      } else {
        error = "Unexpected image format returned from API";
      }
    } catch (err) {
      console.error(err);
      error = `Generation failed: ${err}`;
    } finally {
      isGenerating = false;
    }
  }
</script>

<form class="generator-form" onsubmit={handleSubmit}>
  <h3>Generate Image with FLUX-1 Schnell</h3>
  
  <label for="prompt">Prompt</label>
  <input 
    type="text" 
    id="prompt" 
    bind:value={params.prompt}
    placeholder="Enter your prompt" 
    required 
    disabled={isGenerating}
  />
  
  <label for="seed">Seed</label>
  <input 
    type="number" 
    id="seed" 
    bind:value={params.seed}
    min="0" 
    max="2147483647"
    disabled={isGenerating}
  />
  
  <label>
    <input 
      type="checkbox" 
      bind:checked={params.randomizeSeed}
      disabled={isGenerating}
    /> 
    Randomize seed
  </label>
  
  <div class="input-row">
    <div class="input-group">
      <label for="width">Width</label>
      <input 
        type="number" 
        id="width" 
        bind:value={params.width}
        min="256" 
        max="2048" 
        step="32"
        disabled={isGenerating}
      />
    </div>
    <div class="input-group">
      <label for="height">Height</label>
      <input 
        type="number" 
        id="height" 
        bind:value={params.height}
        min="256" 
        max="2048" 
        step="32"
        disabled={isGenerating}
      />
    </div>
  </div>
  
  <label for="steps">Number of inference steps</label>
  <input 
    type="number" 
    id="steps" 
    bind:value={params.steps}
    min="1" 
    max="50"
    disabled={isGenerating}
  />
  
  <button 
    type="submit" 
    class="generate-button"
    disabled={isGenerating || !client}
  >
    {isGenerating ? 'Generating…' : 'Generate Image'}
  </button>
</form>

{#if error}
  <div class="error-message">{error}</div>
{/if}

{#if isGenerating}
  <div class="status-message">Generating image…</div>
{/if}

{#if result}
  <div class="result">
    <img src={result.imageUrl} alt="Generated" />
    <p><strong>Seed</strong>: {result.seed}</p>
    <p><strong>Prompt</strong>: {result.prompt}</p>
  </div>
{/if}

<style>
  .generator-form {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid #eee;
  }
  
  h3 {
    margin-top: 0;
    margin-bottom: 1.5rem;
  }
  
  label {
    font-weight: 600;
    margin-bottom: 0.25rem;
    display: block;
  }
  
  input[type="text"], 
  input[type="number"] {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    margin-bottom: 1rem;
  }
  
  input[type="checkbox"] {
    margin-right: 0.5rem;
  }
  
  .input-row {
    display: flex;
    gap: 1rem;
  }
  
  .input-group {
    flex: 1;
  }
  
  .generate-button {
    background: #007bff;
    color: #fff;
    border: none;
    padding: 0.6rem 1.4rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.2s;
  }
  
  .generate-button:hover:not(:disabled) {
    background: #0056b3;
  }
  
  .generate-button:disabled {
    background: #9ac7ff;
    cursor: not-allowed;
  }
  
  .result {
    margin-top: 1rem;
  }
  
  .result img {
    max-width: 100%;
    border-radius: 8px;
    margin-bottom: 1rem;
  }
  
  .error-message {
    color: #dc3545;
    margin-top: 1rem;
    padding: 0.5rem;
    background: #f8d7da;
    border-radius: 4px;
  }
  
  .status-message {
    color: #0c5460;
    margin-top: 1rem;
    padding: 0.5rem;
    background: #d1ecf1;
    border-radius: 4px;
  }
</style>