<template>
  <div class="saap-input" :class="wrapperClasses">
    <!-- Label -->
    <label v-if="label" :for="inputId" class="saap-input__label">
      {{ label }}
      <span v-if="required" class="saap-input__required" aria-label="required">*</span>
    </label>
    
    <!-- Input Container -->
    <div class="saap-input__container">
      <!-- Left Icon -->
      <component
        v-if="icon && iconPosition === 'left'"
        :is="iconComponent"
        class="saap-input__icon saap-input__icon--left"
        aria-hidden="true"
      />
      
      <!-- Input Element -->
      <input
        :id="inputId"
        ref="inputRef"
        :class="inputClasses"
        :type="type"
        :value="modelValue"
        :placeholder="placeholder"
        :disabled="disabled"
        :readonly="readonly"
        :required="required"
        :aria-invalid="!!error"
        :aria-describedby="ariaDescribedBy"
        v-bind="$attrs"
        @input="handleInput"
        @change="handleChange"
        @focus="handleFocus"
        @blur="handleBlur"
      >
      
      <!-- Right Icon -->
      <component
        v-if="icon && iconPosition === 'right'"
        :is="iconComponent"
        class="saap-input__icon saap-input__icon--right"
        aria-hidden="true"
      />
      
      <!-- Clear Button -->
      <button
        v-if="clearable && modelValue && !disabled && !readonly"
        type="button"
        class="saap-input__clear"
        aria-label="Clear input"
        @click="handleClear"
      >
        <XIcon class="saap-input__clear-icon" />
      </button>
    </div>
    
    <!-- Helper Text -->
    <div v-if="hint || error || success" class="saap-input__helper">
      <!-- Error Message -->
      <div
        v-if="error"
        :id="`${inputId}-error`"
        class="saap-input__error"
        role="alert"
      >
        <AlertCircleIcon class="saap-input__error-icon" aria-hidden="true" />
        {{ error }}
      </div>
      
      <!-- Success Message -->
      <div
        v-else-if="success"
        :id="`${inputId}-success`"
        class="saap-input__success"
      >
        <CheckCircleIcon class="saap-input__success-icon" aria-hidden="true" />
        {{ success }}
      </div>
      
      <!-- Hint -->
      <div
        v-else-if="hint"
        :id="`${inputId}-hint`"
        class="saap-input__hint"
      >
        {{ hint }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, defineEmits, defineProps, ref, useId, withDefaults } from 'vue'
import { XIcon, AlertCircleIcon, CheckCircleIcon } from 'lucide-vue-next'
import type { InputProps } from '@/types'

interface Props extends InputProps {
  clearable?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  type: 'text',
  size: 'md',
  disabled: false,
  readonly: false,
  required: false,
  iconPosition: 'left',
  clearable: false
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: string | number]
  change: [value: string | number]
  focus: [event: FocusEvent]
  blur: [event: FocusEvent]
  clear: []
}>()

// Refs
const inputRef = ref<HTMLInputElement>()
const inputId = useId()

// Computed
const wrapperClasses = computed(() => [
  `saap-input--${props.size}`,
  {
    'saap-input--disabled': props.disabled,
    'saap-input--readonly': props.readonly,
    'saap-input--error': !!props.error,
    'saap-input--success': !!props.success,
    'saap-input--with-icon': !!props.icon,
    'saap-input--with-icon-left': props.icon && props.iconPosition === 'left',
    'saap-input--with-icon-right': props.icon && props.iconPosition === 'right',
    'saap-input--clearable': props.clearable
  }
])

const inputClasses = computed(() => [
  'saap-input__field',
  {
    'saap-input__field--with-icon-left': props.icon && props.iconPosition === 'left',
    'saap-input__field--with-icon-right': props.icon && props.iconPosition === 'right',
    'saap-input__field--clearable': props.clearable && props.modelValue
  }
])

const iconComponent = computed(() => {
  if (props.icon) {
    return resolveIconComponent(props.icon)
  }
  return null
})

const ariaDescribedBy = computed(() => {
  const ids = []
  if (props.error) ids.push(`${inputId}-error`)
  if (props.success) ids.push(`${inputId}-success`)
  if (props.hint) ids.push(`${inputId}-hint`)
  return ids.length ? ids.join(' ') : undefined
})

// Methods
function handleInput(event: Event) {
  const target = event.target as HTMLInputElement
  emit('update:modelValue', target.value)
}

function handleChange(event: Event) {
  const target = event.target as HTMLInputElement
  emit('change', target.value)
}

function handleFocus(event: FocusEvent) {
  emit('focus', event)
}

function handleBlur(event: FocusEvent) {
  emit('blur', event)
}

function handleClear() {
  emit('update:modelValue', '')
  emit('clear')
  inputRef.value?.focus()
}

function resolveIconComponent(iconName: string) {
  try {
    return () => import(`lucide-vue-next/dist/esm/icons/${iconName}.js`)
  } catch {
    return null
  }
}

