<template>
  <div class="expense-form">
    <Form @submit="onSubmit" :validation-schema="schema" :initial-values="initialFormData" v-slot="{ errors }" class="row">
      <!-- Mô tả chi phí -->
      <div class="col-md-12 mb-3">
        <label class="form-label">Mô tả chi phí <span class="text-danger">*</span></label>
        <Field name="Description" v-model="formData.Description" type="text" class="form-control"
          placeholder="Nhập mô tả chi phí..." :class="{ 'is-invalid': errors.Description }" />
        <div class="invalid-feedback">{{ errors.Description }}</div>
      </div>

      <!-- Số tiền -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Số tiền <span class="text-danger">*</span></label>
        <Field name="Amount" v-slot="{ field }">
          <VueNumberFormat 
            v-model:value="formData.Amount" 
            class="form-control"
            :options="{ precision: 0, prefix: '', suffix: ' VND', decimal: ',', thousand: '.', isInteger: true }"
            placeholder="Nhập số tiền..."
            :class="{ 'is-invalid': errors.Amount }"
            @update:modelValue="(value) => {
              // Convert formatted value to number for validation
              const numValue = value ? parseFloat(value.toString().replace(/[.,]/g, '').replace(' VND', '')) : null
              field.onInput(numValue)
            }" />
        </Field>
        <div class="invalid-feedback d-block" v-if="errors.Amount">{{ errors.Amount }}</div>
      </div>

      <!-- Danh mục chi phí -->
      <div class="col-md-6 mb-3">
        <label class="form-label">Danh mục chi phí <span class="text-danger">*</span></label>
        <v-select 
          v-model="formData.ExpenseCategoryId"
          label="Name" 
          :options="categories"
          :reduce="(option) => option.Id"
          placeholder="Chọn danh mục..." 
          @search="getCategories">
          <template #no-options="{ search, searching }">
            Gõ từ khóa để tìm danh mục....
          </template>
          <template v-slot:option="option">
            <span :style="{ paddingLeft: (option.Level || 0) * 20 + 'px' }">
              {{ option.Name }}
              <small v-if="option.Level > 0" class="text-muted">(Level {{ option.Level }})</small>
            </span>
          </template>
        </v-select>
        <Field v-model="formData.ExpenseCategoryId" name="ExpenseCategoryId" type="hidden" />
        <ErrorMessage class="invalid-feedback d-block" name="ExpenseCategoryId" />
      </div>

      <!-- Tài khoản ngân hàng -->
      <div class="col-md-12 mb-3">
        <label class="form-label">Tài khoản ngân hàng nhận tiền</label>
        <v-select 
          v-model="formData.UserBankAccountId"
          label="DisplayText" 
          :options="bankAccounts"
          :reduce="(option) => option.Id"
          placeholder="Chọn tài khoản ngân hàng..." 
          :clearable="true">
          <template #no-options="{ search, searching, loading }">
            Không có tài khoản ngân hàng nào
          </template>
          <template v-slot:option="option">
            <div>
              <div class="fw-bold">{{ option.AccountHolderName }}</div>
              <div class="text-muted small">{{ option.AccountNumber }} - {{ option.BankName }}</div>
              <div v-if="option.IsDefault" class="badge bg-primary">Mặc định</div>
            </div>
          </template>
        </v-select>
        <Field v-model="formData.UserBankAccountId" name="UserBankAccountId" type="hidden" />
        <ErrorMessage class="invalid-feedback d-block" name="UserBankAccountId" />
        <small class="form-text text-muted">Thông tin ngân hàng sẽ được sao chép và lưu trữ cố định khi tạo chi phí</small>
      </div>

      <!-- Ghi chú -->
      <div class="col-md-12 mb-3">
        <label class="form-label">Ghi chú</label>
        <Field as="textarea" rows="3" name="Note" v-model="formData.Note" class="form-control"
          placeholder="Nhập ghi chú (tùy chọn)..." :class="{ 'is-invalid': errors.Note }" />
        <div class="invalid-feedback">{{ errors.Note }}</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, reactive, watch } from 'vue'
import { Form, Field, ErrorMessage } from 'vee-validate'
import * as Yup from 'yup'
import _ from 'lodash'
import expenseCategoryService from '@/services/expenseCategoryService'
import expenseService from '@/services/expenseService'
import myBankAccountService from '@/services/myBankAccountService'

const props = defineProps({
  id: {
    type: [Number, String],
    default: '0'
  },
  isSubmitting: {
    type: Boolean,
    default: false
  }
})

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

// Data
const categories = reactive([])
const bankAccounts = reactive([])
const formData = reactive(expenseService.createDefaultExpenseModel())
const loading = ref(false)

// Computed
const isEdit = computed(() => {
  // Check if id is a valid GUID (not '0', null, undefined, or empty)
  const id = props.id?.toString()
  console.log('isEdit computed - props.id:', props.id, 'id string:', id)
  const result = id && id !== '0' && id !== '' && id !== 'null' && id !== 'undefined'
  console.log('isEdit computed - result:', result)
  return result
})

