import React, { useCallback, useEffect, useMemo, useState } from 'react'

import { Checkbox, Group, TextInput, Select, Title } from '@mantine/core'
import { IconSearch } from '@tabler/icons-react'
import { Pagination } from 'antd'
import { Link } from 'react-router-dom'
import useSWR from 'swr'

import { listOrgClusters, listOrgProjects } from '~/api'
import EmptyResult from '~/components/EmptyResult'
import { getComputedCluster, useCurOrg, useUserStore } from '~/hooks/state'
import { IQueryParams, useQueryParams } from '~/hooks/use-query-params'
import { orgClustersTelemetry } from '~/telemetry'
import { getLocalStorageItem, setLocalStorageItem } from '~/utils/env-config'

import { ClusterCard } from './cluster'

const useProjects = (orgId: string) => {
  const { data, error } = useSWR([`/orgs/${orgId}/projects`], () =>
    listOrgProjects(orgId)
  )

  return {
    projects: data,
    isLoading: !error && !data,
    isError: error
  }
}

const useClusters = (orgId: string, queryParams: IQueryParams) => {
  const { data, error } = useSWR([`/orgs/${orgId}/clusters`, queryParams], () =>
    listOrgClusters(
      orgId!,
      queryParams.query,
      queryParams.limit,
      queryParams.page,
      queryParams.projectId,
      queryParams.showDeleted
    )
  )

  return {
    clusters: data,
    isLoading: !error && !data,
    isError: error
  }
}

const ProjectSelector = ({
  projects,
  onChange
}: {
  projects: any[]
  isLoading: boolean
  onChange: any
}) => {
  const [value, setValue] = useState(projects[0].id ?? '')
  const handleChange = useCallback(
    (value: string) => {
      setValue(value)
      onChange(value)
    },
    [onChange]
  )

  return (
    <Select
      label='Project'
      searchable
      onChange={handleChange}
      value={value}
      style={{ width: 250 }}
      data={projects.map((p) => ({ label: p.name, value: p.id }))}
    />
  )
}

const Clusters = ({
  queryParams,
  onPageChange
}: {
  queryParams: IQueryParams
  onPageChange: any
}) => {
  const { curOrg } = useCurOrg()
  const { id: curOrgId } = curOrg!

  const { clusters: clustersRes } = useClusters(curOrgId!, queryParams)

  const clusters = useMemo(() => {
    return clustersRes?.data.items || []
  }, [clustersRes])

  return (
    <div>
      <section className='grid grid-cols-1 md:grid-cols-2 gap-4 pb-4'>
        {clusters.map((cluster, idx) => (
          <Link
            to={`/orgs/${curOrgId}/clusters/${cluster.id}`}
            key={idx}
            onClick={() =>
              orgClustersTelemetry.clickClusterItem({
                name: cluster.name!,
                id: cluster.id!
              })
            }
          >
            <ClusterCard cluster={getComputedCluster(cluster)} />
          </Link>
        ))}
      </section>

      {(clustersRes?.data.total ?? 0) > 0 && (
        <section className='flex justify-end'>
          <Pagination
            total={clustersRes?.data.total}
            current={queryParams.page}
            pageSize={queryParams.limit}
            onChange={onPageChange}
          />
        </section>
      )}

      {clustersRes?.data.total === 0 && <EmptyResult className='mt-24' />}
    </div>
  )
}

const Page: React.FC = () => {
  const { curOrg } = useCurOrg()
  const { id: curOrgId, isOP } = curOrg!
  const { projects: projectsRes, isLoading } = useProjects(curOrgId!)
  const isInternalUser = useUserStore((state) => state.user?.internal)

  const projects = useMemo(() => {
    return projectsRes?.data.items || []
  }, [projectsRes])

  const showDeletedClusters = useMemo(() => {
    const localStorageVal = getLocalStorageItem(
      'search.org_show_deleted_clusters'
    )
    if (localStorageVal !== null) {
      return localStorageVal === 'true'
    }
    return false
  }, [])

  const defParams = {
    query: '',
    projectId: '',
    limit: 10,
    page: 1,
    showDeleted: showDeletedClusters
  }
  const { queryParams, setQueryParams } = useQueryParams(defParams)
  useEffect(() => {
    if (projects.length > 0) {
      setQueryParams({ ...queryParams, projectId: projects[0].id })
    }
  }, [projects])

  const searchPlaceHolderText = useMemo(() => {
    return isOP ? 'Enter a Cluster Name or ID' : 'Enter a Cluster ID'
  }, [isOP])

  const handleProjectChange = (projectId: string) => {
    setQueryParams({ ...queryParams, projectId: projectId, page: 1 })
  }

  function handleSearch(str: string) {
    orgClustersTelemetry.searchCluster(str)
    setQueryParams({ ...queryParams, query: str, page: 1 })
  }

  function handlePageChange(page: number, pageSize: number) {
    orgClustersTelemetry.clickPagination({ page, pageSize })
    setQueryParams({ ...queryParams, page, limit: pageSize })
  }

  function handleShowDeletedClustersCheck(checked: boolean) {
    setQueryParams({ ...queryParams, page: 1, showDeleted: checked })
    setLocalStorageItem('search.org_show_deleted_clusters', checked + '')
  }

  return (
    <div className='flex flex-col max-w-5xl mb-4 mx-auto'>
      <section className='flex justify-between pt-4'>
        <Title order={1} weight={300}>
          Clusters
        </Title>
      </section>
      <section className='flex justify-between items-center pb-4 py-4'>
        <Group>
          {isLoading || projects.length === 0 ? (
            <Select data={[]} />
          ) : (
            <ProjectSelector
              projects={projects}
              isLoading={isLoading}
              onChange={handleProjectChange}
            />
          )}

          <TextInput
            label='Search'
            placeholder={searchPlaceHolderText}
            onKeyPress={(e) => {
              if (e.key === 'Enter') {
                handleSearch(e.currentTarget.value)
              }
            }}
            style={{ width: 300 }}
            rightSection={<IconSearch size={16} stroke={1.5} />}
          />

          {isInternalUser && (
            <Checkbox
              label='Show deleted clusters'
              className='flex'
              wrapperProps={{ style: { marginTop: '21px' } }}
              defaultChecked={queryParams.showDeleted}
              onChange={(e) => handleShowDeletedClustersCheck(e.target.checked)}
            />
          )}
        </Group>
      </section>
      {queryParams.projectId.length > 0 && (
        <Clusters queryParams={queryParams} onPageChange={handlePageChange} />
      )}
    </div>
  )
}

export default Page
