import { Space, Tag } from 'antd'
import type { ColumnsType } from 'antd/lib/table'
import { useMemo } from 'react'

import { useAgentServiceListAPIProxyRoutes } from 'apiClient/services/agent-gateway'
import type {
  V1Middleware,
  V1Route,
  V1Upstream
} from 'apiClient/services/agent-gateway/interface'

import {
  DetailFields,
  DetailJSON,
  ResourcePageProps,
  ResourceTable
} from '../resources'

function middlewareName(middleware: V1Middleware) {
  if (middleware.operationPolicy) return 'Operation Policy'
  if (middleware.credentialAuth) return 'Credential Auth'
  if (middleware.larkAuthProxy) return 'Lark Auth Proxy'
  return 'Unknown'
}

function upstreamAddress(upstream?: V1Upstream) {
  if (upstream?.baseUrl) return upstream.baseUrl
  if (upstream?.hostTemplate) {
    return upstream.scheme
      ? `${upstream.scheme}://${upstream.hostTemplate}`
      : upstream.hostTemplate
  }
  return '—'
}

const columns: ColumnsType<V1Route> = [
  { title: 'Route ID', dataIndex: 'routeId' },
  {
    title: 'Listener ID',
    dataIndex: 'listenerId',
    render: (value) => value || '—'
  },
  { title: 'Prefix', dataIndex: 'prefix', render: (value) => value || '—' },
  {
    title: 'Upstream',
    key: 'upstream',
    render: (_, route) => upstreamAddress(route.upstream)
  },
  {
    title: 'Middlewares',
    key: 'middlewares',
    render: (_, route) =>
      route.middlewares?.length ? (
        <Space size={[0, 4]} wrap>
          {route.middlewares.map((middleware, index) => (
            <Tag key={index}>{middlewareName(middleware)}</Tag>
          ))}
        </Space>
      ) : (
        '—'
      )
  }
]

function RouteDetail({ route }: { route: V1Route }) {
  const hostParameters = Object.entries(route.upstream?.hostParameters || {})

  return (
    <>
      <DetailFields
        title="Basic Information"
        fields={[
          ['Route ID', route.routeId],
          ['Listener ID', route.listenerId],
          ['Prefix', route.prefix],
          ['Allowed Request Headers', route.allowedRequestHeaders?.join(', ')]
        ]}
      />
      <DetailFields
        title="Upstream"
        fields={[
          ['Base URL', route.upstream?.baseUrl],
          ['Scheme', route.upstream?.scheme],
          ['Host Template', route.upstream?.hostTemplate],
          [
            'Host Parameters',
            hostParameters.length ? (
              <Space direction="vertical" style={{ width: '100%' }}>
                {hostParameters.map(([name, parameter]) => (
                  <DetailFields
                    key={name}
                    title={name}
                    fields={[
                      [
                        'Source',
                        parameter.source?.replace('HOST_PARAMETER_SOURCE_', '')
                      ],
                      ['Allowed Values', parameter.allowedValues?.join(', ')]
                    ]}
                  />
                ))}
              </Space>
            ) : (
              '—'
            )
          ]
        ]}
      />
      <DetailJSON title="Middlewares" value={route.middlewares} />
    </>
  )
}

export default function Routes({ active, agent }: ResourcePageProps) {
  const query = useAgentServiceListAPIProxyRoutes(agent.agentId!, {
    query: {
      enabled: active && !!agent.projectManagementEnabled,
      retry: false,
      refetchOnWindowFocus: false,
      refetchOnReconnect: false,
      keepPreviousData: false
    },
    request: { isShowMessage: false }
  })
  const routes = useMemo(
    () =>
      [...(query.data?.data.routes || [])].sort((left, right) =>
        left.routeId!.localeCompare(right.routeId!)
      ),
    [query.data]
  )

  return (
    <ResourceTable
      active={active}
      agent={agent}
      title="Routes"
      columns={columns}
      records={routes}
      loading={query.isFetching}
      failed={query.isError}
      error={query.error}
      reload={() => query.refetch()}
      recordKey={(route) => route.routeId!}
      renderDetail={(route) => <RouteDetail route={route} />}
    />
  )
}
