import React, { useState, useContext, useEffect } from "react";
import { Image, Modal, PermissionsAndroid, Platform } from "react-native";
import { AtomButtonGhost } from "native/atoms/Buttons/Ghost";
import { AtomButtonDefault } from "native/atoms/Buttons/Default";
import ImagePicker from "react-native-image-picker";
import { AtomIcon } from "native/atoms/Icon";
import {
  PreviewContainer,
  BlankFilePreview,
  ImagePreview,
  FileNameWrapper,
  FileName,
  IconWrapper,
  TextContainer,
  CenteredView,
  ModalView,
  WrapperBtnMenuCamera,
  WrapperBtnMenuGalery,
  WrapperBtnMenuCancel,
  UploadButtonWrapper,
} from "./styles";
import { keysFamily, theme } from "data/dataMx";
import { ThemeContext } from "context/context";
import { IFontWeight } from "interfaces";
import { AtomBody } from "native/atoms/Typography/Body";
import { ITypographyProps } from "native/atoms/Typography/TypographyProps";

export interface IPreviewFileProps {
  /** Placeholder text */
  placeholder: string;
  /** Placeholder props Typography */
  placeholderProps: Omit<ITypographyProps, "text">;
  /** Show Upload Icon or dashed border */
  uploadIcon?: boolean;
  /** Accepted format text */
  acceptedFormatText: string;
  /** Set from parent if the file selected should be deleted (In case of error of success action) */
  deleteFile?: boolean;
  /** Action called after change the input value directly */
  onChange?: (file: Object) => void;
  /** Action called after remove the file from input */
  onRemove?: () => void;
  /** Action called if error on selected file */
  onError?: (errorMessage: string) => void;
  /** Font family file name */
  fontFamilyFileName?: keysFamily;
}

