import React, { useState } from 'react';
import { useNavigation } from '@react-navigation/native';
import YCImage from './YCImage';
import Button from './Button';

import
{
  StyleSheet,
  View,
  Text,
  TextInput,
  FlatList,
  ActivityIndicator,
  TouchableOpacity,
} from 'react-native';

import
{
  Connect,
  CancellationTicket,
  type StreamingCategory,
  type StreamingContent,
  type StreamingService,
} from 'react-native-younify-connect-sdk';

interface YounifyCategoriesProps
{
  onServiceChanged: (service: StreamingService) => void | undefined
  onSearchRequest: (services: StreamingService[], searchTerm: String) => void | undefined
  onBrowseRequest: (content: StreamingContent) => void | undefined
}

const YounifyCategories = React.forwardRef((props: YounifyCategoriesProps, ref) =>
{
  const connect = Connect.shared;
  const navigation = useNavigation();

  interface ServiceContent
  {
    service: StreamingService;
    content: StreamingContent[];
  }

  interface CategoryContent
  {
    category: StreamingCategory;
    services: ServiceContent[];
    isLoading: boolean;
  }

  const [selectedServicesState, setSelectedServicesState] = useState<StreamingService[]>([]);
  const [categoriesState, setCategoriesState] = useState<CategoryContent[]>([]);
  const [cancellationState, setCancellationState] = useState<CancellationTicket>();
  const [searchTextState, setSearchTextState] = useState('game');

  const loadCategories = (categories: StreamingCategory[]) =>
  {
    let categoriesResult: CategoryContent[] = [];
    categories.forEach(function (category)
    {
      categoriesResult.push({ category: category, services: [], isLoading: true });
    });

    setCategoriesState(categoriesResult);
  };

  const updateCategoryContent = (category: StreamingCategory, service: StreamingService, content: StreamingContent[]) =>
  {
    const newService = { service: service, content: content };
    setCategoriesState((prev) => prev.map(el => el.category.equals(category) ? { ...el, isLoading: false, services: [...el.services.filter(function(s) { return s.service.name !== service.name }), newService ] } : el));
  };

  const fetchCategories = async () =>
  {
    setCategoriesState([]);

    try
    {
      let categories = await connect.fetchCategories(null);
      loadCategories(categories);

      return categories;
    }
    catch (e: any)
    {
      console.log("fetch categories failed: " + e);
    }

    return [];
  };

  React.useImperativeHandle(ref, () => ({
    async fetchContent(services: StreamingService[])
    {
      try
      {
        setSelectedServicesState(services);

        let cancellationTicket = new CancellationTicket();
        setCancellationState(cancellationTicket);

        let categories = await fetchCategories();

        await connect.fetchContent(
          categories,
          services,
          cancellationTicket,
          (service, error) =>
          {
            console.log('service error: ' + service.name + ' - ' + (error ? error.message : 'none'));
            props.onServiceChanged(service);
          },
          (category, service, content, error) =>
          {
            console.log('category service content: ' + category.name + ', ' + service.name + ', content count: ' + content.length + ', error: ' + (error ? error.message : 'none'));
            updateCategoryContent(category, service, content);
          });

        setCategoriesState((prev) => prev.map(c => { return { ...c, isLoading: false }}));
        services.forEach(function (service)
        {
          props.onServiceChanged(service);
        });
      }
      catch (e: any)
      {
        console.log("fetch content failed: " + e);
      }
    }
  }));

  return(
    <View style={ styles.categoriesView }>
      <View style={ styles.searchView }>
        <Button title=" < Back " onPress={ async () =>
          {
            if (cancellationState)
              cancellationState.cancel();

            navigation.goBack();
          }} />
        <TextInput
          style={ styles.searchInput }
          placeholder="Search term"
          onChangeText={ newText => setSearchTextState(newText) }
          defaultValue={ searchTextState }/>
        <Button title="Search" onPress={ () =>
        {
          props.onSearchRequest(selectedServicesState, searchTextState);
        }} />
      </View>
      <FlatList
        style={ styles.categoriesList }
        data={ categoriesState }
        renderItem=
        {
          (categoryResult) =>
            (
              <View style={ [ styles.categoryView ] }>
                <Text>{ categoryResult.item.category.name }</Text>
                <ActivityIndicator animating={ categoryResult.item.isLoading } />
                { /* Services */ }
                <FlatList
                  horizontal={ true }
                  data={ categoryResult.item.services }
                  showsHorizontalScrollIndicator={ true }
                  style={ styles.horizontalItemsList }
                  renderItem=
                  {
                    (categoryServiceResult) =>
                      (
                        /* Content items */
                        <FlatList
                          horizontal
                          showsHorizontalScrollIndicator={ true }
                          data={ categoryServiceResult.item.content }
                          style={ styles.horizontalItemsList }
                          renderItem=
                          {
                            (categoryServiceContentItem) =>
                              (
                                <TouchableOpacity onPress={ ()=>
                                {
                                  props.onBrowseRequest(categoryServiceContentItem.item);
                                } }>
                                  <View style={ [ styles.categoryItemsView ] }>
                                    <YCImage
                                      name="contentSmallThumbImage"
                                      connect={ connect }
                                      url={ categoryServiceContentItem.item.smallThumbnailUrl!! }
                                      style={ styles.contentItemImage } />
                                    <YCImage
                                      name="serviceOverlayThumbImage"
                                      connect={ connect }
                                      url={ categoryServiceResult.item.service.overlayThumbnailUrl!! }
                                      style={ styles.contentItemChannelImage } />
                                    <Text style={ styles.contentItemText } numberOfLines={1}>{ categoryServiceContentItem.item.title }</Text>
                                  </View>
                                </TouchableOpacity>
                              )
                          }
                          ItemSeparatorComponent={ () => <View style={ styles.categoriesListSeparator } /> } />
                      )
                  }
                  ItemSeparatorComponent={ () => <View style={ styles.categoriesListSeparator } /> } />
              </View>
            )
        }
        ItemSeparatorComponent={ () => <View style={ styles.categoriesListSeparator } /> } />
    </View>
  )
});

const styles = StyleSheet.create
(
  {
    searchInput:
    {
      padding: 6,
      borderWidth: 1,
      flex: 1
    },
    searchView:
    {
      flexDirection: 'row',
      width: '100%',
      height: 30,
      alignItems: 'stretch',
      gap: 6,
      marginBottom: 20
    },
    categoriesList:
    {
      flex : 1
    },
    categoryView:
    {
      gap: 3
    },
    categoryItemsView:
    {
      gap: 3
    },
    categoriesListSeparator:
    {
      height: 5
    },
    contentItemImage:
    {
      width: 149,
      height: 84
    },
    contentItemText:
    {
      maxWidth: 149,
    },
    contentItemChannelImage:
    {
      width: 36,
      height: 20,
      position: 'absolute',
      top: 65,
      left: 113
    },
    horizontalItemsList:
    {
      height: 114,
      flexDirection: 'row',
      gap: 3
    },
    categoriesView:
    {
      paddingTop: 20,
      paddingLeft: 10,
      paddingRight: 10,
      flex: 1,
    }
  }
);

export default YounifyCategories;