<script lang="ts">
  import type { GradioClient, TextGenerationParams, TextGenerationResult } from '$lib/types';
  
  interface Props {
    client: GradioClient | null;
  }
  
  let { client = null }: Props = $props();
  
  let params: TextGenerationParams = $state({
    prompt: "",
    maxTokens: 200,
    temperature: 1.0,
    topP: 0.7,
    presencePenalty: 0.1,
    countPenalty: 0.1
  });
  
  let isGenerating = $state(false);
  let result: TextGenerationResult | null = $state(null);
  let error: string | null = $state(null);
  
  async function handleSubmit(e: Event) {
    e.preventDefault();
    
    if (!client || !params.prompt.trim()) {
      error = "Please enter a prompt.";
      return;
    }
    
    isGenerating = true;
    error = null;
    result = null;
    
    try {
      const output = await client.predict(0, [
        params.prompt,
        params.maxTokens,
        params.temperature,
        params.topP,
        params.presencePenalty,
        params.countPenalty
      ]);
      
      const generatedText = output.data[0];
      
      result = {
        text: generatedText,
        prompt: params.prompt
      };
    } catch (err) {
      console.error(err);
      error = `Text generation failed: ${err}`;
    } finally {
      isGenerating = false;
    }
  }
</script>

<form class="text-form" onsubmit={handleSubmit}>
  <h3>Generate Text with RWKV</h3>
  
  <label for="textPrompt">Prompt</label>
  <textarea 
    id="textPrompt" 
    bind:value={params.prompt}
    rows="4" 
    placeholder="Enter your prompt here..."
    disabled={isGenerating}
  ></textarea>
  
  <div class="input-row">
    <div class="input-group">
      <label for="maxTokens">Max Tokens</label>
      <input 
        type="number" 
        id="maxTokens" 
        bind:value={params.maxTokens}
        min="10" 
        max="1000" 
        step="10"
        disabled={isGenerating}
      />
    </div>
    <div class="input-group">
      <label for="temperature">Temperature</label>
      <input 
        type="number" 
        id="temperature" 
        bind:value={params.temperature}
        min="0.2" 
        max="2.0" 
        step="0.1"
        disabled={isGenerating}
      />
    </div>
  </div>
  
  <div class="input-row">
    <div class="input-group">
      <label for="topP">Top P</label>
      <input 
        type="number" 
        id="topP" 
        bind:value={params.topP}
        min="0.0" 
        max="1.0" 
        step="0.05"
        disabled={isGenerating}
      />
    </div>
    <div class="input-group">
      <label for="presencePenalty">Presence Penalty</label>
      <input 
        type="number" 
        id="presencePenalty" 
        bind:value={params.presencePenalty}
        min="0.0" 
        max="1.0" 
        step="0.1"
        disabled={isGenerating}
      />
    </div>
  </div>
  
  <label for="countPenalty">Count Penalty</label>
  <input 
    type="number" 
    id="countPenalty" 
    bind:value={params.countPenalty}
    min="0.0" 
    max="1.0" 
    step="0.1"
    disabled={isGenerating}
  />
  
  <button 
    type="submit" 
    class="generate-button"
    disabled={isGenerating || !client}
  >
    {isGenerating ? 'Generating Text…' : 'Generate Text'}
  </button>
</form>

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

{#if result}
  <div class="text-result">
    <h4>Generated Text</h4>
    <p><strong>Prompt:</strong> {result.prompt.substring(0, 100)}{result.prompt.length > 100 ? '...' : ''}</p>
    <p><strong>Generated:</strong></p>
    <div class="generated-text">{result.text}</div>
  </div>
{/if}

<style>
  .text-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;
  }
  
  textarea {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    margin-bottom: 1rem;
    font-family: inherit;
    resize: vertical;
  }
  
  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-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;
  }
  
  .text-result {
    background: #f8f9fa;
    padding: 1rem;
    border-radius: 6px;
    margin-top: 1rem;
  }
  
  .text-result h4 {
    margin-top: 0;
  }
  
  .generated-text {
    white-space: pre-wrap;
    font-family: monospace;
    background: #fff;
    padding: 1rem;
    border-radius: 4px;
    border: 1px solid #ddd;
  }
  
  .error-message {
    color: #dc3545;
    margin-top: 1rem;
    padding: 0.5rem;
    background: #f8d7da;
    border-radius: 4px;
  }
</style>