import React, { useState } from 'react'
import {
  View,
  StyleSheet,
  TouchableOpacity,
  Text,
  ActivityIndicator,
  FlatList,
} from 'react-native'

import { useLogout } from '../components/Logout'
import { colors, colorsV2 } from '../Colors'
import { TextStyles, Styles } from '../Styles'
import { Artist } from '../types/Artist'
import * as Sentry from 'sentry-expo'
import { ArtistImage } from '../components/ArtistImage'
import { Strings } from '../i18n'
import { User } from '../user'
import { useArtists } from '../hooks/useArtists'
import { SearchBar } from '../components/SearchBar'
import { NoResults } from '../components/NoResults'

const styles = StyleSheet.create({
  artist: {
    paddingVertical: 8,
    marginLeft: 40,
    flexDirection: 'row',
    flex: 1,
    alignItems: 'center',
  },
  hasBottomBorder: {
    borderBottomColor: colors.mutedBrightMetal,
    borderBottomWidth: 1,
  },
  container: {
    flexGrow: 1,
    justifyContent: 'flex-start',
    marginTop: 20,
  },
  artistItem: {
    marginVertical: 9,
    flexDirection: 'row',
    alignItems: 'center',
    marginHorizontal: 7,
  },
  gridImage: {
    borderWidth: 4,
    borderColor: colors.white,
  },
  image: {
    marginRight: 16,
    borderWidth: 2,
    borderColor: colors.white,
  },
  initial: {
    ...TextStyles.h3,
    color: colors.white,
    marginBottom: 40,
    marginHorizontal: 9,
    marginTop: 40,
  },
  empty: {
    ...TextStyles.h3,
    color: colors.white,
    maxWidth: 315,
  },
  artistName: {
    ...TextStyles.bodyHeader,
    flex: 1,
    color: colors.white,
    marginStart: 23,
  },
})

export const ArtistsScreen: React.FC<{ user: User }> = ({ user }) => {
  const logout = useLogout()
  const [searchString, setSearchString] = useState('')
  const loading = useArtists(user)
  const artists = user?.artists ?? []

  if (!loading && artists.length === 0) {
    Sentry.Native.captureMessage(
      `No artists for user id ${user.id}`,
      Sentry.Native.Severity.Warning
    )

    return (
      <View style={styles.container}>
        <Header />
        <EmptyArtists />
        <LogoutButton onPress={logout} />
      </View>
    )
  }
  const isPreviouslySelectedArtist = ({ sonyArtistId }: Artist) =>
    sonyArtistId === user.previousArtistId
  const sortByName = (a: Artist, b: Artist) => a.name.localeCompare(b.name)
  const sortPreviouslySelectedArtistFirst = (a: Artist, b: Artist) =>
    isPreviouslySelectedArtist(a) ? -1 : 1

  const filteredArtists = artists
    .filter((artist) =>
      artist.name.toLowerCase().includes(searchString.toLowerCase().trim())
    )
    .sort(sortByName)
    .sort(sortPreviouslySelectedArtistFirst)

  const canAccessPreviousArtist =
    filteredArtists[0]?.sonyArtistId === user.previousArtistId

  const showInitialInstruction = !(
    user.previousArtistId && canAccessPreviousArtist
  )

  return (
    <View
      style={{
        backgroundColor: colorsV2.black,
        flex: 1,
        ...Styles.screenHorizontalPadding,
      }}
    >
      {!loading && (
        <Header>
          {showInitialInstruction && (
            <Text style={styles.initial}>{Strings.ArtistsScreen.initial}</Text>
          )}
          {artists.length > 5 && (
            <SearchBar
              filter={searchString}
              setFilter={setSearchString}
              placeholder={Strings.Shared.SearchHintArtist}
            />
          )}
        </Header>
      )}

      <View style={styles.container}>
        {loading ? (
          <View style={{ flexGrow: 1, justifyContent: 'center' }}>
            <ActivityIndicator size="large" />
          </View>
        ) : (
          <FlatList
            style={{ flex: 1 }}
            contentContainerStyle={{ flexGrow: 1 }}
            showsVerticalScrollIndicator={false}
            data={filteredArtists}
            ListEmptyComponent={<NoResults />}
            renderItem={({ item }) => (
              <ArtistListItem
                artist={item}
                onPress={() => user.setLastUsedArtistId(item.sonyArtistId)}
                sticky={item.sonyArtistId === user.previousArtistId}
              />
            )}
            keyExtractor={(item) => item.sonyArtistId}
            ListFooterComponent={<LogoutButton onPress={logout} />}
            ListFooterComponentStyle={{ flex: 1 }}
            stickyHeaderIndices={
              filteredArtists.some(isPreviouslySelectedArtist) ? [0] : []
            }
          />
        )}
      </View>
    </View>
  )
}

const EmptyArtists: React.FC = () => (
  <View style={{ flexDirection: 'column', alignItems: 'flex-start' }}>
    <View style={{ marginLeft: 8 }}>
      <Text style={styles.empty}>{Strings.ArtistsScreen.empty}</Text>
    </View>
  </View>
)

const LogoutButton: React.FC<{ onPress: () => void }> = ({ onPress }) => (
  <View
    style={{
      paddingVertical: 77,
      flex: 1,
      justifyContent: 'flex-end',
    }}
  >
    <TouchableOpacity onPress={onPress}>
      <Text
        style={[
          TextStyles.bodyHeader,
          { color: colors.white, textAlign: 'center' },
        ]}
      >
        {Strings.Shared.LogOut}
      </Text>
    </TouchableOpacity>
  </View>
)

const Header: React.FC<{}> = ({ children }) => {
  return (
    <View
      style={{
        marginTop: 40,
      }}
    >
      {children}
    </View>
  )
}

const ArtistListItem: React.FC<{
  artist: Artist
  sticky: boolean
  onPress: () => void
}> = ({ artist, sticky, onPress }) => (
  <TouchableOpacity
    onPress={onPress}
    style={
      sticky
        ? {
            backgroundColor: colorsV2.black,
            ...styles.hasBottomBorder,
          }
        : {}
    }
  >
    <View key={artist.sonyArtistId} style={styles.artistItem}>
      {artist.image && artist.image.uri && (
        <ArtistImage
          key={artist.image.uri}
          artist={artist}
          size={89}
          style={styles.gridImage}
        />
      )}
      <Text style={styles.artistName}>{artist.name}</Text>
    </View>
  </TouchableOpacity>
)
