<template>
  <input
    :id="id"
    :type="type"
    :value="modelValue"
    :placeholder="placeholder"
    :disabled="disabled"
    :required="required"
    :class="inputClasses"
    :aria-invalid="error ? 'true' : null"
    @input="onInput"
  />
</template>

<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';

// It's good practice to define specific types for props like 'type' if you want to restrict them,
// but for VInput, standard HTML input types are numerous.
// For now, we'll use String and rely on native HTML behavior.
// type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' ; // etc.

export default defineComponent({
  name: 'VInput',
  props: {
    modelValue: {
      type: [String, Number] as PropType<string | number>,
      required: true,
    },
    type: {
      type: String, // as PropType<InputType> if you define a specific list
      default: 'text',
    },
    placeholder: {
      type: String,
      default: null,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    required: {
      type: Boolean,
      default: false,
    },
    error: {
      type: Boolean,
      default: false,
    },
    id: {
      type: String,
      default: null,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const inputClasses = computed(() => [
      'form-input',
      { 'error': props.error },
    ]);

    const onInput = (event: Event) => {
      const target = event.target as HTMLInputElement;
      // For number inputs, target.value might still be a string,
      // convert if type is number and value is parsable.
      // However, v-model.number modifier usually handles this.
      // Here, we just emit the raw value. Parent can handle conversion.
      emit('update:modelValue', target.value);
    };

    return {
      inputClasses,
      onInput,
    };
  },
});
</script>

<style lang="scss" scoped>
.form-input {
  display: block;
  width: 100%; // Inputs typically span the full width of their container
  padding: 0.5em 0.75em; // Example padding, adjust as per design
  font-size: 1rem;
  font-family: inherit; // Inherit font from parent
  line-height: 1.5;
  color: #212529; // Example text color (Bootstrap's default)
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid #ced4da; // Example border (Bootstrap's default)
  border-radius: 0.25rem; // Example border-radius
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;

  &:focus {
    border-color: #80bdff; // Example focus color (Bootstrap's default)
    outline: 0;
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); // Example focus shadow
  }

  &::placeholder {
    color: #6c757d; // Example placeholder color (Bootstrap's default)
    opacity: 1; // Override Firefox's lower default opacity
  }

  &[disabled],
  &[readonly] {
    background-color: #e9ecef; // Example disabled background (Bootstrap's default)
    opacity: 1; // Ensure text is readable
    cursor: not-allowed;
  }

  // Error state
  &.error {
    border-color: #dc3545; // Example error color (Bootstrap's danger)
    // Add other error state styling, e.g., box-shadow, text color if needed
    &:focus {
      border-color: #dc3545;
      box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
    }
  }
}

// Specific styling for different input types if needed, e.g., for number inputs
// input[type="number"] {
//   // Styles for number inputs, like removing spinners on some browsers
// }
</style>
