import React, { useState } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import {
  Button,
  List,
  Portal,
  SegmentedButtons,
  Switch,
  Text,
  useTheme,
} from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import type {} from 'redux-thunk/extend-redux';
import { useRealm } from '@realm/react';
import { FileSystem, FileStat } from 'react-native-file-access';
import {
  RootState,
  setAutofocusMemesSearch,
  setAutofocusTagsSearch,
  setGridColumns,
  setMasonryColumns,
  setNoMedia,
  setSnackbarMessage,
} from '../../state';
import { Meme } from '../../database';
import StorageLocationChangeDialog from './storageLocationChangeDialog';

const settingsStyles = StyleSheet.create({
  scrollView: {
    paddingHorizontal: '4%',
  },
  marginBottom: {
    marginBottom: 15,
  },
  columnSegmentedButtons: {
    marginBottom: 15,
    paddingHorizontal: '2%',
  },
  autoFocusSwitch: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: '2%',
    marginBottom: 15,
  },
  hideMediaSwitch: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: '2%',
  },
});

const Settings = () => {
  const { colors } = useTheme();
  const noMedia = useSelector((state: RootState) => state.settings.noMedia);
  const autoFocusMemesSearch = useSelector(
    (state: RootState) => state.settings.autoFocusMemesSearch,
  );
  const autoFocusTagsSearch = useSelector(
    (state: RootState) => state.settings.autoFocusTagsSearch,
  );
  const masonryColumns = useSelector(
    (state: RootState) => state.settings.masonryColumns,
  );
  const gridColumns = useSelector(
    (state: RootState) => state.settings.gridColumns,
  );
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  const storageUri = useSelector(
    (state: RootState) => state.settings.storageUri,
  )!;
  const dispatch = useDispatch();
  const realm = useRealm();

  const [
    storageLocationChangeDialogVisible,
    setStorageLocationChangeDialogVisible,
  ] = useState(false);

  const refreshMemeMetadata = async () => {
    const stat = await FileSystem.statDir(storageUri);

    const statMap = new Map<string, FileStat>();
    stat.forEach(s => statMap.set(s.filename, s));

    const memes = realm.objects<Meme>(Meme.schema.name);

    realm.write(() => {
      memes.forEach(meme => {
        const fileStat = statMap.get(meme.filename);
        meme.size = fileStat?.size ?? 0;
      });
    });

    dispatch(setSnackbarMessage('Meme metadata refreshed.'));
  };

  return (
    <>
      <ScrollView
        contentContainerStyle={[
          settingsStyles.scrollView,
          { backgroundColor: colors.background },
        ]}>
        <List.Section>
          <List.Subheader>Views</List.Subheader>
          <View style={settingsStyles.autoFocusSwitch}>
            <Text>Autofocus Memes Searchbar</Text>
            <Switch
              value={autoFocusMemesSearch}
              onValueChange={value => {
                void dispatch(setAutofocusMemesSearch(value));
              }}
            />
          </View>
          <View style={settingsStyles.autoFocusSwitch}>
            <Text>Autofocus Tags Searchbar</Text>
            <Switch
              value={autoFocusTagsSearch}
              onValueChange={value => {
                void dispatch(setAutofocusTagsSearch(value));
              }}
            />
          </View>
          <Text style={settingsStyles.columnSegmentedButtons}>
            Masonry Columns
          </Text>
          <SegmentedButtons
            value={masonryColumns.toString()}
            onValueChange={value => {
              void dispatch(
                setMasonryColumns(Number.parseInt(value) as 1 | 2 | 3 | 4),
              );
            }}
            buttons={[
              { label: '1', value: '1' },
              { label: '2', value: '2' },
              { label: '3', value: '3' },
              { label: '4', value: '4' },
            ]}
            style={settingsStyles.marginBottom}
          />
          <Text style={settingsStyles.columnSegmentedButtons}>
            Grid Columns
          </Text>
          <SegmentedButtons
            value={gridColumns.toString()}
            onValueChange={value => {
              void dispatch(
                setGridColumns(Number.parseInt(value) as 1 | 2 | 3 | 4),
              );
            }}
            buttons={[
              { label: '1', value: '1' },
              { label: '2', value: '2' },
              { label: '3', value: '3' },
              { label: '4', value: '4' },
            ]}
          />
        </List.Section>
        <List.Section>
          <List.Subheader>Storage</List.Subheader>
          <Button
            mode="elevated"
            style={settingsStyles.marginBottom}
            onPress={() => setStorageLocationChangeDialogVisible(true)}>
            Change Storage Location
          </Button>
          <Button
            mode="elevated"
            style={settingsStyles.marginBottom}
            onPress={refreshMemeMetadata}>
            Refresh Meme Metadata
          </Button>
          <View style={settingsStyles.hideMediaSwitch}>
            <Text>Hide media from gallery</Text>
            <Switch
              value={noMedia}
              onValueChange={value => {
                void dispatch(setNoMedia(value));
              }}
            />
          </View>
        </List.Section>
      </ScrollView>
      <Portal>
        <StorageLocationChangeDialog
          visible={storageLocationChangeDialogVisible}
          setVisible={setStorageLocationChangeDialogVisible}
          setSnackbarMessage={message => {
            dispatch(setSnackbarMessage(message));
          }}
        />
      </Portal>
    </>
  );
};

export default Settings;
