<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<script lang="ts">
  import { createBubbler } from 'svelte/legacy';

  const bubble = createBubbler();
  import type { HTMLInputTypeAttribute } from 'svelte/elements';
  import { twMerge } from 'tailwind-merge';
  import { v4 as uuidv4 } from 'uuid';

  interface Props {
    label?: string;
    id?: string;
    name: string;
    errorMessage?: string;
    value: string | number;
    type?: HTMLInputTypeAttribute;
    prefix?: import('svelte').Snippet;
    suffix?: import('svelte').Snippet;
    [key: string]: any;
  }

  let {
    label = undefined,
    id = uuidv4(),
    name,
    errorMessage = undefined,
    value = $bindable(),
    type = 'text',
    prefix,
    suffix,
    ...rest
  }: Props = $props();

  const inputProps = {
    class: twMerge(
      'w-full px-4 h-full rounded-lg outline-hidden bg-transparent text-color',
      prefix && 'pl-9',
      suffix && 'pr-12'
    ),
    id,
    name,
    ...rest
  };
</script>

<div class="flex flex-col gap-2">
  {#if label}
    <label for={id} class="text-sm ml-1 text-color">
      {label}
    </label>
  {/if}

  <div
    class={twMerge(
      'rounded-md dark:bg-shade-d400  ring-1 ring-gray-300 dark:ring-gray-500 flex items-center h-[40px] text-color relative focus-within:ring-2 focus-within:ring-gray-400 transition group',
      errorMessage && 'ring-red-600! ring-2 '
    )}
  >
    {#if prefix}
      <div class="flex items-center justify-center absolute left-2 top-1/2 -translate-y-1/2">
        {@render prefix?.()}
      </div>
    {/if}

    {#if type === 'text'}
      <input bind:value type="text" oninput={bubble('input')} {...inputProps} />
    {:else if type === 'password'}
      <input bind:value type="password" oninput={bubble('input')} {...inputProps} />
    {:else if type === 'number'}
      <input bind:value type="number" oninput={bubble('input')} {...inputProps} />
    {/if}

    {#if suffix}
      <div class="flex items-center justify-center absolute right-2 top-1/2 -translate-y-1/2">
        {@render suffix?.()}
      </div>
    {/if}
  </div>

  {#if errorMessage}
    <span class="text-red-600 text-xs font-medium ml-1">
      {errorMessage}
    </span>
  {/if}
</div>