// Initial form data for vee-validate
const initialFormData = computed(() => {
  return {
    ...formData,
    ExpenseCategoryId: formData?.ExpenseCategoryId || null
  }
})


// Validation schema
const schema = Yup.object().shape({
  Description: Yup.string()
    .required('Mô tả chi phí không được để trống')
    .max(256, 'Không vượt quá 256 ký tự'),
  Amount: Yup.number()
    .required('Số tiền không được để trống')
    .min(1, 'Số tiền phải lớn hơn 0')
    .typeError('Số tiền phải là một số hợp lệ'),
  ExpenseCategoryId: Yup.number()
    .required('Danh mục chi phí không được để trống')
    .min(1, 'Vui lòng chọn danh mục chi phí hợp lệ'),
  UserBankAccountId: Yup.number()
    .nullable()
    .min(1, 'Tài khoản ngân hàng không hợp lệ'),
  Note: Yup.string()
    .nullable()
    .max(512, 'Không vượt quá 512 ký tự')
})

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

// 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
}

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

  try {
    const hierarchyResult = await expenseCategoryService.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
      const filtered = flattenedCategories.filter(cat =>
        cat.Name.toLowerCase().includes(keyword.toLowerCase())
      )

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

  loading(false)
}, 500)

// Load bank accounts for current user
const loadBankAccounts = async () => {
  try {
    bankAccounts.splice(0, bankAccounts.length)
    const accounts = await myBankAccountService.getAll()
    
    if (accounts && accounts.length > 0) {
      accounts.forEach(account => {
        bankAccounts.push({
          Id: account.Id,
          DisplayText: `${account.AccountHolderName} - ${account.AccountNumber} (${account.BankName})`,
          AccountHolderName: account.AccountHolderName,
          AccountNumber: account.AccountNumber,
          BankName: account.BankName,
          IsDefault: account.IsDefault
        })
      })
      
      console.log('Loaded bank accounts:', bankAccounts.length)
    }
  } catch (error) {
    console.error('Error loading bank accounts:', error)
  }
}

// Load danh sách danh mục chi phí cho form
const loadCategoriesForForm = async () => {
  try {
    categories.splice(0, categories.length)
    const hierarchyResult = await expenseCategoryService.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 => {
        categories.push(category)
      })
    }
  } catch (error) {
    console.error('Error loading categories for form:', error)
  }
}

// Load dữ liệu expense nếu đang edit
const loadExpenseData = async () => {
  console.log('loadExpenseData called - props.id:', props.id, 'type:', typeof props.id)
  console.log('isEdit.value:', isEdit.value)
  
  if (!isEdit.value) {
    // Tạo mới - khởi tạo dữ liệu mặc định
    const defaultData = expenseService.createDefaultExpenseModel()
    Object.assign(formData, defaultData)
    console.log('Create mode - initialized default data')
    return
  }

  try {
    loading.value = true
    console.log('Loading expense data for id:', props.id)
    const expense = await expenseService.getById(props.id)
    console.log('Loaded expense data:', expense)
    
    if (expense) {
      Object.assign(formData, expense)
      console.log('Form data after loading:', formData)
    } else {
      console.error('Expense not found for id:', props.id)
      const defaultData = expenseService.createDefaultExpenseModel()
      Object.assign(formData, defaultData)
    }
  } catch (error) {
    console.error('Error loading expense data:', error)
    const defaultData = expenseService.createDefaultExpenseModel()
    Object.assign(formData, defaultData)
  } finally {
    loading.value = false
  }
}


const onSubmit = async (values, { setFieldError }) => {
  try {
    // Use values from Form and merge with formData to include Id
    const submitData = { 
      ...values,
      Id: formData.Id // Include Id from formData
    }
    
    console.log('ExpenseForm onSubmit - submitData:', submitData)
    
    // Ensure Amount is properly converted to number
    if (submitData.Amount) {
      if (typeof submitData.Amount === 'string') {
        submitData.Amount = parseFloat(submitData.Amount.toString().replace(/[.,]/g, '').replace(' VND', ''))
      }
      
      // Validate amount after conversion
      if (isNaN(submitData.Amount) || submitData.Amount <= 0) {
        setFieldError('Amount', 'Số tiền phải lớn hơn 0')
        return
      }
    }
    
    emit('submit', submitData)
  } catch (error) {
    console.error('Error in onSubmit:', error)
  }
}

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

// Lifecycle
onMounted(async () => {
  console.log('ExpenseForm mounted with props.id:', props.id, 'type:', typeof props.id)
  
  // Load danh sách danh mục chi phí và tài khoản ngân hàng
  await Promise.all([
    loadCategoriesForForm(),
    loadBankAccounts()
  ])
  
  // Load dữ liệu expense (nếu edit mode)
  await loadExpenseData()
})

// Watch for props.id changes to reload data
watch(() => props.id, async (newId, oldId) => {
  if (newId !== oldId) {
    await loadExpenseData()
  }
})
</script>

<style scoped>
.expense-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>
