<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import type { PopoverPlacement } from 'naive-ui';
import { NButton, NInput, NPopover } from 'naive-ui';

type AutosizeOptions = {
  minRows?: number;
  maxRows?: number;
};

interface Props {
  value?: string | number | null;
  size?: NaiveUI.InputProps['size'];
  autosize?: AutosizeOptions;
  width?: number;
  minWidth?: number;
  placement?: PopoverPlacement;
}

const props = withDefaults(defineProps<Props>(), {
  value: '',
  size: 'small',
  autosize: () => ({ minRows: 4, maxRows: 8 }),
  width: 320,
  minWidth: 240,
  placement: 'bottom-start'
});

const emit = defineEmits<{
  (e: 'update:value', value: string): void;
  (e: 'updateValue', value: string): void;
}>();

const showPopover = ref(false);
const normalizedValue = computed(() => (props.value ?? '').toString());
const innerValue = ref(normalizedValue.value);

watch(
  () => props.value,
  val => {
    const next = (val ?? '').toString();
    if (next !== innerValue.value) {
      innerValue.value = next;
    }
  }
);

function handleInput(value: string) {
  innerValue.value = value;
  emit('update:value', value);
  emit('updateValue', value);
}

function togglePopover(show?: boolean) {
  if (typeof show === 'boolean') {
    showPopover.value = show;
    return;
  }
  showPopover.value = !showPopover.value;
}
</script>

<template>
  <NPopover trigger="click" :placement="placement" :show="showPopover" @update:show="togglePopover">
    <template #trigger>
      <NInput :size="size" :value="innerValue" @update:value="handleInput">
        <template #prefix>
          <NButton size="tiny" quaternary circle class="textarea-expand-btn" @click.stop="togglePopover()">
            <icon-ic-round-open-in-full />
          </NButton>
        </template>
      </NInput>
    </template>
    <div class="inline-textarea-popover" :style="{ width: `${width}px`, minWidth: `${minWidth}px` }">
      <NInput type="textarea" :value="innerValue" :autosize="autosize" @update:value="handleInput" />
    </div>
  </NPopover>
</template>

<style scoped>
.textarea-expand-btn {
  margin-right: 4px;
}

.inline-textarea-popover {
  max-width: 80vw;
}
</style>
