'use client'
import { useQuery } from '@apollo/client'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import React, { ReactElement, useEffect, useState } from 'react'
import { z } from 'zod'
import {
  FeedQueryInput,
  ListNodesDocument,
  NodeQueryInput,
  NodeSortingByEnum,
  SortingWayEnum
} from '../../graphql/generated/types'
import { useMatomo } from '../../hooks/MatomoHook'
import createUrlSearchParams from '../../utils/createUrlSearchParams'
import { stringTrimmed, transform } from '../../utils/transform'
import createSortingInputSchema from '../../schema/createSortingInputSchema'
import ErrorMessage from '../ErrorMessage'
import Loader from '../Loader'
import LoadMoreButton from '../LoadMoreButton'
import ResponsiveTable from '../ResponsiveTable'
import NodeForm from './NodeForm'
import NodeHeader from './NodeHeader'
import NodePlaceholder from './NodePlaceholder'
import NodeResults from './NodeResults'

export const nodeQueryInputSchema = createSortingInputSchema(NodeSortingByEnum)
  .extend(
    {
      search: transform(
        z.string().optional(),
        stringTrimmed,
        z.string()
      )
    }
  )

export default function NodeSearch (): ReactElement {
  const matomo = useMatomo()
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const router = useRouter()
  let routerQuery: NodeQueryInput
  try {
    routerQuery = nodeQueryInputSchema.parse(Object.fromEntries(searchParams))
  } catch (e) {
    routerQuery = {
      search: '',
      sortBy: NodeSortingByEnum.RefreshedAt,
      sortWay: SortingWayEnum.Desc
    }
  }
  console.log('Router query', routerQuery)
  const [query, setQuery] = useState<NodeQueryInput>(routerQuery)
  const [page, setPage] = useState<number>(0)
  const [pageLoading, setPageLoading] = useState<boolean>(false)
  const { loading, error, data, fetchMore, refetch } = useQuery(ListNodesDocument, {
    variables: {
      query,
      paging: {
        page: 0
      }
    }
  })

  useEffect(() => {
    matomo.trackEvent({
      category: 'nodes',
      action: 'next-page',
      customDimensions: [
        {
          value: page.toString(),
          id: 1
        }
      ]
    })
  }, [page])
  useEffect((): void => {
    router.push(`${pathname ?? ''}?${createUrlSearchParams(query).toString()}`)
    matomo.trackEvent({
      category: 'nodes',
      action: 'new-search'
    })
  }, [query])

  const handleQueryChange = (query: FeedQueryInput): void => {
    console.info('Query changed', { query })
    setQuery(query)
    setPage(0)
  }

  const handleSearchSubmit = async (): Promise<void> => {
    setPageLoading(true)
    setQuery(query)
    setPage(0)
    await refetch({ paging: { page: 0 } })
    setPageLoading(false)
  }

  const handleLoadMore = async (): Promise<void> => {
    setPage(page + 1)
    console.info('Loading next page', { query, page })
    setPageLoading(true)
    await fetchMore({
      variables: {
        paging: { page: page + 1 }
      },
      updateQuery: (previousData, { fetchMoreResult }) => {
        console.log('more', {
          previousData, fetchMoreResult
        })
        if (undefined === fetchMoreResult?.listNodes?.items) {
          return previousData
        }
        if (undefined === previousData?.listNodes?.items) {
          return fetchMoreResult
        }
        fetchMoreResult.listNodes.items = [
          ...previousData.listNodes.items,
          ...fetchMoreResult.listNodes.items
        ]
        return fetchMoreResult
      }
    })
    setPageLoading(false)
  }

  const toggleSort = (sortBy: NodeSortingByEnum): void => {
    const sortWay = query.sortBy === sortBy && query.sortWay === SortingWayEnum.Asc ? SortingWayEnum.Desc : SortingWayEnum.Asc
    matomo.trackEvent({
      category: 'nodes',
      action: 'sort',
      customDimensions: [
        {
          value: `${sortBy} ${sortWay}`,
          id: 2
        }
      ]
    })
    setQuery({
      ...query,
      sortBy,
      sortWay
    })
  }

  return (
        <>
            <NodeForm query={query} onQueryChange={handleQueryChange} onSubmit={handleSearchSubmit}/>
            <ResponsiveTable>
                <NodeHeader onSortToggle={toggleSort} query={query}/>
                <Loader loading={loading || pageLoading} showBottom={true} placeholder={(<NodePlaceholder/>)}>
                    <NodeResults nodes={data?.listNodes?.items}/>
                </Loader>
            </ResponsiveTable>
            <LoadMoreButton onClick={handleLoadMore}
                            show={!loading && !pageLoading && data?.listNodes?.paging?.hasNext === true}/>
            <ErrorMessage message={error?.message}/>
        </>
  )
}
