<script setup lang="ts">
import { NInput } from 'naive-ui'

import AppInputNumber from '@/components/AppInputNumber.vue'
import { computed, reactive, ref, watch } from 'vue'

import { updateBootVolume } from '@/api/bootVolumes'
import FormField from '@/components/FormField.vue'
import FormModal from '@/components/FormModal.vue'
import type { BootVolume, UpdateBootVolumeRequest } from '@/types/api'
import { useToast } from '@/composables/useToast'

const props = defineProps<{
  show: boolean
  cfgId: number | null
  volume: BootVolume | null
  region?: string
}>()
const emit = defineEmits<{ 'update:show': [boolean]; updated: [] }>()

const message = useToast()
const submitting = ref(false)

const form = reactive({ displayName: '', sizeInGBs: 50, vpusPerGB: 10 })

watch(
  () => props.show,
  (v) => {
    if (v && props.volume)
      Object.assign(form, {
        displayName: props.volume.displayName,
        sizeInGBs: props.volume.sizeInGBs,
        vpusPerGB: props.volume.vpusPerGB,
      })
  },
)

const sizeError = computed(() =>
  props.volume && form.sizeInGBs < props.volume.sizeInGBs ? '仅支持扩容，不能缩小' : '',
)
const canSubmit = computed(() => Boolean(form.displayName.trim()) && !sizeError.value)

/** 零值字段不更新：只提交与当前值不同的字段 */
function buildBody(v: BootVolume): UpdateBootVolumeRequest {
  const body: UpdateBootVolumeRequest = {}
  if (form.displayName.trim() !== v.displayName) body.displayName = form.displayName.trim()
  if (form.sizeInGBs !== v.sizeInGBs) body.sizeInGBs = form.sizeInGBs
  if (form.vpusPerGB !== v.vpusPerGB) body.vpusPerGB = form.vpusPerGB
  return body
}

async function submit() {
  if (props.cfgId === null || !props.volume) return
  const body = buildBody(props.volume)
  if (!Object.keys(body).length) {
    emit('update:show', false)
    return
  }
  submitting.value = true
  try {
    await updateBootVolume(props.cfgId, props.volume.id, body, props.region)
    message.success(body.sizeInGBs ? '修改已提交；扩容后需在实例 OS 内扩展文件系统' : '修改已提交')
    emit('update:show', false)
    emit('updated')
  } catch (e) {
    message.error(e instanceof Error ? e.message : '保存失败')
  } finally {
    submitting.value = false
  }
}
</script>

<template>
  <FormModal
    :show="show"
    title="编辑引导卷"
    :width="440"
    :submitting="submitting"
    :submit-disabled="!canSubmit"
    submit-text="保存修改"
    @update:show="emit('update:show', $event)"
    @submit="submit"
  >
    <FormField label="显示名" required>
      <NInput v-model:value="form.displayName" placeholder="引导卷显示名" />
    </FormField>
    <div class="grid grid-cols-2 gap-3 max-md:grid-cols-1">
      <FormField
        label="大小（GB）"
        hint="仅支持扩容，不能缩小；扩容后需在实例 OS 内扩展文件系统"
        :error="sizeError"
      >
        <AppInputNumber
          v-model:value="form.sizeInGBs"
          :min="volume?.sizeInGBs ?? 47"
          :max="32768"
          class="w-full"
        />
      </FormField>
      <FormField label="性能（VPU/GB）" hint="10 均衡 / 20 高性能 / 30–120 超高性能，步进 10">
        <AppInputNumber
          v-model:value="form.vpusPerGB"
          :min="10"
          :max="120"
          :step="10"
          class="w-full"
        />
      </FormField>
    </div>
  </FormModal>
</template>
