import React, { useEffect, useState } from 'react';
import {
  AppBar,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TablePagination,
  TableRow,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import IconButton from '@material-ui/core/IconButton';
import Paper from '@material-ui/core/Paper';
import Toolbar from '@material-ui/core/Toolbar';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import {
  Delete,
  Description,
  FolderOpen,
  KeyboardArrowLeft,
  Lock,
  LockOpen,
} from '@material-ui/icons';
import * as Acsys from '../utils/Acsys/Acsys';
import LoadingDialog from '../components/Dialogs/LoadingDialog';
import MessageDialog from '../components/Dialogs/MessageDialog';
import ImageDialog from '../components/Dialogs/ImageDialog';
import YesNoDialog from '../components/Dialogs/YesNoDialog';
import NewFolderDialog from '../components/Dialogs/NewFolderDialog';

const Storage = (props) => {
  const [locked, setLocked] = useState(true);
  const [isDialog, setIsDialog] = useState(false);
  const [mode, setMode] = useState('');
  const [imgUrl, setImgUrl] = useState(undefined);
  const [con, setCon] = useState(true);
  const [fileName, setFileName] = useState('');
  const [currentDir, setCurrentDir] = useState('');
  const [newFolderName, setNewFolderName] = useState('');
  const [files, setFiles] = useState([]);
  const [uploadFile, setUploadFile] = useState('');
  const [page, setPage] = useState(0);
  const [rowsPerPage] = useState(15);
  const [openMessage, setOpenMessage] = useState(false);
  const [loading, setLoading] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [newFolder, setNewFolder] = useState(false);
  const [isOpenImage, setIsOpenImage] = useState(false);
  const [messageTitle, setMessageTitle] = useState('');
  const [message, setMessage] = useState('');
  const [setError] = useState('');
  const [deleteLoading, setDeleteLoading] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [previousDir, setPreviousDir] = useState('');

  const set = (name, ref) => {
    try {
      props.setFile(name, ref);
    } catch (error) {}
  };

  const closeMessage = () => {
    setOpenMessage(false);
  };

  const openDir = async (dir) => {
    setLoading(true);
    const parentDir = files[0].parent;
    const filesTemp = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', dir],
    ]);
    for (var i = 0; i < filesTemp.length; i++) {
      await Acsys.getStorageURL(filesTemp[i].acsys_id)
        .then((result) => {
          filesTemp[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    filesTemp.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setLoading(false);
    setPreviousDir(parentDir);
    setCurrentDir('/' + dir);
    setFiles(filesTemp);
  };

  const openDirPage = async (dir) => {
    props.history.push('/Storage?' + dir);
    setLocked(false);
  };

  const previousDirFunc = async () => {
    setLoading(true);
    let parentFile = '/';
    let currentDir;
    let files;
    if (previousDir !== '/') {
      const parent = await Acsys.getData(
        'acsys_storage_items',
        [['acsys_id', '=', previousDir]],
        1
      );
      parentFile = parent[0].parent;
      currentDir = '/' + previousDir;
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', previousDir],
      ]);
    } else {
      currentDir = previousDir;
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', '/'],
      ]);
    }
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));

    setLoading(false);
    setPreviousDir(parentFile);
    setCurrentDir(currentDir);
    setFiles(files);
  };

  const setRef = (ref) => {
    setUploadFile(ref);
  };

  const uploadFileFunc = async () => {
    try {
      setLoading(true);
      await Acsys.uploadFile(uploadFile.files[0], currentDir).then(async () => {
        await loadFiles();
      });
      setLoading(false);
    } catch (error) {}
  };

  const syncFiles = async () => {
    handleSyncClose();
    setLoading(true);
    await Acsys.syncFiles();
    let files = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', '/'],
    ]);
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setLoading(false);
    setFiles(files);
  };

  const handleSyncOpen = () => {
    setSyncing(true);
  };

  const handleSyncClose = () => {
    setSyncing(false);
  };

  const openImg = (url) => {
    setIsOpenImage(true);
    setImgUrl(url);
  };

  const handleImgClose = () => {
    setIsOpenImage(false);
  };

  const handleChange = (event) => {
    setNewFolderName(event);
  };

  const newFolderOpen = () => {
    setNewFolder(true);
  };

  const newFolderClose = () => {
    setNewFolder(false);
  };

  const createNewFolder = async () => {
    if (newFolderName.indexOf(' ') >= 0) {
      setNewFolder(false);
      setOpenMessage(true);
      setMessageTitle('Error');
      setMessage('Folder name cannot contain spaces.');
    } else {
      setLoading(true);
      setNewFolder(false);
      await Acsys.createNewFolder(newFolderName, currentDir);
      await loadFiles();
      setLoading(false);
    }
  };

  const makeFilePublic = async (fileName) => {
    setLoading(true);
    await Acsys.makeFilePublic(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    setLoading(false);
  };

  const makeFilePrivate = async (fileName) => {
    setLoading(true);
    await Acsys.makeFilePrivate(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    setLoading(false);
  };

  const deleteFile = async () => {
    setDeleteLoading(true);
    await Acsys.deleteFile(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    handleDeleteClose();
  };

  const handleDeleteOpen = async (fileName) => {
    setDeleting(true);
    setFileName(fileName);
  };

  const handleDeleteClose = () => {
    setDeleting(false);
    setDeleteLoading(false);
  };

  const loadFiles = async () => {
    setTimeout(() => {}, 1000);
    let dir = currentDir;
    if (dir !== '/') {
      dir = dir.substring(1, dir.length);
    }
    const files = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', dir],
    ]);
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setFiles(files);
  };

  const handleChangePage = (event, page) => {
    setPage(page);
  };

  useEffect(async () => {
    try {
      if (
        props.location.search.substring(1) !== currentDir.substring(1) &&
        !locked
      ) {
        let newDir = props.location.search.substring(1);
        if (newDir.length < 1) {
          newDir = '/';
        }
        setLocked(true);
        setLoading(true);
        setIsOpenImage(false);
        const files = await Acsys.getData('acsys_storage_items', [
          ['parent', '=', newDir],
        ]).catch();
        for (var i = 0; i < files.length; i++) {
          await Acsys.getStorageURL(files[i].acsys_id)
            .then((result) => {
              files[i]['url'] = result;
            })
            .catch((error) => console.log(error));
        }
        files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
        let currentDir = '/';
        if (newDir !== '/') {
          currentDir += newDir;
        }
        setLocked(false);
        setLoading(false);
        setCurrentDir(currentDir);
        setFiles(files);
      }
    } catch (error) {}
  }, [locked, currentDir, props.location]);

  useEffect(async () => {
    setLoading(true);
    let parent = '/';
    let mode = 'standard';

    try {
      if (props.mode.length > 0) {
        mode = props.mode;
      }
    } catch (error) {
      props.setHeader('Storage');
    }
    let con;
    let files;
    try {
      con = await Acsys.isStorageConnected();
      if (!con) {
        setLoading(false);
        setCon(con);
      }
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', parent],
      ]);
      for (var i = 0; i < files.length; i++) {
        await Acsys.getStorageURL(files[i].acsys_id)
          .then((result) => {
            files[i]['url'] = result;
          })
          .catch((error) => console.log(error));
      }
      files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    } catch (error) {}
    setLoading(false);
    setIsDialog(isDialog);
    setMode(mode);
    setCon(con);
    setFiles(files);
  }, []);

  const getPrevButton = () => {
    return mode !== 'standard' ? (
      <Grid item>
        <Tooltip title="Back">
          <IconButton onClick={() => previousDirFunc()}>
            <KeyboardArrowLeft color="inherit" />
          </IconButton>
        </Tooltip>
      </Grid>
    ) : (
      <div></div>
    );
  };
  const renderIcon = (content_type, url) => {
    if (content_type === 'Folder') {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <FolderOpen />
        </TableCell>
      );
    } else if (content_type.includes('image')) {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <img
            src={url}
            style={{ cursor: 'pointer', height: 40, width: 40, margin: 0 }}
            onClick={() => openImg(url)}
          />
        </TableCell>
      );
    } else {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <Description
            style={{ cursor: 'pointer', height: 40, width: 40, margin: 0 }}
            onClick={() => window.open(url, '_blank')}
          />
        </TableCell>
      );
    }
  };
  const renderName = (id, content_type, name) => {
    if (content_type === 'Folder') {
      if (mode === 'standard') {
        return (
          <TableCell>
            <a onClick={() => openDirPage(id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      } else {
        return (
          <TableCell>
            <a onClick={() => openDir(id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      }
    } else {
      if (mode === 'standard') {
        return (
          <TableCell>
            <a>{name}</a>
          </TableCell>
        );
      } else {
        return (
          <TableCell>
            <a onClick={() => set(name, id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      }
    }
  };
  const renderTableData = () => {
    return files
      .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
      .map((file, index) => {
        const { acsys_id, name, content_type, updated, is_public, url } = file;
        if (name.length > 0) {
          return (
            <TableRow key={index}>
              {renderIcon(content_type, url, name)}
              {renderName(acsys_id, content_type, name)}
              <TableCell>{content_type}</TableCell>
              <TableCell>{updated}</TableCell>
              {Acsys.getMode() !== 'Viewer' ? (
                <TableCell style={{ minWidth: 100 }} align="right">
                  {is_public ? (
                    <Tooltip title="Public To Internet">
                      <IconButton
                        edge="start"
                        color="inherit"
                        aria-label="make private"
                        onClick={() => makeFilePrivate(acsys_id)}
                        style={{ marginRight: 10 }}
                      >
                        <LockOpen />
                      </IconButton>
                    </Tooltip>
                  ) : (
                    <Tooltip title="Not Public">
                      <IconButton
                        edge="start"
                        color="inherit"
                        aria-label="make public"
                        onClick={() => makeFilePublic(acsys_id)}
                        style={{ marginRight: 10 }}
                      >
                        <Lock />
                      </IconButton>
                    </Tooltip>
                  )}
                  <Tooltip title="Delete File">
                    <IconButton
                      edge="start"
                      color="inherit"
                      aria-label="delete"
                      onClick={() => handleDeleteOpen(acsys_id)}
                    >
                      <Delete />
                    </IconButton>
                  </Tooltip>
                </TableCell>
              ) : (
                <div />
              )}
            </TableRow>
          );
        } else {
          return <div />;
        }
      });
  };

  if (con) {
    try {
      return (
        <div>
          <Paper style={{ margin: 'auto', overflow: 'hidden', clear: 'both' }}>
            <AppBar
              position="static"
              elevation={0}
              style={{
                backgroundColor: '#fafafa',
                borderBottom: '1px solid #dcdcdc',
              }}
            >
              <Toolbar style={{ margin: 4, paddingLeft: 12, paddingRight: 12 }}>
                {Acsys.getMode() !== 'Viewer' ? (
                  <Grid container spacing={1}>
                    <Grid item xs style={{ overflow: 'hidden' }}>
                      <Typography
                        align="left"
                        variant="subtitle2"
                        noWrap
                        style={{ marginTop: 10, color: '#000000' }}
                      >
                        {currentDir}
                      </Typography>
                    </Grid>
                    {getPrevButton()}
                    <Grid item style={{ minWidth: 20 }}>
                      <Tooltip title="Scan For File Updates">
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={handleSyncOpen}
                        >
                          Scan
                        </Button>
                      </Tooltip>
                    </Grid>
                    <Grid item style={{ minWidth: 20 }}>
                      <input
                        id="contained-button-file"
                        type="file"
                        style={{ display: 'none' }}
                        ref={setRef}
                        onChange={uploadFileFunc}
                      />
                      <label htmlFor="contained-button-file">
                        <Tooltip title="Upload File">
                          <Button
                            variant="contained"
                            color="primary"
                            component="span"
                          >
                            Upload
                          </Button>
                        </Tooltip>
                      </label>
                    </Grid>
                    <Grid item style={{ minWidth: 20 }}>
                      <Tooltip title="New Folder">
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={newFolderOpen}
                        >
                          New Folder
                        </Button>
                      </Tooltip>
                    </Grid>
                  </Grid>
                ) : (
                  <Grid container spacing={1}>
                    <Grid item xs style={{ overflow: 'hidden' }}>
                      <Typography
                        align="left"
                        variant="subtitle2"
                        noWrap
                        style={{ marginTop: 10, color: '#000000' }}
                      >
                        {currentDir}
                      </Typography>
                    </Grid>
                    {getPrevButton()}
                  </Grid>
                )}
              </Toolbar>
            </AppBar>
            <div style={{ margin: 'auto', overflow: 'auto' }}>
              <Table>
                <TableHead style={{ backgroundColor: '#fafafa' }}>
                  <TableRow>
                    <TableCell
                      colSpan={2}
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                      }}
                    >
                      NAME
                    </TableCell>
                    <TableCell
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                        width: 100,
                      }}
                    >
                      TYPE
                    </TableCell>
                    <TableCell
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                        width: 110,
                      }}
                    >
                      LAST MODIFIED
                    </TableCell>
                    {Acsys.getMode() !== 'Viewer' ? (
                      <TableCell
                        style={{
                          paddingLeft: 16,
                          paddingRight: 16,
                          paddingTop: 5,
                          paddingBottom: 5,
                          width: 100,
                        }}
                        align="right"
                      >
                        ACTIONS
                      </TableCell>
                    ) : (
                      <div />
                    )}
                  </TableRow>
                </TableHead>
                <TableBody>{renderTableData()}</TableBody>
              </Table>
            </div>
            <TablePagination
              rowsPerPageOptions={[25]}
              component="div"
              count={files.length}
              rowsPerPage={rowsPerPage}
              page={page}
              backIconButtonProps={{
                'aria-label': 'previous page',
              }}
              nextIconButtonProps={{
                'aria-label': 'next page',
              }}
              onChangePage={handleChangePage}
              // onChangeRowsPerPage={handleChangeRowsPerPage}
            />
            <LoadingDialog loading={loading} message={'Loading'} />
            <MessageDialog
              open={openMessage}
              closeDialog={closeMessage}
              title={messageTitle}
              message={message}
            />
            <YesNoDialog
              open={syncing}
              closeDialog={handleSyncClose}
              title={'Sync files?'}
              message={
                'Are you sure you want to resync files? This operation can require multiple writes.'
              }
              action={syncFiles}
            />
            <ImageDialog
              open={isOpenImage}
              closeDialog={handleImgClose}
              imgUrl={imgUrl}
            />
            <NewFolderDialog
              open={newFolder}
              closeDialog={newFolderClose}
              handleChange={handleChange}
              createNewFolder={createNewFolder}
            />
            <YesNoDialog
              open={deleting}
              closeDialog={handleDeleteClose}
              title={'Delete file?'}
              message={'Are you sure you want to delete this file?'}
              action={deleteFile}
              actionProcess={deleteLoading}
            />
          </Paper>
        </div>
      );
    } catch (error) {
      console.log('error', error);
      return (
        <div style={{ maxWidth: 1236, margin: 'auto' }}>
          <Paper style={{ height: 40 }}>
            <div style={{ padding: 10, margin: 'auto' }}>
              Please make sure database has been created.
            </div>
          </Paper>
        </div>
      );
    }
  } else {
    return (
      <div style={{ maxWidth: 1236, margin: 'auto' }}>
        <Paper style={{ height: 40 }}>
          <div style={{ padding: 10, margin: 'auto' }}>
            Please configure storage.
          </div>
        </Paper>
      </div>
    );
  }
};
export default Storage;