import React, {useMemo, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  IconCamera,
  IconFile,
  IconPhoto,
  IconUpload,
  IconVideo,
} from '@tabler/icons-react-native';
import {ImageOrVideo} from 'react-native-image-crop-picker';
import {Typography} from '@components/_core/Typography';
import {Button} from '@components/_HuGo/Button';
import {Dialog} from '@components/_HuGo/Dialog';
import {HuGoFile} from '@components/_HuGo/interfaces';
import {ListItem} from '@components/_HuGo/List';
import {useTheme} from '@shared/theme';
import {openCamera, openGallery} from '@shared/utils';

import {
  DEFAULT_INPUTS,
  DEFAULT_VALID_TYPES,
  UploaderInputs,
  UploaderValidTypes,
} from './interfaces';
import {styles} from './styles';
import {
  formatAssetToFile,
  formatValidTypes,
  getUploaderInputFlags,
  hasImageType,
  isDocumentsOnly,
  pickFiles,
} from './utils';
import {PressableAvatar} from '../PressableAvatar';

export type LayoutProps = {
  buttonTitle?: string;
  description?: string;
  multiFiles?: boolean;
  onPickFiles: (files: HuGoFile[]) => void;
  title?: string;
  validTypes?: UploaderValidTypes[];
  layoutVariant?: 'row' | 'column';
  inputs?: UploaderInputs[];
};

interface Props extends LayoutProps {
  isCenter?: boolean;
  showButton: boolean;
  maxAttachments?: number;
}

export function Layout({
  buttonTitle,
  description,
  isCenter,
  multiFiles,
  onPickFiles,
  showButton,
  title,
  validTypes = DEFAULT_VALID_TYPES,
  layoutVariant = 'column',
  inputs = DEFAULT_INPUTS,
  maxAttachments = 5,
}: Props) {
  const {theme} = useTheme();
  const {t} = useTranslation();
  const [focused, setFocused] = useState(false);
  const canPickImages = useMemo(() => hasImageType(validTypes), [validTypes]);
  const isColumnLayout = layoutVariant === 'column';
  const {camera, documents, gallery, video} = useMemo(
    () => getUploaderInputFlags(inputs),
    [inputs],
  );
  const documentsOnly = useMemo(() => isDocumentsOnly(inputs), [inputs]);

  const onCloseDialog = () => setFocused(false);

  const onPickFromGallery = () => {
    onCloseDialog();
    openGallery({
      saveMultiple: assets => {
        onPickFiles(assets.map(asset => formatAssetToFile(asset)));
      },
      save: (asset: ImageOrVideo) => onPickFiles([formatAssetToFile(asset)]),
      options: {
        mediaType: 'photo',
        multiple: multiFiles,
        maxFiles: maxAttachments,
      },
    });
  };

  const onPickFromFiles = async () => {
    !documentsOnly && onCloseDialog();
    const files = await pickFiles({
      allowMultiSelection: multiFiles,
      type: formatValidTypes(validTypes),
    });
    !!files.length && onPickFiles(files);
  };

  const onPressUpload = () => {
    canPickImages ? setFocused(true) : onPickFromFiles();
  };

  const onPickFromCamera = () => {
    onCloseDialog();
    openCamera({
      save: (asset: ImageOrVideo) => onPickFiles([formatAssetToFile(asset)]),
      options: {forceJpg: true, mediaType: 'photo'},
    });
  };

  const onPickFromVideo = () => {
    onCloseDialog();
    openCamera({
      save: (asset: ImageOrVideo) => onPickFiles([formatAssetToFile(asset)]),
      options: {mediaType: 'video'},
    });
  };

  return (
    <>
      <View style={styles.container}>
        <View>
          {!!title && (
            <Typography align={isCenter ? 'center' : 'left'} weight="semiBold">
              {title}
            </Typography>
          )}
          {!!description && (
            <Typography
              align={isCenter ? 'center' : 'left'}
              color={theme.text.neutral.lighter}
              variant="xs">
              {description}
            </Typography>
          )}
        </View>
        {showButton && (
          <Button
            IconRight={IconUpload}
            onPress={documentsOnly ? onPickFromFiles : onPressUpload}
            size="sm"
            style={isCenter ? styles.buttonCenter : styles.buttonLeft}
            text={buttonTitle || t('general.upload_file')}
            variant="secondary"
          />
        )}
      </View>
      <Dialog
        isVisible={focused}
        onClose={onCloseDialog}
        withCloseButton={isColumnLayout}
        {...(isColumnLayout
          ? {title: t('general.select_source')}
          : {headerStyle: styles.rowHeader})}>
        {isColumnLayout ? (
          <>
            {video && (
              <ListItem
                avatar={{Icon: IconVideo}}
                onItemPress={onPickFromVideo}
                title={t('general.video')}
                style={styles.listItem}
              />
            )}
            {canPickImages && gallery && (
              <ListItem
                avatar={{Icon: IconPhoto}}
                onItemPress={onPickFromGallery}
                title={t('general.gallery')}
                style={styles.listItem}
              />
            )}
            {documents && (
              <ListItem
                avatar={{Icon: IconFile}}
                onItemPress={onPickFromFiles}
                title={t('general.files')}
                style={styles.listItem}
              />
            )}
            {canPickImages && camera && (
              <ListItem
                avatar={{Icon: IconCamera}}
                onItemPress={onPickFromCamera}
                title={t('general.camera')}
                style={styles.listItem}
              />
            )}
          </>
        ) : (
          <View style={styles.rowContainer}>
            {video && (
              <PressableAvatar
                Icon={IconVideo}
                onPress={onPickFromVideo}
                title={t('general.video')}
              />
            )}
            {documents && (
              <PressableAvatar
                Icon={IconFile}
                onPress={onPickFromFiles}
                title={t('general.document')}
              />
            )}
            {canPickImages && (
              <>
                {gallery && (
                  <PressableAvatar
                    Icon={IconPhoto}
                    onPress={onPickFromGallery}
                    title={t('general.image')}
                  />
                )}
                {camera && (
                  <PressableAvatar
                    Icon={IconCamera}
                    onPress={onPickFromCamera}
                    title={t('general.camera')}
                  />
                )}
              </>
            )}
          </View>
        )}
      </Dialog>
    </>
  );
}
