import { ref } from 'vue'

interface DashboardServiceInfo {
  recipient_id?: number
}

export interface DashboardService {
  id?: number | string
  service_name: string
  service_infos?: DashboardServiceInfo[]
}

interface DashboardMinistry {
  id?: number | string
  ministry_name: string
}

const services = ref<DashboardService[]>([])
const ministries = ref<DashboardMinistry[]>([])
// The first render must reserve the selector/matrix space until the client fetch starts.
const isLoadingServices = ref(true)
// When the fetch fails we surface a friendly error (shown by dropdown placeholders)
// instead of silently leaving the list empty.
const servicesError = ref<string | null>(null)
let hasFetchedServices = false
// Dedup guard: prevents duplicate concurrent fetches when multiple
// components mount and call fetchServicesAndMinistries() at once.
let isFetchInProgress = false

// Coerce the raw API payload into clean DashboardService rows:
// drops invalid rows, trims names, and removes duplicates by name.
const normalizeServices = (value: unknown): DashboardService[] | null => {
  if (!Array.isArray(value)) return null

  const seen = new Set<string>()
  const normalized: DashboardService[] = []

  for (const item of value) {
    if (!item || typeof item !== 'object') continue

    const record = item as {
      id?: number | string
      service_name?: unknown
      service_infos?: unknown
    }
    const serviceName = typeof record.service_name === 'string' ? record.service_name.trim() : ''

    if (!serviceName || seen.has(serviceName)) continue
    seen.add(serviceName)

    normalized.push({
      id: record.id,
      service_name: serviceName,
      service_infos: Array.isArray(record.service_infos) ? record.service_infos as DashboardServiceInfo[] : []
    })
  }

  return normalized
}

// Same normalization/dedup as services, but for ministry rows.
const normalizeMinistries = (value: unknown): DashboardMinistry[] | null => {
  if (!Array.isArray(value)) return null

  const seen = new Set<string>()
  const normalized: DashboardMinistry[] = []

  for (const item of value) {
    if (!item || typeof item !== 'object') continue

    const record = item as { id?: number | string, ministry_name?: unknown }
    const ministryName = typeof record.ministry_name === 'string' ? record.ministry_name.trim() : ''

    if (!ministryName || seen.has(ministryName)) continue
    seen.add(ministryName)
    normalized.push({ id: record.id, ministry_name: ministryName })
  }

  return normalized
}

export const useDashboardServices = () => {
  // force=true bypasses the cache so the UI can offer a manual "Retry".
  const fetchServicesAndMinistries = async (force = false) => {
    if ((!force && hasFetchedServices) || isFetchInProgress) return
    isFetchInProgress = true
    isLoadingServices.value = true
    servicesError.value = null

    try {
      const api = useApi()
      const [servicesData, ministriesData] = await Promise.all([
        api.post('v3/dashboard/servicelist', {}),
        api.post('v3/dashboard/ministry', {})
      ])

      const normalizedServices = normalizeServices(servicesData?.data)
      const normalizedMinistries = normalizeMinistries(ministriesData?.data)

      if (!normalizedServices || !normalizedMinistries) {
        throw new Error('Service list response does not match the expected data shape')
      }

      services.value = normalizedServices
      ministries.value = normalizedMinistries
      hasFetchedServices = true
    } catch (error) {
      // On failure: empty both lists, flag the error, and reset the cache so a
      // later Retry will actually re-fetch instead of being skipped.
      services.value = []
      ministries.value = []
      servicesError.value = 'Service options unavailable'
      hasFetchedServices = false
      console.error('Failed to fetch services and ministries:', error)
    } finally {
      isFetchInProgress = false
      isLoadingServices.value = false
    }
  }

  return {
    services,
    ministries,
    isLoadingServices,
    servicesError,
    fetchServicesAndMinistries
  }
}
