import React, { useContext } from 'react'
import { RouteProp } from '@react-navigation/native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import {
  createStackNavigator,
  StackNavigationProp,
} from '@react-navigation/stack'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { Colors, colors } from './Colors'
import Globe from './icons/Globe'
import Library from './icons/Library'
import SettingsIcon from './icons/Settings'
import SocialNodes from './icons/SocialNodes'
import { CountriesScreen } from './screens/CountriesScreen'
import { FollowersScreen } from './screens/FollowersScreen'
import { GlobeScreen } from './screens/GlobeScreen'
import { SocialScreen } from './screens/SocialScreen'
import { TrackScreen } from './screens/TrackScreenV2'
import { LibraryScreen } from './screens/LibraryScreen'
import { ScreenNames } from './constants/ScreenNames'
import { Track } from './types/Track'
import { Country as CountryType } from './types/Country'
import { UserContext } from './contexts/UserContext'
import { ArtistContext } from './contexts/ArtistContext'
import { TracksScreen } from './screens/TracksScreen'
import { TrackStreamSourcesScreen } from './screens/TrackStreamSourcesScreen'
import { TrackChartsScreen } from './screens/TrackChartsScreen'
import { TrackPlaylistsScreen } from './screens/TrackPlaylistsScreen'
import { TrackPlaylistScreen } from './screens/TrackPlaylistScreen'
import { ChartDsp, Dsp, SocialMedia, StreamingDsp } from './Consts'
import { ProductsScreen } from './screens/ProductsScreen'
import { ProductDetailScreen } from './screens/ProductDetailScreen'
import { Mode } from './types/helpers'
import { VideosScreen, VideosScreenModes } from './screens/VideosScreen'
import { VideoScreen } from './screens/VideoScreen'
import { VideoViewsGraphScreen } from './screens/VideoViewsGraphScreen'
import { VideoEngagementGraphScreen } from './screens/VideoEngagementGraphScreen'
import { SearchScreen } from './screens/SearchScreen'
import { TrackStreamsGraphScreen } from './screens/TrackStreamsGraphScreen'
import { MarketSelectorScreen } from './screens/MarketSelectorScreen'
import { ProductTracksComparisonScreen } from './screens/ProductTracksComparisonScreen'
import { TrackTikTokScreen } from './screens/TrackTikTokScreen'
import { TimeInterval } from './types/TimeInterval'
import { SettingsScreen } from './screens/SettingsScreen'
import { MarketScreen } from './screens/MarketScreen'
import { ArtistStreamsGraphScreen } from './screens/ArtistStreamsGraphScreen'
import { MarketChartsScreen } from './screens/MarketChartsScreen'

const trackScreens = [
  {
    name: ScreenNames.Track,
    component: TrackScreen,
  },
  {
    name: ScreenNames.TrackStreamSources,
    component: TrackStreamSourcesScreen,
  },
  {
    name: ScreenNames.TrackStreamsGraph,
    component: TrackStreamsGraphScreen,
  },
  {
    name: ScreenNames.TrackCharts,
    component: TrackChartsScreen,
  },
  {
    name: ScreenNames.TrackPlaylists,
    component: TrackPlaylistsScreen,
  },
  {
    name: ScreenNames.TrackTikTok,
    component: TrackTikTokScreen,
  },

  {
    name: ScreenNames.TrackPlaylist,
    component: TrackPlaylistScreen,
  },
  {
    name: ScreenNames.MarketSelector,
    component: MarketSelectorScreen,
  },
  {
    name: ScreenNames.ProductTracksComparison,
    component: ProductTracksComparisonScreen,
  },
]

const Country = createStackNavigator()
const CountryNavigation = () => (
  <Country.Navigator headerMode="none">
    <Country.Screen name={ScreenNames.Globe} component={GlobeScreen} />
    <Country.Screen name={ScreenNames.Countries} component={CountriesScreen} />
    <Country.Screen name={ScreenNames.Market} component={MarketScreen} />
    <Country.Screen
      name={ScreenNames.ArtistStreamsGraph}
      component={ArtistStreamsGraphScreen}
    />
    <Country.Screen
      name={ScreenNames.MarketCharts}
      component={MarketChartsScreen}
    />
    {trackScreens.map(({ name, component }) => (
      <Country.Screen key={name} name={name} component={component} />
    ))}
  </Country.Navigator>
)

const Tracks = createStackNavigator()
const TracksNavigation = () => (
  <Tracks.Navigator headerMode="none">
    <Tracks.Screen name={ScreenNames.Library} component={LibraryScreen} />
    <Tracks.Screen name={ScreenNames.Tracks} component={TracksScreen} />
    {trackScreens.map(({ name, component }) => (
      <Tracks.Screen key={name} name={name} component={component} />
    ))}
    <Tracks.Screen name={ScreenNames.Products} component={ProductsScreen} />
    <Tracks.Screen
      name={ScreenNames.ProductDetail}
      component={ProductDetailScreen}
    />
    <Tracks.Screen name={ScreenNames.Videos} component={VideosScreen} />
    <Tracks.Screen name={ScreenNames.Video} component={VideoScreen} />
    <Tracks.Screen
      name={ScreenNames.VideoViewsGraph}
      component={VideoViewsGraphScreen}
    />
    <Tracks.Screen
      name={ScreenNames.VideoEngagementGraph}
      component={VideoEngagementGraphScreen}
    />
    <Tracks.Screen name={ScreenNames.Search} component={SearchScreen} />
  </Tracks.Navigator>
)

