import { ref, computed, watch } from 'vue'
import { refDebounced } from '@vueuse/core'
import type { District } from '~/models/district'
import type { SelectItem } from '~/components/pub/my-ui/form/select.vue'
import { toTitleCase } from '~/lib/utils'
import * as districtService from '~/services/district.service'

// Global cache untuk districts berdasarkan regency code
const districtsCache = ref<Map<string, District[]>>(new Map())
const loadingStates = ref<Map<string, boolean>>(new Map())
const errorStates = ref<Map<string, string | null>>(new Map())

export function useDistricts(regencyCode: Ref<string | undefined> | string | undefined) {
  // Convert regencyCode ke ref jika bukan ref
  const regencyCodeRef = typeof regencyCode === 'string' || regencyCode === undefined ? ref(regencyCode) : regencyCode

  // Computed untuk mendapatkan districts berdasarkan regency code
  const districts = computed(() => {
    const code = regencyCodeRef.value
    if (!code) return []
    return districtsCache.value.get(code) || []
  })

  // Computed untuk loading state
  const isLoading = computed(() => {
    const code = regencyCodeRef.value
    if (!code) return false
    return loadingStates.value.get(code) || false
  })

  // Computed untuk error state
  const error = computed(() => {
    const code = regencyCodeRef.value
    if (!code) return null
    return errorStates.value.get(code) || null
  })

  // Computed untuk format SelectItem
  const districtOptions = computed<SelectItem[]>(() => {
    return districts.value.map((district) => ({
      label: toTitleCase(district.name),
      value: district.code,
      searchValue: `${district.code} ${district.name}`.trim(),
    }))
  })

  // Function untuk fetch districts berdasarkan regency code
  async function fetchDistricts(regencyCodeParam?: string, forceRefresh = false, isUserAction = false) {
    const code = regencyCodeParam || regencyCodeRef.value
    if (!code) return

    // Jika user action atau force refresh, selalu fetch
    // Jika bukan user action dan sudah ada cache, skip
    if (!isUserAction && !forceRefresh && districtsCache.value.has(code)) {
      return
    }

    // Jika sedang loading, skip untuk mencegah duplicate calls
    if (loadingStates.value.get(code)) {
      return
    }

    // Tambahan: Cek apakah ada pending request untuk code yang sama
    const pendingKey = `pending_${code}`
    if (loadingStates.value.get(pendingKey)) {
      return
    }

    loadingStates.value.set(pendingKey, true)

    loadingStates.value.set(code, true)
    errorStates.value.set(code, null)

    try {
      const response = await districtService.getList({
        sort: 'name:asc',
        'regency-code': code,
        'page-no-limit': true,
      })

      if (response.success) {
        const districtsData = response.body.data || []
        districtsCache.value.set(code, districtsData)
      } else {
        errorStates.value.set(code, 'Gagal memuat data kecamatan')
        console.error('Failed to fetch districts:', response)
      }
    } catch (err) {
      errorStates.value.set(code, 'Terjadi kesalahan saat memuat data kecamatan')
      console.error('Error fetching districts:', err)
    } finally {
      loadingStates.value.set(code, false)
      loadingStates.value.delete(pendingKey)
    }
  }

  // Function untuk mencari district berdasarkan code
  function getDistrictByCode(code: string): District | undefined {
    const regencyCode = regencyCodeRef.value
    if (!regencyCode) return undefined

    const districtsForRegency = districtsCache.value.get(regencyCode) || []
    return districtsForRegency.find((district) => district.code === code)
  }

  // Function untuk mencari district berdasarkan name
  function getDistrictByName(name: string): District | undefined {
    const regencyCode = regencyCodeRef.value
    if (!regencyCode) return undefined

    const districtsForRegency = districtsCache.value.get(regencyCode) || []
    return districtsForRegency.find((district) => district.name.toLowerCase() === name.toLowerCase())
  }

  // Function untuk clear cache regency tertentu
  function clearCache(regencyCodeParam?: string) {
    const code = regencyCodeParam || regencyCodeRef.value
    if (code) {
      districtsCache.value.delete(code)
      loadingStates.value.delete(code)
      errorStates.value.delete(code)
    }
  }

  // Function untuk clear semua cache
  function clearAllCache() {
    districtsCache.value.clear()
    loadingStates.value.clear()
    errorStates.value.clear()
  }

  // Function untuk refresh data
  function refreshDistricts(regencyCodeParam?: string) {
    const code = regencyCodeParam || regencyCodeRef.value
    if (code) {
      return fetchDistricts(code, true)
    }
  }

  // Debounced regency code untuk mencegah multiple calls
  const debouncedRegencyCode = refDebounced(regencyCodeRef, 100)

  // Watch perubahan regency code untuk auto fetch
  watch(
    debouncedRegencyCode,
    (newCode, oldCode) => {
      if (newCode && newCode !== oldCode) {
        // Jika ada oldCode berarti user action (ganti pilihan)
        const isUserAction = !!oldCode
        fetchDistricts(newCode, false, isUserAction)
      }
    },
    { immediate: true },
  )

  return {
    // Data
    districts: readonly(districts),
    districtOptions,

    // State
    isLoading: readonly(isLoading),
    error: readonly(error),

    // Methods
    fetchDistricts,
    refreshDistricts,
    getDistrictByCode,
    getDistrictByName,
    clearCache,
    clearAllCache,
  }
}

// Export untuk direct access ke cached data (jika diperlukan)
export const useDistrictsCache = () => ({
  districtsCache: readonly(districtsCache),
  loadingStates: readonly(loadingStates),
  errorStates: readonly(errorStates),
})
