import * as React from 'react'
import DefaultLayout from '../layouts'
import { RouteComponentProps } from '@reach/router'
import { stringifyParams, extendSearchParams, parseQuery } from '../helpers/url'
import SearchInput from '../components/SearchInput'
import { apolloClient } from '../clients'
import { ApolloProvider } from 'react-apollo'

type Props = RouteComponentProps

export default abstract class extends React.Component<Props, any> {
  public render() {
    const { location } = this.props
    const { name, namespace, term: searchTerm, version = null } = parseQuery(
      location.search
    )

    const ContentComponent = this.getContentComponent() as any

    return (
      <DefaultLayout
        headerBefore={
          <SearchInput onSearchEnter={this.onSearchEnter} value={searchTerm} />
        }
        showFooter={false}
        {...this.props as any}
      >
        <ApolloProvider client={apolloClient}>
          <ContentComponent
            onBack={this.onBack}
            onChangeVersion={this.onChangeVersion}
            onClickDownload={this.onClickDownload}
            onClickView={this.onClickView}
            name={name}
            version={version}
            namespace={namespace}
          />
        </ApolloProvider>
      </DefaultLayout>
    )
  }

  private onSearchEnter = (searchTerm: string) => {
    const query = stringifyParams({
      term: searchTerm,
    })
    this.props.navigate(`/search/?${query}`)
  }

  private onBack = () => {
    const { term, os, dist, codename } = parseQuery(this.props.location.search)
    if (term) {
      const query = stringifyParams({ term, os, dist, codename })
      this.props.navigate(`/search/?${query}`)
    } else {
      this.props.navigate('/')
    }
  }

  private onChangeVersion = (version: string) => {
    const { search, pathname } = this.props.location
    const query = extendSearchParams(search, {
      version,
    })
    this.props.navigate(`${pathname}/?${query}`)
  }

  private onClickView = () => {
    const { search } = this.props.location
    this.props.navigate(`/package/code/${search}`)
  }

  private onClickDownload = () => {}

  protected abstract getContentComponent(): any
}