const Social = createStackNavigator()
const SocialNavigation = () => (
  <Social.Navigator headerMode="none">
    <Social.Screen name={ScreenNames.Social} component={SocialScreen} />
    <Social.Screen name={ScreenNames.Followers} component={FollowersScreen} />
  </Social.Navigator>
)

const Settings = createStackNavigator()
const SettingsNavigation = () => (
  <Settings.Navigator headerMode="none">
    <Settings.Screen name={ScreenNames.Settings} component={SettingsScreen} />
  </Settings.Navigator>
)

const TabNavigator = createBottomTabNavigator()

export const Navigation = () => {
  const user = useContext(UserContext)
  const insets = useSafeAreaInsets()
  const artistId = user.lastUsedArtist.sonyArtistId

  const artist = artistId
    ? user.artists?.find((a) => a.sonyArtistId === artistId)
    : null ?? user.lastUsedArtist

  return (
    <ArtistContext.Provider value={artist}>
      <TabNavigator.Navigator
        initialRouteName={ScreenNames.TracksTab}
        screenOptions={({ route }) => ({
          tabBarIcon: ({ focused, color, size }) => {
            if (route.name === ScreenNames.Globe) {
              return <Globe focused={focused} tintColor={color} />
            }

            if (route.name === ScreenNames.TracksTab) {
              return <Library focused={focused} tintColor={color} />
            }

            if (route.name === ScreenNames.SocialTab) {
              return <SocialNodes focused={focused} tintColor={color} />
            }

            if (route.name === ScreenNames.SettingsTab) {
              return <SettingsIcon focused={focused} tintColor={color} />
            }

            return <Globe focused={focused} tintColor={color} />
          },
        })}
        tabBarOptions={{
          showLabel: false,
          inactiveTintColor: colors.gray,
          style: [
            {
              backgroundColor: Colors.background,
              borderTopWidth: 0,
              margin: 8,
              ...{
                marginBottom:
                  insets.bottom > 0 ? -insets.bottom / 2 : undefined, //Pull buttons closer to the bottom on iPhoneX, etc. phones with rounded bottom corners
              },
            },
          ],
        }}
      >
        <TabNavigator.Screen
          name={ScreenNames.TracksTab}
          component={TracksNavigation}
        />
        <TabNavigator.Screen
          name={ScreenNames.CountriesTab}
          component={CountryNavigation}
        />
        <TabNavigator.Screen
          name={ScreenNames.SocialTab}
          component={SocialNavigation}
        />
        <TabNavigator.Screen
          name={ScreenNames.SettingsTab}
          component={SettingsNavigation}
        />
      </TabNavigator.Navigator>
    </ArtistContext.Provider>
  )
}

interface FollowersScreenProps {
  artistId?: string
  dspSlug: SocialMedia
  data: {
    dspSlug: string
    title: string
    data: number[]
  }[]
  timeInterval?: TimeInterval
}

export interface CountryTrackProps {
  track?: Track
  isrc?: string
  artistId?: string
  countryCode?: string
  countryName?: string
}

type NavigationParamList = {
  Artist: { artistId: string }
  CountriesTab: undefined
  Countries: { artistId?: string; timeInterval?: TimeInterval }
  Market: {
    artistId?: string
    countryCode: string
  }
  MarketCharts: { countryCode: string; dsp: ChartDsp }
  Filter: undefined
  Followers: FollowersScreenProps
  Globe: { artistId?: string }
  SocialTab: undefined
  Social: { artistId: string }
  Track: { isrc: string; track?: Track; countryCode?: string }
  Tracks: { mode: Mode }
  MarketSelector: {
    previousScreen: keyof NavigationParamList
    topMarketCountryCodes?: string[]
  }
  Products: { mode: Mode }
  ProductDetail: { productId: string; timeInterval?: TimeInterval }
  ProductTracksComparison: { productId: string }
  ArtistTab: null
  TracksTab: null
  CountryTrack: CountryTrackProps
  Library: { artistId: string }
  Settings: undefined
  TrackStreamsSource: { isrc: string; dsp: StreamingDsp | 'all' }
  TrackStreamSources: {
    isrc: string
    dsp: StreamingDsp
    countryCode?: string
  }
  TrackStreamsGraph: { isrc: string; dsp: Dsp | 'all'; countryCode?: string }
  TrackCharts: { isrc: string; dsp: ChartDsp; countryCode?: string }
  TrackPlaylists: { isrc: string; dsp: ChartDsp }
  TrackTikTok: { isrc: string; countryCode?: string }
  TrackPlaylist: {
    isrc: string
    playlistId: string
    countryCode?: string
  }
  Videos: { mode: VideosScreenModes }
  Video: { videoId: string; countryCode?: string }
  VideoViewsGraph: { videoId: string; countryCode?: string }
  VideoEngagementGraph: { videoId: string; countryCode?: string }
  Search: undefined
  SettingsTab: undefined
  ArtistStreamsGraph: { countryCode?: string; dsp: Dsp | 'all' }
}

export type ReactNavigationProps<T extends ScreenNames> = {
  route: RouteProp<NavigationParamList, T>
  navigation: NavigationProp<T>
}

export type NavigationProp<T extends ScreenNames> = StackNavigationProp<
  NavigationParamList,
  T
>
