import axios from 'axios'

export type LinkedTenantRecord = {
  id: string
  name?: string
  slug?: string
  primary_domain?: string
  timezone?: string
  default_currency?: string
  is_active?: boolean
}

export type OrganizationTenantSummary = {
  rows: LinkedTenantRecord[]
  count: number
}

export type OrganizationTenantSummaryMap = Record<string, OrganizationTenantSummary>

export const emptyOrganizationTenantSummary: OrganizationTenantSummary = {
  rows: [],
  count: 0,
}

const normalizeTenantRows = (rows: any): LinkedTenantRecord[] => {
  if (!Array.isArray(rows)) {
    return []
  }

  return rows.map((row: any) => ({
    id: row?.id,
    name: row?.name,
    slug: row?.slug,
    primary_domain: row?.primary_domain,
    timezone: row?.timezone,
    default_currency: row?.default_currency,
    is_active: row?.is_active,
  }))
}

export const getTenantSetupHref = (organizationId?: string, organizationName?: string) => {
  if (!organizationId) {
    return '/tenants/tenants-new'
  }

  const params = new URLSearchParams({ organizationId })

  if (organizationName) {
    params.set('organizationName', organizationName)
  }

  return `/tenants/tenants-new?${params.toString()}`
}

export const getTenantViewHref = (tenantId?: string, organizationId?: string, organizationName?: string) => {
  if (!tenantId) {
    return '/tenants/tenants-list'
  }

  const params = new URLSearchParams({ id: tenantId })

  if (organizationId) {
    params.set('organizationId', organizationId)
  }

  if (organizationName) {
    params.set('organizationName', organizationName)
  }

  return `/tenants/tenants-view/?${params.toString()}`
}

export const getTenantManageHref = (
  tenantId?: string,
  organizationId?: string,
  organizationName?: string,
) => {
  if (!tenantId) {
    return '/tenants/tenants-list'
  }

  const params = new URLSearchParams({ id: tenantId })

  if (organizationId) {
    params.set('organizationId', organizationId)
  }

  if (organizationName) {
    params.set('organizationName', organizationName)
  }

  return `/tenants/tenants-edit/?${params.toString()}`
}

export const getOrganizationViewHref = (organizationId?: string, tenantId?: string, tenantName?: string) => {
  if (!organizationId) {
    return '/organizations/organizations-list'
  }

  const params = new URLSearchParams({ id: organizationId })

  if (tenantId) {
    params.set('tenantId', tenantId)
  }

  if (tenantName) {
    params.set('tenantName', tenantName)
  }

  return `/organizations/organizations-view/?${params.toString()}`
}

export const getOrganizationManageHref = (
  organizationId?: string,
  tenantId?: string,
  tenantName?: string,
) => {
  if (!organizationId) {
    return '/organizations/organizations-list'
  }

  const params = new URLSearchParams({ id: organizationId })

  if (tenantId) {
    params.set('tenantId', tenantId)
  }

  if (tenantName) {
    params.set('tenantName', tenantName)
  }

  return `/organizations/organizations-edit/?${params.toString()}`
}

export const mergeEntityOptions = (existingOptions: any[] = [], nextOptions: any[] = []) => {
  const mergedById = new Map<string, any>()

  ;[...existingOptions, ...nextOptions].forEach((item: any) => {
    if (!item?.id) {
      return
    }

    mergedById.set(item.id, item)
  })

  return Array.from(mergedById.values())
}

export const loadLinkedTenantSummary = async (organizationId: string): Promise<OrganizationTenantSummary> => {
  if (!organizationId) {
    return emptyOrganizationTenantSummary
  }

  const { data } = await axios.get('/tenants', {
    params: {
      organizations: organizationId,
      limit: 5,
      page: 0,
      sort: 'asc',
      field: 'name',
    },
  })

  const normalizedRows = normalizeTenantRows(data?.rows)

  return {
    rows: normalizedRows,
    count: typeof data?.count === 'number' ? data.count : normalizedRows.length,
  }
}

export const loadLinkedTenantSummaries = async (
  organizationIds: string[],
): Promise<OrganizationTenantSummaryMap> => {
  const uniqueOrganizationIds = Array.from(new Set(organizationIds.filter(Boolean)))

  if (!uniqueOrganizationIds.length) {
    return {}
  }

  const settledResults = await Promise.allSettled(
    uniqueOrganizationIds.map(async (organizationId) => ({
      summary: await loadLinkedTenantSummary(organizationId),
    })),
  )

  return settledResults.reduce((acc: OrganizationTenantSummaryMap, result, index) => {
    const organizationId = uniqueOrganizationIds[index]

    if (result.status === 'fulfilled') {
      acc[organizationId] = result.value.summary
      return acc
    }

    console.error(`Failed to load linked tenants for organization ${organizationId}:`, result.reason)
    acc[organizationId] = emptyOrganizationTenantSummary
    return acc
  }, {})
}
