<template>
  <div
    class="custom-textarea-container bg-white dark:bg-gray-700 border-2 border-gray-200 dark:border-gray-600"
    :class="{ 'focused': isFocused, 'disabled': disabled }"
    @drop="handleDrop"
    @dragover="handleDragOver"
    @dragenter="handleDragEnter"
    @dragleave="handleDragLeave"
  >
        <textarea
          ref="textareaRef"
          :value="modelValue"
          :placeholder="placeholder"
          :disabled="disabled"
          :readonly="readonly"
          :maxlength="maxlength"
          :rows="rows"
          class="custom-textarea"
          @input="handleInput"
          @focus="handleFocus"
          @blur="handleBlur"
          @keydown="handleKeydown"
          @paste="handlePaste"
        ></textarea>

    <div class="textarea-actions" v-if="clearable || $slots.actions">
      <button
        v-if="clearable && modelValue && !disabled"
        class="clear-btn"
        @click="handleClear"
        type="button"
      >
        <i class="fas fa-times"></i>
      </button>
      <slot name="actions"></slot>
    </div>
  </div>
</template>

<script setup>
import {ref, nextTick, watch} from 'vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: ''
  },
  disabled: {
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: false
  },
  maxlength: {
    type: Number,
    default: undefined
  },
  rows: {
    type: Number,
    default: 3
  },
  autoResize: {
    type: Boolean,
    default: false
  },
  maxRows: {
    type: Number,
    default: 6
  },
  detectPaste: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(['update:modelValue', 'focus', 'blur', 'clear', 'keydown', 'paste-file']);

const textareaRef = ref(null);
const isFocused = ref(false);

const handleInput = (event) => {
  emit('update:modelValue', event.target.value);

  if (props.autoResize) {
    autoResize();
  }
};

const handleFocus = (event) => {
  isFocused.value = true;
  emit('focus', event);
};

const handleBlur = (event) => {
  isFocused.value = false;
  emit('blur', event);
};

const handleClear = () => {
  emit('update:modelValue', '');
  emit('clear');
  textareaRef.value?.focus();

  if (props.autoResize) {
    autoResize();
  }
};

const handleKeydown = (event) => {
  emit('keydown', event);
};

const handlePaste = (event) => {
  if (!props.detectPaste) return;

  const items = event.clipboardData?.items;
  if (!items) return;

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item.kind === 'file') {
      event.preventDefault();
      const file = item.getAsFile();
      if (file) {
        emit('paste-file', file);
      }
      break;
    }
  }
};

const handleDrop = (event) => {
  event.preventDefault();
  const files = event.dataTransfer?.files;
  if (files && files.length > 0) {
    emit('paste-file', files[0]);
  }
};

const handleDragOver = (event) => {
  event.preventDefault();
};

const handleDragEnter = (event) => {
  event.preventDefault();
};

const handleDragLeave = (event) => {
  event.preventDefault();
};

const autoResize = () => {
  nextTick(() => {
    if (!textareaRef.value) return;

    const textarea = textareaRef.value;
    textarea.style.height = 'auto';

    const lineHeight = parseInt(getComputedStyle(textarea).lineHeight);
    const maxHeight = lineHeight * props.maxRows;
    const scrollHeight = textarea.scrollHeight;

    textarea.style.height = Math.min(scrollHeight, maxHeight) + 'px';
  });
};

const focus = () => {
  textareaRef.value?.focus();
};

const blur = () => {
  textareaRef.value?.blur();
};

// 监听内容变化自动调整高度
watch(() => props.modelValue, () => {
  if (props.autoResize) {
    autoResize();
  }
});

defineExpose({
  focus,
  blur
});
</script>

<style scoped>
.custom-textarea-container {
  position: relative;
  border-radius: 12px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}

.custom-textarea-container:hover {
  border-color: #cbd5e1;
}

.dark .custom-textarea-container:hover {
  border-color: #6b7280;
}

.custom-textarea-container.focused {
  border-color: #4361ee;
  box-shadow: 0 0 0 4px rgba(67, 97, 238, 0.1);
}

.dark .custom-textarea-container.focused {
  box-shadow: 0 0 0 4px rgba(67, 97, 238, 0.2);
}

.custom-textarea-container.disabled {
  background: #f8fafc;
  border-color: #e2e8f0;
  cursor: not-allowed;
}

.dark .custom-textarea-container.disabled {
  background: #1f2937;
  border-color: #374151;
}

.custom-textarea {
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  padding: 12px 16px;
  font-size: 14px;
  line-height: 1.5;
  resize: none;
  font-family: inherit;
}

.custom-textarea::placeholder {
  color: #94a3b8;
}

.dark .custom-textarea::placeholder {
  color: #6b7280;
}

.custom-textarea:disabled {
  cursor: not-allowed;
  color: #94a3b8;
}

.dark .custom-textarea:disabled {
  color: #6b7280;
}

.textarea-actions {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  gap: 8px;
}

.clear-btn {
  background: none;
  border: none;
  color: #94a3b8;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.clear-btn:hover {
  color: #64748b;
  background: #f1f5f9;
}

.dark .clear-btn:hover {
  color: #d1d5db;
  background: #4b5563;
}
</style>
