<script lang="ts">
  import type { GradioClient, CaptionParams, CaptionResult, CaptionType, CaptionLength } from '$lib/types';
  
  interface Props {
    client: GradioClient | null;
    currentImage?: Blob | null;
  }
  
  let { client = null, currentImage = null }: Props = $props();
  
  let imageInput: HTMLInputElement;
  let uploadedImage: File | null = $state(null);
  let captionType: CaptionType = $state("Descriptive");
  let captionLength: CaptionLength = $state("long");
  let isGenerating = $state(false);
  let result: CaptionResult | null = $state(null);
  let error: string | null = $state(null);
  
  const captionTypes: CaptionType[] = [
    "Descriptive",
    "Descriptive (Informal)",
    "Training Prompt",
    "MidJourney",
    "Booru tag list",
    "Booru-like tag list",
    "Art Critic",
    "Product Listing",
    "Social Media Post"
  ];
  
  const captionLengths: CaptionLength[] = [
    "any",
    "very short",
    "short",
    "medium-length",
    "long",
    "very long"
  ];
  
  function handleFileChange(e: Event) {
    const target = e.target as HTMLInputElement;
    if (target.files && target.files[0]) {
      uploadedImage = target.files[0];
    }
  }
  
  async function handleSubmit(e: Event) {
    e.preventDefault();
    
    const imageToCaption = uploadedImage || currentImage;
    
    if (!client || !imageToCaption) {
      error = "Please upload an image or generate one above.";
      return;
    }
    
    isGenerating = true;
    error = null;
    result = null;
    
    try {
      const output = await client.predict("/stream_chat", [
        imageToCaption,
        captionType,
        captionLength,
        [], // extra_options
        "", // name_input
        ""  // custom_prompt
      ]);
      
      const [prompt, caption] = output.data;
      
      result = {
        caption,
        type: captionType,
        length: captionLength
      };
    } catch (err) {
      console.error(err);
      error = `Caption generation failed: ${err}`;
    } finally {
      isGenerating = false;
    }
  }
</script>

<form class="caption-form" onsubmit={handleSubmit}>
  <h3>Caption Image</h3>
  
  <label for="imageInput">
    Upload Image {currentImage ? 'or use generated image' : ''}
  </label>
  <input 
    type="file" 
    id="imageInput" 
    accept="image/*"
    onchange={handleFileChange}
    bind:this={imageInput}
    disabled={isGenerating}
  />
  
  <label for="captionType">Caption Type</label>
  <select 
    id="captionType" 
    bind:value={captionType}
    disabled={isGenerating}
  >
    {#each captionTypes as type}
      <option value={type}>{type}</option>
    {/each}
  </select>
  
  <label for="captionLength">Caption Length</label>
  <select 
    id="captionLength" 
    bind:value={captionLength}
    disabled={isGenerating}
  >
    {#each captionLengths as length}
      <option value={length}>
        {length.charAt(0).toUpperCase() + length.slice(1).replace('-', ' ')}
      </option>
    {/each}
  </select>
  
  <button 
    type="submit" 
    class="generate-button"
    disabled={isGenerating || !client}
  >
    {isGenerating ? 'Generating Caption…' : 'Generate Caption'}
  </button>
</form>

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

{#if result}
  <div class="caption-result">
    <h4>Generated Caption</h4>
    <p><strong>Type:</strong> {result.type}</p>
    <p><strong>Length:</strong> {result.length}</p>
    <p><strong>Caption:</strong></p>
    <p class="caption-text">{result.caption}</p>
  </div>
{/if}

<style>
  .caption-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="file"], 
  select {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    margin-bottom: 1rem;
  }
  
  .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;
  }
  
  .caption-result {
    background: #f8f9fa;
    padding: 1rem;
    border-radius: 6px;
    margin-top: 1rem;
  }
  
  .caption-result h4 {
    margin-top: 0;
  }
  
  .caption-text {
    font-style: italic;
  }
  
  .error-message {
    color: #dc3545;
    margin-top: 1rem;
    padding: 0.5rem;
    background: #f8d7da;
    border-radius: 4px;
  }
</style>