// Expose methods for parent components
defineExpose({
  focus: () => inputRef.value?.focus(),
  blur: () => inputRef.value?.blur(),
  select: () => inputRef.value?.select()
})
</script>

<style lang="scss" scoped>
@import '@/styles/mixins.scss';

.saap-input {
  display: flex;
  flex-direction: column;
  gap: var(--saap-space-2);
  
  // Sizes
  &--sm {
    font-size: var(--saap-text-sm);
  }
  
  &--md {
    font-size: var(--saap-text-base);
  }
  
  &--lg {
    font-size: var(--saap-text-lg);
  }
}

.saap-input__label {
  display: flex;
  align-items: center;
  gap: var(--saap-space-1);
  font-weight: var(--saap-font-medium);
  color: var(--saap-neutral-700);
  font-size: var(--saap-text-sm);
  line-height: var(--saap-leading-normal);
}

.saap-input__required {
  color: var(--saap-error);
  font-weight: var(--saap-font-normal);
}

.saap-input__container {
  position: relative;
  display: flex;
  align-items: center;
}

.saap-input__field {
  @include input-base;
  
  // Icon spacing
  &--with-icon-left {
    padding-left: 2.5rem;
    
    .saap-input--sm & {
      padding-left: 2.25rem;
    }
    
    .saap-input--lg & {
      padding-left: 3rem;
    }
  }
  
  &--with-icon-right {
    padding-right: 2.5rem;
    
    .saap-input--sm & {
      padding-right: 2.25rem;
    }
    
    .saap-input--lg & {
      padding-right: 3rem;
    }
  }
  
  &--clearable {
    padding-right: 2.5rem;
    
    .saap-input--sm & {
      padding-right: 2.25rem;
    }
    
    .saap-input--lg & {
      padding-right: 3rem;
    }
  }
  
  // States
  .saap-input--error & {
    border-color: var(--saap-error);
    
    &:focus {
      border-color: var(--saap-error);
      box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
    }
  }
  
  .saap-input--success & {
    border-color: var(--saap-success);
    
    &:focus {
      border-color: var(--saap-success);
      box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
    }
  }
}

.saap-input__icon {
  position: absolute;
  width: 1rem;
  height: 1rem;
  color: var(--saap-neutral-500);
  pointer-events: none;
  
  &--left {
    left: var(--saap-space-3);
    
    .saap-input--sm & {
      left: var(--saap-space-2);
    }
    
    .saap-input--lg & {
      left: var(--saap-space-4);
    }
  }
  
  &--right {
    right: var(--saap-space-3);
    
    .saap-input--sm & {
      right: var(--saap-space-2);
    }
    
    .saap-input--lg & {
      right: var(--saap-space-4);
    }
  }
  
  .saap-input--sm & {
    width: 0.875rem;
    height: 0.875rem;
  }
  
  .saap-input--lg & {
    width: 1.125rem;
    height: 1.125rem;
  }
}

.saap-input__clear {
  position: absolute;
  right: var(--saap-space-3);
  width: 1.25rem;
  height: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--saap-border-radius-sm);
  color: var(--saap-neutral-500);
  cursor: pointer;
  transition: var(--saap-transition-fast);
  
  &:hover {
    color: var(--saap-neutral-700);
    background: var(--saap-neutral-100);
  }
  
  &:focus {
    outline: 2px solid var(--saap-primary-400);
    outline-offset: 1px;
  }
  
  .saap-input--sm & {
    right: var(--saap-space-2);
    width: 1rem;
    height: 1rem;
  }
  
  .saap-input--lg & {
    right: var(--saap-space-4);
    width: 1.5rem;
    height: 1.5rem;
  }
}

.saap-input__clear-icon {
  width: 0.75rem;
  height: 0.75rem;
  
  .saap-input--sm & {
    width: 0.625rem;
    height: 0.625rem;
  }
  
  .saap-input--lg & {
    width: 1rem;
    height: 1rem;
  }
}

.saap-input__helper {
  display: flex;
  align-items: flex-start;
  gap: var(--saap-space-2);
  font-size: var(--saap-text-sm);
  line-height: var(--saap-leading-normal);
}

.saap-input__error,
.saap-input__success,
.saap-input__hint {
  display: flex;
  align-items: flex-start;
  gap: var(--saap-space-1);
}

.saap-input__error {
  color: var(--saap-error);
}

.saap-input__success {
  color: var(--saap-success);
}

.saap-input__hint {
  color: var(--saap-neutral-600);
}

.saap-input__error-icon,
.saap-input__success-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  margin-top: 0.125rem; // Align with text
}

// Focus within styling
.saap-input:focus-within .saap-input__label {
  color: var(--saap-primary-600);
}

.saap-input--error:focus-within .saap-input__label {
  color: var(--saap-error);
}

.saap-input--success:focus-within .saap-input__label {
  color: var(--saap-success);
}
</style>
