<template>
  <div class="category-form">
    <Form @submit="onSubmit" :validation-schema="schema" v-slot="{ errors }" class="row">
      <!-- Tên danh mục -->
      <div class="col-md-12 mb-3">
        <label class="form-label">Tên danh mục <span class="text-danger">*</span></label>
        <Field name="Name" v-model="formData.Name" type="text" class="form-control" placeholder="Nhập tên danh mục..."
          :class="{ 'is-invalid': errors.Name }" />
        <div class="invalid-feedback">{{ errors.Name }}</div>
      </div>

      <!-- Mã tài khoản -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Mã tài khoản</label>
        <Field name="AccountCode" v-model="formData.AccountCode" type="text" class="form-control"
          placeholder="Nhập mã tài khoản..." :class="{ 'is-invalid': errors.AccountCode }" />
        <div class="invalid-feedback">{{ errors.AccountCode }}</div>
      </div>

      <!-- Mô tả -->
      <div class="col-md-12 mb-3">
        <label class="form-label">Mô tả</label>
        <Field as="textarea" rows="3" name="Description" v-model="formData.Description" class="form-control"
          placeholder="Nhập mô tả danh mục..." :class="{ 'is-invalid': errors.Description }" />
        <div class="invalid-feedback">{{ errors.Description }}</div>
      </div>

      <!-- Danh mục cha -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Danh mục cha</label>
        <v-select v-model="selectedParentCategory" label="Name" :filterable="false" :options="parentCategories"
          @search="getParentCategories" placeholder="Chọn danh mục cha (tùy chọn)..."
          :class="{ 'is-invalid': errors.ParentId }">
          <template #no-options="{ search, searching, loading }">
            Gõ từ khóa để tìm....
          </template>
          <template v-slot:option="option">
            <span :style="{ paddingLeft: (option.Level || 0) * 20 + 'px' }">
              {{ option.Name }}
            </span>
          </template>
        </v-select>
        <div class="invalid-feedback d-block" v-if="errors.ParentId">{{ errors.ParentId }}</div>
      </div>

      <!-- Thứ tự hiển thị -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Thứ tự hiển thị <span class="text-danger">*</span></label>
        <Field name="DisplayOrder" v-model="formData.DisplayOrder" type="number" class="form-control"
          placeholder="Nhập thứ tự hiển thị..." :class="{ 'is-invalid': errors.DisplayOrder }" />
        <div class="invalid-feedback">{{ errors.DisplayOrder }}</div>
      </div>

      <!-- Người phê duyệt -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Người phê duyệt</label>
        <v-select v-model="selectedApprover" label="UserName" :filterable="false" :options="users" @search="getUsers"
          placeholder="Chọn người phê duyệt..." :class="{ 'is-invalid': errors.ApprovedBy }">
          <template #no-options="{ search, searching, loading }">
            Gõ từ khóa để tìm....
          </template>
          <template v-slot:option="option">
            {{ option.UserName }} {{ option.FullName ? `(${option.FullName})` : '' }}
          </template>
        </v-select>
        <div class="invalid-feedback d-block" v-if="errors.ApprovedBy">{{ errors.ApprovedBy }}</div>
      </div>

      <!-- Buttons -->
      <div class="col-12 d-flex justify-content-end gap-2">
        <button type="button" class="btn btn-secondary" @click="handleCancel" :disabled="isSubmitting">
          Hủy
        </button>
        <button type="submit" class="btn btn-primary" :disabled="isSubmitting">
          <span v-if="isSubmitting" class="spinner-border spinner-border-sm me-2"></span>
          {{ isEdit ? 'Cập nhật' : 'Tạo mới' }}
        </button>
      </div>
    </Form>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, reactive } from 'vue'
import { Form, Field } from 'vee-validate'
import * as Yup from 'yup'
import _ from 'lodash'
import userService from '@/services/userService'
import incomeCategoryService from '@/services/incomeCategoryService'

