<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
import { CollectionPropertiesObject } from '@MailManager/models/collection'
import type { CollectionObject } from '@MailManager/models/collection'
import type { ServiceObject } from '@MailManager/models'

interface Props {
  modelValue: boolean
  service: ServiceObject
  folder: CollectionObject
  allFolders?: CollectionObject[]
}

const props = withDefaults(defineProps<Props>(), {
  allFolders: () => []
})

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  updated: [folder: CollectionObject]
}>()

const collectionsStore = useCollectionsStore()

const folderName = ref('')
const loading = ref(false)
const errorMessage = ref('')
const validationErrors = ref<string[]>([])

const dialogValue = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit('update:modelValue', value)
})

const isValid = computed(() => {
  return folderName.value.trim().length > 0 && validationErrors.value.length === 0
})

const parentFolderLabel = computed(() => {
  const parentId = props.folder.collection
  if (parentId === null || parentId === undefined) return 'Root'

  const parent = props.allFolders.find(
    f =>
      String(f.identifier) === String(parentId) &&
      f.provider === props.folder.provider &&
      String(f.service) === String(props.folder.service)
  )

  return parent?.properties.label || 'Root'
})

const validateFolderName = (name: string): string[] => {
  const errors: string[] = []

  if (!name || name.trim().length === 0) {
    errors.push('Folder name is required')
    return errors
  }

  if (name.length > 255) {
    errors.push('Folder name too long (max 255 characters)')
  }

  if (/[<>:"|?*\x00-\x1F]/.test(name)) {
    errors.push('Folder name contains invalid characters')
  }

  if (props.service.provider === 'imap' && /[\/\\]/.test(name)) {
    errors.push('IMAP folder names cannot contain / or \\')
  }

  if (name !== name.trim()) {
    errors.push('Folder name cannot have leading or trailing spaces')
  }

  return errors
}

const checkDuplicateName = (name: string): boolean => {
  const parentId = props.folder.collection ?? null
  return props.allFolders.some(f => {
    if (String(f.identifier) === String(props.folder.identifier)) return false
    return (
      f.properties.label === name &&
      String(f.collection) === String(parentId) &&
      f.provider === props.folder.provider &&
      String(f.service) === String(props.folder.service)
    )
  })
}

watch(folderName, (newName) => {
  errorMessage.value = ''
  validationErrors.value = validateFolderName(newName)

  if (validationErrors.value.length === 0 && newName.trim().length > 0 && checkDuplicateName(newName)) {
    validationErrors.value.push('A folder with this name already exists in this location')
  }
})

function resetForm() {
  folderName.value = props.folder.properties.label || ''
  errorMessage.value = ''
  validationErrors.value = []
  loading.value = false
}

watch(dialogValue, (isOpen) => {
  if (isOpen) {
    resetForm()
  }
}, { immediate: true })

const handleRename = async () => {
  const errors = validateFolderName(folderName.value)
  if (errors.length > 0) {
    validationErrors.value = errors
    return
  }

  if (checkDuplicateName(folderName.value)) {
    validationErrors.value = ['A folder with this name already exists in this location']
    return
  }

  const newName = folderName.value.trim()
  if (newName === props.folder.properties.label) {
    dialogValue.value = false
    return
  }

  loading.value = true
  errorMessage.value = ''

  try {
    const properties = new CollectionPropertiesObject()
    properties.label = newName
    properties.rank = props.folder.properties.rank ?? 0
    properties.subscribed = props.folder.properties.subscribed ?? true

    const updatedFolder = await collectionsStore.update(
      props.folder.provider,
      props.folder.service,
      props.folder.identifier,
      properties
    )

    emit('updated', updatedFolder)
    dialogValue.value = false
    resetForm()
  } catch (error: any) {
    console.error('[RenameFolderDialog] Failed to rename folder:', error)
    errorMessage.value = error.message || 'Failed to rename folder. Please try again.'
  } finally {
    loading.value = false
  }
}

const handleCancel = () => {
  dialogValue.value = false
  resetForm()
}
</script>

<template>
  <v-dialog
    v-model="dialogValue"
    max-width="500"
    persistent
  >
    <v-card>
      <v-card-title class="text-h5">
        Rename Folder
      </v-card-title>

      <v-card-text>
        <div class="mb-4">
          <div class="text-caption text-medium-emphasis">Account</div>
          <div class="text-body-2">
            {{ service.label || service.primaryAddress || 'Mail Account' }}
          </div>
        </div>

        <div class="mb-4">
          <div class="text-caption text-medium-emphasis">Location</div>
          <div class="text-body-2">
            {{ parentFolderLabel }}
          </div>
        </div>

        <v-text-field
          v-model="folderName"
          label="Folder Name"
          placeholder="Enter folder name"
          variant="outlined"
          autofocus
          :error-messages="validationErrors"
          :disabled="loading"
          @keyup.enter="isValid && handleRename()"
        />

        <v-alert
          v-if="errorMessage"
          type="error"
          variant="tonal"
          density="compact"
          class="mt-2"
        >
          {{ errorMessage }}
        </v-alert>
      </v-card-text>

      <v-card-actions>
        <v-spacer />

        <v-btn
          variant="text"
          :disabled="loading"
          @click="handleCancel"
        >
          Cancel
        </v-btn>

        <v-btn
          color="primary"
          variant="elevated"
          :loading="loading"
          :disabled="!isValid"
          @click="handleRename"
        >
          Save
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<style scoped>
.text-caption {
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.0333em;
}
</style>