export const MoleculePreviewFile = ({
  placeholder,
  placeholderProps: {
    size = "medium",
    align = "center",
    color = "neutral500",
    weight = "regular",
  },
  uploadIcon = false,
  acceptedFormatText,
  deleteFile = false,
  onChange = () => {},
  onRemove = () => {},
  onError = () => {},
  fontFamilyFileName = "regular",
}: IPreviewFileProps) => {
  const [selectedFile, setSelectedFile] = useState<any | undefined>();
  const [hasError, setHasError] = useState<boolean>(false);
  const [errorMessage, setErrorMessage] = useState<string | undefined>();

  const { fontFamily } = useContext(ThemeContext);
  const font: string = fontFamily.main[fontFamilyFileName as keyof IFontWeight];
  const fontWeight: number =
    fontFamily.weight[font as keyof typeof fontFamily.weight];

  const [modalVisible, setModalVisible] = useState<boolean>(false);

  useEffect(() => {
    if (deleteFile) {
      removeFile();
    }
  }, [deleteFile]);

  const trucatedFileName = (name: string) => {
    return name.replace(/(.{10})..+/, "$1…");
  };

  const removeFile = () => {
    setSelectedFile(undefined);
    onRemove();
  };

  const handleImageSelected = (result: ImagePicker.ImagePickerResponse) => {
    if (result.didCancel) {
      // User cancelled image picker
    } else if (result.errorCode || result.errorMessage) {
      setErrorMessage(result?.errorMessage || "Error Selecting file");
      setHasError(true);
    } else {
      const file = result.assets?.length ? result.assets[0] : null;

      if (file) {
        setSelectedFile(file);
        onChange(file);
      }
    }

    setModalVisible(false);
  };

  const handleOpenCamera = async () => {
    setErrorMessage("");
    setHasError(false);

    const requestPermission = Platform.OS === "android";
    let hasPermission = true;

    if (requestPermission) {
      const grantedcamera = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.CAMERA,
        {
          title: "App Camera Permission",
          message: "App needs access to your camera ",
          buttonNeutral: "Ask Me Later",
          buttonNegative: "Cancel",
          buttonPositive: "OK",
        }
      );

      const grantedstorage = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: "App Storage Permission",
          message: "App needs access to your storage ",
          buttonNeutral: "Ask Me Later",
          buttonNegative: "Cancel",
          buttonPositive: "OK",
        }
      );

      hasPermission =
        grantedcamera === PermissionsAndroid.RESULTS.GRANTED &&
        grantedstorage === PermissionsAndroid.RESULTS.GRANTED;
    }

    if (hasPermission) {
      ImagePicker.launchCamera({
        mediaType: "photo",
        saveToPhotos: true,
        includeBase64: true,
      })
        .then((result) => {
          handleImageSelected(result);
        })
        .catch((err) => {
          setErrorMessage("Error : " + err);
          setHasError(true);
        });
    }
  };

  const handleOpenGallery = async () => {
    setErrorMessage("");
    setHasError(false);

    ImagePicker.launchImageLibrary({
      mediaType: "photo",
      selectionLimit: 1,
      includeBase64: true,
    })
      .then((result) => {
        handleImageSelected(result);
      })
      .catch((err) => {
        setErrorMessage("Error : " + err);
        setHasError(true);
      });
  };

  return (
    <>
      <PreviewContainer>
        {!selectedFile && (
          <>
            <FileNameWrapper>
              <AtomBody
                weight={weight}
                size={size}
                align={align}
                color={color}
                text={placeholder}
              />
            </FileNameWrapper>

            <FileNameWrapper>
              <AtomBody
                text={acceptedFormatText}
                size="small"
                color={"neutral500"}
                weight="regular"
              />
            </FileNameWrapper>
          </>
        )}

        {selectedFile ? (
          <ImagePreview onPress={() => setModalVisible(true)}>
            <Image
              source={{ uri: selectedFile.uri }}
              style={{ width: 98, height: 94 }}
            />
          </ImagePreview>
        ) : uploadIcon ? (
          <UploadButtonWrapper>
            <AtomButtonDefault
              disabled={false}
              color="primary"
              text="Start Uploading"
              size="medium"
              width="100%"
              onPress={() => setModalVisible(true)}
              testID="open-files"
            />
          </UploadButtonWrapper>
        ) : (
          <BlankFilePreview onPress={() => setModalVisible(true)} />
        )}
      </PreviewContainer>

      {selectedFile && selectedFile?.fileName && (
        <FileNameWrapper>
          <FileName
            fontWeight={fontWeight}
            font={font}
            color={theme.neutral500}
          >
            {trucatedFileName(selectedFile.fileName)}
          </FileName>

          <IconWrapper onPress={removeFile} testID="remove-file">
            <AtomIcon name="delete" size={18} color={"neutral500"} />
          </IconWrapper>
        </FileNameWrapper>
      )}

      {hasError && errorMessage ? (
        <FileNameWrapper>
          <FileName font={font} color={theme.secondary400}>
            *{errorMessage}
          </FileName>
        </FileNameWrapper>
      ) : null}

      {!selectedFile && (
        <Modal
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={() => {
            setModalVisible(!modalVisible);
          }}
        >
          <CenteredView>
            <ModalView color={theme.neutral700}>
              <WrapperBtnMenuCamera
                color={theme.neutral100}
                borderColor={theme.neutral300}
              >
                <TextContainer
                  color={theme.neutral700}
                  onPress={handleOpenCamera}
                >
                  Camera
                </TextContainer>
              </WrapperBtnMenuCamera>
              <WrapperBtnMenuGalery
                color={theme.neutral100}
                borderColor={theme.neutral300}
              >
                <TextContainer
                  color={theme.neutral700}
                  onPress={handleOpenGallery}
                >
                  Gallery
                </TextContainer>
              </WrapperBtnMenuGalery>
              <WrapperBtnMenuCancel color={theme.neutral100}>
                <AtomButtonGhost
                  disabled={false}
                  text="Dismiss"
                  color="custom"
                  size="medium"
                  onPress={() => setModalVisible(!modalVisible)}
                />
              </WrapperBtnMenuCancel>
            </ModalView>
          </CenteredView>
        </Modal>
      )}
    </>
  );
};