const props = defineProps({
  modelValue: {
    type: Object,
    required: true
  },
  isEdit: {
    type: Boolean,
    default: false
  },
  isSubmitting: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue', 'submit', 'cancel'])

// Data
const users = reactive([])
const parentCategories = reactive([])

// Computed
const formData = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// Computed để đảm bảo v-select hiển thị đúng giá trị
const selectedApprover = computed({
  get: () => {
    const id = formData.value?.ApprovedBy
    if (!id) return null

    // Tìm user trong danh sách users
    const user = users.find(u => Number(u.Id) === Number(id))
    return user || null
  },
  set: (value) => {
    if (value) {
      formData.value.ApprovedBy = value.Id
    } else {
      formData.value.ApprovedBy = null
    }
  }
})

// Computed để đảm bảo v-select parent category hiển thị đúng giá trị
const selectedParentCategory = computed({
  get: () => {
    const id = formData.value?.ParentId
    if (!id) return null

    // Tìm category trong danh sách parentCategories
    const category = parentCategories.find(cat => Number(cat.Id) === Number(id))
    return category || null
  },
  set: (value) => {
    if (value) {
      formData.value.ParentId = value.Id
    } else {
      formData.value.ParentId = null
    }
  }
})

// Validation schema
const schema = Yup.object().shape({
  Name: Yup.string()
    .required('Tên danh mục không được để trống')
    .max(128, 'Không vượt quá 128 ký tự'),
  AccountCode: Yup.string()
    .nullable()
    .max(50, 'Mã tài khoản không vượt quá 50 ký tự'),
  Description: Yup.string()
    .nullable()
    .max(256, 'Không vượt quá 256 ký tự'),
  DisplayOrder: Yup.number()
    .typeError('Thứ tự hiển thị không hợp lệ')
    .required('Thứ tự hiển thị không được để trống')
    .min(1, 'Thứ tự hiển thị phải >= 1'),
  ParentId: Yup.number()
    .nullable()
    .notRequired()
    .min(1, 'ID danh mục cha phải >= 1'),
  ApprovedBy: Yup.number()
    .nullable()
    .notRequired()
    .min(1, 'ID người phê duyệt phải >= 1')
})

// Methods
const getUsers = async (keyword, loading) => {
  if (keyword.length) {
    loading(true)
    await getUsersDebounce(loading, keyword)
  }
}

let getUsersDebounce = _.debounce(async (loading, keyword) => {
  users.splice(0, users.length)

  const staffResult = await userService.sugStaff(keyword)
  if (staffResult != null && staffResult.length > 0) {
    staffResult.forEach(staff => {
      users.push(staff)
    })
  }
  loading(false)
}, 500)

const getParentCategories = async (keyword, loading) => {
  if (keyword.length) {
    loading(true)
    await getParentCategoriesDebounce(loading, keyword)
  }
}

let getParentCategoriesDebounce = _.debounce(async (loading, keyword) => {
  parentCategories.splice(0, parentCategories.length)

  try {
    // Lấy danh sách danh mục theo cây phân cấp để có thể chọn làm parent
    const hierarchyResult = await incomeCategoryService.getHierarchy()
    if (hierarchyResult && hierarchyResult.length > 0) {
      // Flatten toàn bộ cây phân cấp thành mảng phẳng
      const flattenedCategories = flattenCategories(hierarchyResult)

      // Lọc theo keyword và loại trừ chính nó nếu đang edit
      const filtered = flattenedCategories.filter(cat => {
        const matchesKeyword = cat.Name.toLowerCase().includes(keyword.toLowerCase())
        const isNotSelf = !props.isEdit || cat.Id !== formData.value?.Id
        return matchesKeyword && isNotSelf
      })

      filtered.forEach(category => {
        parentCategories.push(category)
      })
    }
  } catch (error) {
    console.error('Error loading parent categories:', error)
  }

  loading(false)
}, 500)

const ensureApproverOption = async () => {
  const id = formData.value?.ApprovedBy
  if (!id) return

  if (!users.some(u => Number(u.Id) === Number(id))) {
    try {
      const user = await userService.getStaff(id)
      if (user && user.Id) {
        users.push(user)
      }
    } catch (e) {
      console.error('Error loading approver:', e)
    }
  }
}

// Đảm bảo ApprovedByUserName được hiển thị đúng khi edit
const ensureApproverDisplay = () => {
  const id = formData.value?.ApprovedBy
  const userName = formData.value?.ApprovedByUserName

  if (id && userName) {
    // Kiểm tra xem user đã có trong danh sách chưa
    const existingUser = users.find(u => Number(u.Id) === Number(id))

    if (!existingUser) {
      // Tạo object user từ thông tin có sẵn
      const userObj = {
        Id: id,
        UserName: userName,
        FullName: userName // Fallback nếu không có FullName
      }
      users.push(userObj)
    } else {
      // Cập nhật UserName nếu đã có user nhưng UserName khác
      if (existingUser.UserName !== userName) {
        existingUser.UserName = userName
        existingUser.FullName = userName
      }
    }
  }
}

// Flatten hierarchical data to flat array
const flattenCategories = (categories, level = 0) => {
  const result = []
  categories.forEach(category => {
    // Thêm category hiện tại với level
    result.push({
      ...category,
      Level: level
    })

    // Nếu có children, flatten chúng với level + 1
    if (category.Children && category.Children.length > 0) {
      const childrenFlattened = flattenCategories(category.Children, level + 1)
      result.push(...childrenFlattened)
    }
  })
  return result
}

// Load danh sách danh mục cha cho form
const loadParentCategoriesForForm = async () => {
  try {
    parentCategories.splice(0, parentCategories.length)
    const hierarchyResult = await incomeCategoryService.getHierarchy()
    if (hierarchyResult && hierarchyResult.length > 0) {
      // Flatten toàn bộ cây phân cấp thành mảng phẳng
      const flattenedCategories = flattenCategories(hierarchyResult)
      flattenedCategories.forEach(category => {
        parentCategories.push(category)
      })
    }
  } catch (error) {
    console.error('Error loading parent categories for form:', error)
  }
}

const ensureParentCategoryOption = async () => {
  const id = formData.value?.ParentId
  if (!id) return

  if (!parentCategories.some(cat => Number(cat.Id) === Number(id))) {
    try {
      const category = await incomeCategoryService.getById(id)
      if (category && category.Id) {
        parentCategories.push(category)
      }
    } catch (e) {
      console.error('Error loading parent category:', e)
    }
  }
}

const onSubmit = async () => {
  emit('submit', formData.value)
}

const handleCancel = () => {
  emit('cancel')
}

// Lifecycle
onMounted(async () => {
  // Load danh sách danh mục cha trước để có thể hiển thị đúng
  await loadParentCategoriesForForm()

  // Sau đó mới load thông tin user và parent category
  ensureApproverDisplay()
  await ensureApproverOption()
  await ensureParentCategoryOption()
})

// Watch for changes in ApprovedBy to ensure option exists
watch(() => formData.value?.ApprovedBy, async () => {
  await ensureApproverOption()
})

// Watch for changes in ParentId to ensure option exists
watch(() => formData.value?.ParentId, async () => {
  await ensureParentCategoryOption()
})

// Watch for changes in ApprovedByUserName to ensure display
watch(() => formData.value?.ApprovedByUserName, () => {
  ensureApproverDisplay()
})

// Watch for changes in formData to ensure display
watch(() => formData.value, (newValue) => {
  if (newValue && newValue.ApprovedBy && newValue.ApprovedByUserName) {
    ensureApproverDisplay()
  }
}, { deep: true, immediate: true })

// Watch for changes in parentCategories to ensure parent category display
watch(() => parentCategories.length, () => {
  if (parentCategories.length > 0 && formData.value?.ParentId) {
    // Đảm bảo parent category được hiển thị đúng khi danh sách đã load
    const category = parentCategories.find(cat => Number(cat.Id) === Number(formData.value.ParentId))
    if (!category) {
      ensureParentCategoryOption()
    }
  }
})
</script>

<style scoped>
.category-form {
  padding: 1rem;
}

.form-label {
  font-weight: 500;
  margin-bottom: 0.5rem;
  color: #495057;
}

.text-danger {
  color: #dc3545 !important;
}

.is-invalid {
  border-color: #dc3545;
}

.invalid-feedback {
  display: block;
  color: #dc3545;
  font-size: 0.875rem;
  margin-top: 0.25rem;
}

.btn {
  font-size: 0.875rem;
}
</style>
