import { ref, computed, watch } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import type { Regency } from '~/models/regency'
import type { Item } from '~/components/pub/my-ui/combobox'
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
import { toTitleCase } from '~/lib/utils'
import * as regencyService from '~/services/regency.service'

// Interface untuk query parameters
interface RegencyQueryParams {
  'province-code'?: string
  search?: string
  'page-number'?: number
  'page-size'?: number
  sort?: string
}

// Interface untuk cached data dengan pagination
interface CachedRegencyData {
  data: Regency[]
  meta: PaginationMeta
  queryKey: string // untuk tracking query yang berbeda
}

// Global cache untuk regencies berdasarkan query key (province-code + search + pagination)
const regenciesCache = reactive(new Map<string, CachedRegencyData>())
const loadingStates = reactive(new Map<string, boolean>())
const errorStates = reactive(new Map<string, string | null>())

interface UseRegenciesOptions {
  provinceCode?: Ref<string | undefined> | string | undefined
  pageSize?: number
  enablePagination?: boolean
  enableSearch?: boolean
}

export function useRegencies(options: UseRegenciesOptions | Ref<string | undefined> | string | undefined = {}) {
  // Backward compatibility - jika parameter pertama adalah provinceCode
  const normalizedOptions: UseRegenciesOptions =
    typeof options === 'object' && 'value' in options
      ? { provinceCode: options }
      : typeof options === 'string' || options === undefined
        ? { provinceCode: options }
        : options

  const { provinceCode, pageSize = 10, enablePagination = true, enableSearch = true } = normalizedOptions

  // Convert provinceCode ke ref jika bukan ref
  const provinceCodeRef =
    typeof provinceCode === 'string' || provinceCode === undefined ? ref(provinceCode) : provinceCode || ref(undefined)

  // State untuk pagination dan search
  const currentPage = ref(1)
  const currentPageSize = ref(pageSize)
  const searchQuery = ref('')

  // Function untuk generate query key
  const generateQueryKey = (params: RegencyQueryParams) => {
    const keyParts = [
      params['province-code'] || '',
      params.search || '',
      params['page-number'] || 1,
      params['page-size'] || pageSize,
      params.sort || 'name:asc',
    ]
    return keyParts.join('|')
  }

  // Current query key
  const currentQueryKey = computed(() => {
    return generateQueryKey({
      'province-code': provinceCodeRef.value,
      search: enableSearch ? searchQuery.value : undefined,
      'page-number': enablePagination ? currentPage.value : undefined,
      'page-size': enablePagination ? currentPageSize.value : undefined,
      sort: 'name:asc',
    })
  })

  // Computed untuk mendapatkan regencies berdasarkan current query
  const regencies = computed(() => {
    const queryKey = currentQueryKey.value
    const cachedData = regenciesCache.get(queryKey)
    return cachedData?.data || []
  })

  // Computed untuk pagination meta
  const paginationMeta = computed(() => {
    const queryKey = currentQueryKey.value
    const cachedData = regenciesCache.get(queryKey)
    return (
      cachedData?.meta || {
        recordCount: 0,
        page: currentPage.value,
        pageSize: currentPageSize.value,
        totalPage: 0,
        hasNext: false,
        hasPrev: false,
      }
    )
  })

  // Computed untuk loading state
  const isLoading = computed(() => {
    const queryKey = currentQueryKey.value
    return loadingStates.get(queryKey) || false
  })

  // Computed untuk error state
  const error = computed(() => {
    const queryKey = currentQueryKey.value
    return errorStates.get(queryKey) || null
  })

  // Computed untuk format Item
  const regencyOptions = computed<Item[]>(() => {
    return regencies.value.map((regency) => ({
      label: toTitleCase(regency.name),
      value: regency.code,
      searchValue: `${regency.code} ${regency.name}`.trim(),
    }))
  })

  // Function untuk fetch regencies dengan pagination dan search
  async function fetchRegencies(params?: Partial<RegencyQueryParams>, forceRefresh = false) {
    const queryParams: RegencyQueryParams = {
      'province-code': params?.['province-code'] || provinceCodeRef.value,
      search: enableSearch ? params?.search || searchQuery.value : undefined,
      'page-number': enablePagination ? params?.['page-number'] || currentPage.value : undefined,
      'page-size': enablePagination ? params?.['page-size'] || currentPageSize.value : undefined,
      sort: params?.sort || 'name:asc',
    }

    // Jika tidak ada province code, return
    // if (!queryParams['province-code']) return  // buat komponen select birth

    const queryKey = generateQueryKey(queryParams)

    // Jika tidak force refresh dan sudah ada cache, skip
    if (!forceRefresh && regenciesCache.has(queryKey)) {
      return
    }

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

    loadingStates.set(queryKey, true)
    errorStates.set(queryKey, null)

    try {
      // Prepare API parameters
      const apiParams: any = {
        sort: queryParams.sort,
        'province-code': queryParams['province-code'],
      }

      // Add pagination or no-limit based on enablePagination
      if (enablePagination && queryParams['page-number'] && queryParams['page-size']) {
        apiParams['page-number'] = queryParams['page-number']
        apiParams['page-size'] = queryParams['page-size']
      } else {
        apiParams['page-no-limit'] = true
      }

      // Add search if enabled and has value
      if (enableSearch && queryParams.search && queryParams.search.trim().length >= 3) {
        apiParams.search = queryParams.search.trim()
      }

      const response = await regencyService.getList(apiParams)

      if (response.success) {
        const regenciesData = response.body.data || []
        const meta = response.body.meta || { record_totalCount: regenciesData.length }

        // Create pagination meta
        const paginationMeta: PaginationMeta = {
          recordCount: meta.record_totalCount,
          page: queryParams['page-number'] || 1,
          pageSize: queryParams['page-size'] || regenciesData.length,
          totalPage:
            enablePagination && queryParams['page-size']
              ? Math.ceil(meta.record_totalCount / queryParams['page-size'])
              : 1,
          hasNext: false,
          hasPrev: false,
        }

        if (enablePagination && queryParams['page-size']) {
          paginationMeta.hasNext = paginationMeta.page < paginationMeta.totalPage
          paginationMeta.hasPrev = paginationMeta.page > 1
        }

        // Cache the result
        regenciesCache.set(queryKey, {
          data: [...regenciesData],
          meta: { ...paginationMeta },
          queryKey,
        })
      } else {
        errorStates.set(queryKey, 'Gagal memuat data kabupaten/kota')
        console.error('Failed to fetch regencies:', response)
      }
    } catch (err) {
      errorStates.set(queryKey, 'Terjadi kesalahan saat memuat data kabupaten/kota')
      console.error('Error fetching regencies:', err)
    } finally {
      loadingStates.set(queryKey, false)
    }
  }

  // Function untuk mencari regency berdasarkan code (search di semua cached data)
  function getRegencyByCode(code: string): Regency | undefined {
    // Search di semua cached data
    for (const cachedData of regenciesCache.values()) {
      const found = cachedData.data.find((regency) => regency.code === code)
      if (found) return found
    }
    return undefined
  }

  // Function untuk mencari regency berdasarkan name (search di semua cached data)
  function getRegencyByName(name: string): Regency | undefined {
    // Search di semua cached data
    for (const cachedData of regenciesCache.values()) {
      const found = cachedData.data.find((regency) => regency.name.toLowerCase() === name.toLowerCase())
      if (found) return found
    }
    return undefined
  }

  // Function untuk pagination
  function goToPage(page: number) {
    if (page >= 1 && page <= paginationMeta.value.totalPage) {
      currentPage.value = page
    }
  }

  function nextPage() {
    if (paginationMeta.value.hasNext) {
      currentPage.value += 1
    }
  }

  function prevPage() {
    if (paginationMeta.value.hasPrev) {
      currentPage.value -= 1
    }
  }

  function changePageSize(size: number) {
    currentPageSize.value = size
    currentPage.value = 1 // Reset ke halaman pertama
  }

  // Function untuk search
  function setSearch(query: string) {
    searchQuery.value = query
    currentPage.value = 1 // Reset ke halaman pertama saat search
  }

  function clearSearch() {
    searchQuery.value = ''
    currentPage.value = 1
  }

  // Function untuk clear cache berdasarkan query key pattern
  function clearCache(provinceCodeParam?: string) {
    const code = provinceCodeParam || provinceCodeRef.value
    if (code) {
      // Clear semua cache yang mengandung province code tersebut
      const keysToDelete: string[] = []
      for (const [key] of regenciesCache.entries()) {
        if (key.startsWith(code + '|')) {
          keysToDelete.push(key)
        }
      }
      keysToDelete.forEach((key) => {
        regenciesCache.delete(key)
        loadingStates.delete(key)
        errorStates.delete(key)
      })
    }
  }

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

  // Function untuk refresh data
  function refreshRegencies(params?: Partial<RegencyQueryParams>) {
    return fetchRegencies(params, true)
  }

  // Debounced province code untuk mencegah multiple calls
  const debouncedProvinceCode = refDebounced(provinceCodeRef, 100)

  // Watch perubahan province code untuk auto fetch
  watch(
    debouncedProvinceCode,
    (newCode, oldCode) => {
      if (newCode && newCode !== oldCode) {
        // Reset pagination dan search saat province code berubah
        currentPage.value = 1
        if (enableSearch) {
          searchQuery.value = ''
        }
        fetchRegencies()
      }
    },
    { immediate: true },
  )

  const triggerFetchAfterIdle = useDebounceFn(() => {
    if (enableSearch) {
      currentPage.value = 1
      fetchRegencies()
    }
  }, 1000)

  // Watch perubahan search query untuk auto fetch dan reset halaman
  watch(searchQuery, (newSearch, oldSearch) => {
    if (newSearch !== oldSearch) {
      triggerFetchAfterIdle()
    }
  })

  // Watch perubahan pagination untuk auto fetch
  watch([currentPage, currentPageSize], () => {
    if (enablePagination) {
      fetchRegencies()
    }
  })

  watch(regencyOptions, (val) => {
    console.log('[regencyOptions] updated', val.length)
  })

  return {
    // Data
    regencies: readonly(regencies),
    regencyOptions,

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

    // Search state
    searchQuery: enableSearch ? searchQuery : readonly(ref('')),

    // Pagination state
    currentPage: enablePagination ? currentPage : readonly(ref(1)),
    currentPageSize: enablePagination ? currentPageSize : readonly(ref(pageSize)),

    // Methods
    fetchRegencies,
    refreshRegencies,
    getRegencyByCode,
    getRegencyByName,
    clearCache,
    clearAllCache,

    // Pagination methods
    goToPage: enablePagination ? goToPage : () => {},
    nextPage: enablePagination ? nextPage : () => {},
    prevPage: enablePagination ? prevPage : () => {},
    changePageSize: enablePagination ? changePageSize : () => {},

    // Search methods
    setSearch: enableSearch ? setSearch : () => {},
    clearSearch: enableSearch ? clearSearch : () => {},
  }
}

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