import {
  Box,
  ExpansionPanel,
  ExpansionPanelDetails,
  ExpansionPanelSummary,
  NativeSelect,
  Tooltip,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import { KeyboardArrowDown } from '@material-ui/icons';
import React, { useEffect, useState } from 'react';
import * as Acsys from '../utils/Acsys/Acsys';
import LoadingDialog from '../components/Dialogs/LoadingDialog';
import MessageDialog from '../components/Dialogs/MessageDialog';
import YesNoDialog from '../components/Dialogs/YesNoDialog';

const Settings = (props) => {
  const [host, setHost] = useState('');
  const [port, setPort] = useState('');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [socketPath, setSocketPath] = useState('');
  const [dhost, setDhost] = useState('');
  const [dport, setDport] = useState('');
  const [ddatabase, setDatabase] = useState('');
  const [dusername, setDusername] = useState('');
  const [dpassword, setDpassword] = useState('');
  const [project_name, setProjectName] = useState('');
  const [databaseType, setDatabaseType] = useState('');
  const [type, setType] = useState('');
  const [project_id, setProjectId] = useState('');
  const [private_key_id, setPrivateKeyId] = useState('');
  const [private_key, setPrivateKey] = useState('');
  const [client_email, setClientEmail] = useState('');
  const [client_id, setClientId] = useState('');
  const [auth_uri, setAuthUri] = useState('');
  const [token_uri, setTokenUri] = useState('');
  const [auth_provider_x509_cert_url, setAuthProviderX509CertUrl] =
    useState('');
  const [client_x509_cert_url, setClientX509CertUrl] = useState('');
  const [bucket, setBucket] = useState('');
  const [buckets, setBuckets] = useState([]);
  const [updateBucket, setUpdateBucket] = useState(false);
  const [updateEmail, setUpdateEmail] = useState(false);
  const [updateDatabase, setUpdateDatabase] = useState(false);
  const [updateStorage, setUpdateStorage] = useState(false);
  const [uploadFile, setUploadFile] = useState();
  const [fileName, setFileName] = useState('');
  const [page, setPage] = useState(0);
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [error, setError] = useState('');
  const [message, setMessage] = useState('');
  const [messageOpen, setMessageOpen] = useState(false);
  const [isStateless, setIsStateless] = useState('');

  const handleClickOpen = () => {
    if (updateDatabase || updateStorage || updateEmail || updateBucket) {
      setOpen(true);
    }
  };

  const handleClose = () => {
    setOpen(false);
  };

  const handleMessageClose = () => {
    setMessageOpen(false);
  };

  const closeDialog = () => {
    setLoading(false);
  };

  useEffect(async () => {
    props.setHeader('Settings');
    const isStateless = await Acsys.isStateless();
    const emailConfig = await Acsys.getEmailConfig();
    if (emailConfig.length > 0) {
      setHost(emailConfig[0].host);
      setPort(emailConfig[0].port);
      setUsername(emailConfig[0].username);
      setPassword(emailConfig[0].password);
    }
    const databaseType = await Acsys.getDatabaseType();
    if (!isStateless) {
      const databaseConfig = await Acsys.getDatabaseConfig();
      if (databaseType === 'local') {
        setProjectName(databaseConfig.project_name);
      } else if (databaseType === 'firestore') {
        const currentBucket = await Acsys.getCurrentBucket();
        const buckets = await Acsys.getStorageBuckets();

        setBucket(currentBucket);
        setBuckets(buckets);
        setType(databaseConfig.type);
        setProjectId(databaseConfig.project_id);
        setPrivateKeyId(databaseConfig.private_key_id);
        setPrivateKey(databaseConfig.private_key);
        setClientEmail(databaseConfig.client_email);
        setClientId(databaseConfig.client_id);
        setAuthUri(databaseConfig.auth_uri);
        setTokenUri(databaseConfig.token_uri);
        setAuthProviderX509CertUrl(databaseConfig.auth_provider_x509_cert_url);
        setClientX509CertUrl(databaseConfig.client_x509_cert_url);
      } else if (databaseType === 'mysql') {
        const currentBucket = await Acsys.getCurrentBucket();
        const buckets = await Acsys.getStorageBuckets();
        setBucket(currentBucket);
        setBuckets(buckets);
        setType(databaseConfig.type);
        setProjectId(databaseConfig.project_id);
        setPrivateKeyId(databaseConfig.private_key_id);
        setPrivateKey(databaseConfig.private_key);
        setClientEmail(databaseConfig.client_email);
        setClientId(databaseConfig.client_id);
        setAuthUri(databaseConfig.auth_uri);
        setTokenUri(databaseConfig.token_uri);
        setAuthProviderX509CertUrl(databaseConfig.auth_provider_x509_cert_url);
        setClientX509CertUrl(databaseConfig.client_x509_cert_url);
      }
    }
    setIsStateless(isStateless);
    setDatabaseType(databaseType);
  }, []);

  // setDatabaseType = (type) => {
  //   setState({
  //     databaseType: type,
  //   });
  // };

  const selectBucket = (bucket) => {
    setBucket(bucket);
  };

  const setEmail = async () => {
    const config = {
      host: host,
      port: port,
      username: username,
      password: password,
    };
    await Acsys.setEmailConfig(config);
  };

  const set_bucket = async () => {
    const config = {
      bucket: bucket,
    };
    await Acsys.setStorageBucket(config);
  };

  const handlesetDatabase = async () => {
    if (databaseType === 'firestore') {
      if (uploadFile === undefined) {
        setMessageOpen(true);
        setOpen(false);
        setMessage('Please select a configuration to upload.');
        setLoading(false);
      } else {
        await Acsys.setFirestoreConfig(uploadFile);
      }
    } else if (databaseType === 'mysql') {
      if (
        dhost < 1 ||
        ddatabase < 1 ||
        dusername < 1 ||
        dpassword < 1 ||
        uploadFile === undefined
      ) {
        setMessageOpen(true);
        setOpen(false);
        setMessage(
          'Please complete all necessary database fields and storage setTings.'
        );
        setLoading(false);
      } else {
        await Acsys.setMysqlConfig(
          dhost,
          dport,
          ddatabase,
          dusername,
          dpassword,
          socketPath,
          uploadFile
        );
      }
    } else if (databaseType === 'local') {
      if (project_name.length < 1) {
        setMessageOpen(true);
        setOpen(false);
        setMessage('Please enter a project name.');
        setLoading(false);
      } else {
        await Acsys.setLocalDatabaseConfig(project_name);
      }
    }
  };

  const setConfig = async () => {
    setOpen(false);
    setLoading(false);
    if (updateEmail) {
      setEmail();
      await sleep(5000);
    }
    if (updateBucket) {
      set_bucket();
      await sleep(5000);
    }
    if (updateDatabase || updateStorage) {
      handlesetDatabase();
      await sleep(5000);
    }
    if ((updateDatabase || updateEmail || updateStorage) && loading) {
      await sleep(7500);
      window.location.reload();
    }
    setLoading(false);
  };

  const setRef = (ref) => {
    const fileReader = new FileReader();
    fileReader.onload = (event) => loadFields(event);
    try {
      fileReader.readAsText(ref.target.files[0]);
    } catch (error) {}
    setFileName(ref.target.files[0].name), setUploadFile(ref.target.files[0]);
  };

  const loadFields = (event) => {
    try {
      const setTings = JSON.parse(event.target.result);
      setType(setTings.type);
      setProjectId(ettings.project_id);
      setPrivateKeyId(setTings.private_key_id);
      setPrivateKey(setTings.private_key);
      setClientEmail(setTings.client_email);
      setClientId(setTings.client_id);
      setAuthUri(setTings.auth_uri);
      setTokenUri(setTings.token_uri);
      setAuthProviderX509CertUrl(setTings.auth_provider_x509_cert_url);
      setClientX509CertUrl(setTings.client_x509_cert_url);
    } catch (error) {}
  };

  const sleep = (time) => {
    return new Promise((resolve) => setTimeout(resolve, time));
  };

  const onChange = (event) => {
    // setState({ [event.target.name]: event.target.value });
  };

  const getBucketPanel = () => {
    console.log('buckerts', buckets);
    return (
      <ExpansionPanel
        style={{ clear: 'both' }}
        onChange={(e) => setUpdateBucket(!updateBucket)}
      >
        <ExpansionPanelSummary
          expandIcon={<KeyboardArrowDown />}
          aria-controls="panel1a-content"
          id="panel1a-header"
        >
          <Typography>Bucket Configuration</Typography>
        </ExpansionPanelSummary>
        <ExpansionPanelDetails>
          <Box
            margin="auto"
            width="90%"
            display="flex"
            flexDirection="column"
            textAlign="center"
            padding="16px"
          >
            <NativeSelect
              value={bucket}
              onChange={(e) => setBucket(e.target.value)}
              style={{ width: '100%', paddingTop: 7 }}
            >
              {buckets.map((bucketName) => (
                <option value={bucketName}>{bucketName}</option>
              ))}
            </NativeSelect>
          </Box>
        </ExpansionPanelDetails>
      </ExpansionPanel>
    );
  };

  const getLocalPanel = () => {
    return (
      <ExpansionPanel
        style={{ clear: 'both' }}
        onChange={(e) => setUpdateDatabase(!updateDatabase)}
      >
        <ExpansionPanelSummary
          expandIcon={<KeyboardArrowDown />}
          aria-controls="panel1a-content"
          id="panel1a-header"
        >
          <Typography>Local Configuration</Typography>
        </ExpansionPanelSummary>
        <ExpansionPanelDetails>
          <Box
            margin="auto"
            width="90%"
            display="flex"
            flexDirection="column"
            textAlign="center"
            padding="16px"
          >
            <input
              id="project_name"
              name="project_name"
              placeholder="Project Name"
              value={project_name}
              onChange={(e) => setProjectName(e.target.value)}
              style={{ marginTop: '20px' }}
            />
          </Box>
        </ExpansionPanelDetails>
      </ExpansionPanel>
    );
  };

  const getFirestorePanel = (name) => {
    return (
      <Grid>
        <Grid item xs={12} style={{ marginBottom: 30 }}>
          {bucket.length > 0 ? getBucketPanel() : null}
        </Grid>
        <Grid item xs={12}>
          <ExpansionPanel
            style={{ clear: 'both' }}
            onChange={(e) => setUpdateStorage(!updateStorage)}
          >
            <ExpansionPanelSummary
              expandIcon={<KeyboardArrowDown />}
              aria-controls="panel1a-content"
              id="panel1a-header"
            >
              <Typography>{name} Configuration</Typography>
            </ExpansionPanelSummary>
            <ExpansionPanelDetails>
              <Box
                margin="auto"
                width="90%"
                display="flex"
                flexDirection="column"
                textAlign="center"
                padding="16px"
              >
                <input
                  id="type"
                  name="type"
                  onChange={(e) => setType(e.target.value)}
                  placeholder="Type"
                  value={type}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="project_id"
                  name="project_id"
                  onChange={(e) => setProjectId(e.target.value)}
                  placeholder="Project ID"
                  value={project_id}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="private_key_id"
                  name="private_key_id"
                  onChange={(e) => setPrivateKeyId(e.target.value)}
                  placeholder="Private Key ID"
                  value={private_key_id}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="private_key"
                  name="private_key"
                  onChange={(e) => setPrivateKeyId(e.target.value)}
                  placeholder="Private Key"
                  value={private_key}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="client_email"
                  name="client_email"
                  onChange={(e) => setClientEmail(e.target.value)}
                  placeholder="Client Email"
                  value={client_email}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="client_id"
                  name="client_id"
                  onChange={(e) => setClientId(e.target.value)}
                  placeholder="Client ID"
                  value={client_id}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="auth_uri"
                  name="auth_uri"
                  onChange={(e) => setAuthUri(e.target.value)}
                  placeholder="Auth URI"
                  value={auth_uri}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="token_uri"
                  name="token_uri"
                  onChange={(e) => setTokenUri(e.target.value)}
                  placeholder="Token URI"
                  value={token_uri}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="auth_provider_x509_cert_url"
                  name="auth_provider_x509_cert_url"
                  onChange={(e) => setAuthProviderX509CertUrl(e.target.value)}
                  placeholder="Auth Provider x509 Cert URL"
                  value={auth_provider_x509_cert_url}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="client_x509_cert_url"
                  name="client_x509_cert_url"
                  onChange={(e) => setClientX509CertUrl(e.target.value)}
                  placeholder="Client x509 Cert URL"
                  value={client_x509_cert_url}
                  style={{ marginTop: '20px' }}
                />
                <Grid container style={{ marginTop: '20px' }}>
                  <Grid item xs>
                    <input defaultValue={fileName} style={{ width: '100%' }} />
                  </Grid>
                  <Grid item>
                    <input
                      id="contained-button-file"
                      type="file"
                      style={{ display: 'none' }}
                      onChange={setRef}
                    />
                    <label htmlFor="contained-button-file">
                      <Button
                        variant="contained"
                        color="primary"
                        component="span"
                        style={{ marginLeft: 28, height: 32 }}
                      >
                        New Config
                      </Button>
                    </label>
                  </Grid>
                </Grid>
              </Box>
            </ExpansionPanelDetails>
          </ExpansionPanel>
        </Grid>
      </Grid>
    );
  };

  const getMysqlPanel = () => {
    return (
      <Grid>
        <Grid item xs={12} style={{ marginBottom: 30 }}>
          <ExpansionPanel
            style={{ clear: 'both' }}
            onChange={(e) => setUpdateDatabase(!updateDatabase)}
          >
            <ExpansionPanelSummary
              expandIcon={<KeyboardArrowDown />}
              aria-controls="panel1a-content"
              id="panel1a-header"
            >
              <Typography>MySQL Configuration</Typography>
            </ExpansionPanelSummary>
            <ExpansionPanelDetails>
              <Box
                margin="auto"
                width="90%"
                display="flex"
                flexDirection="column"
                textAlign="center"
                padding="16px"
              >
                <input
                  id="dhost"
                  name="dhost"
                  placeholder="Host"
                  value={dhost}
                  onChange={(e) => setDhost(e.target.value)}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="dport"
                  name="dport"
                  placeholder="Port (Can be empty)"
                  value={dport}
                  onChange={(e) => setDport(e.target.value)}
                  type="number"
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="ddatabase"
                  name="ddatabase"
                  placeholder="Database"
                  value={ddatabase}
                  onChange={(e) => setDatabase(e.target.value)}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="dusername"
                  name="dusername"
                  placeholder="Username"
                  value={dusername}
                  onChange={(e) => setDusername(e.target.value)}
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="dpassword"
                  name="dpassword"
                  placeholder="Password"
                  value={dpassword}
                  onChange={(e) => setDpassword(e.target.value)}
                  type="password"
                  style={{ marginTop: '20px' }}
                />
                <input
                  id="socketPath"
                  name="socketPath"
                  placeholder="Socket Path (May be needed for production environments)"
                  value={socketPath}
                  onChange={(e) => setSocketPath(e.target.value)}
                  style={{ marginTop: '20px' }}
                />
              </Box>
            </ExpansionPanelDetails>
          </ExpansionPanel>
        </Grid>
        <Grid item xs={12}>
          {getFirestorePanel('Storage')}
        </Grid>
      </Grid>
    );
  };

  const getConfigPanel = () => {
    if (databaseType === 'local') {
      return getLocalPanel();
    } else if (databaseType === 'firestore') {
      return getFirestorePanel('Firestore');
    } else if (databaseType === 'mysql') {
      return getMysqlPanel();
    }
  };

  return (
    <div>
      <Tooltip title="Save Server setTings">
        <Button
          style={{ float: 'right', marginBottom: 20, marginLeft: 20 }}
          variant="contained"
          color="primary"
          onClick={handleClickOpen}
        >
          Configure
        </Button>
      </Tooltip>
      <Paper
        style={{
          margin: 'auto',
          overflow: 'hidden',
          clear: 'both',
          marginBottom: 20,
        }}
      >
        <div>
          <div class="element-container">
            <Grid container spacing={3}>
              <Grid item xs={12}>
                <Grid container>
                  <Grid item xs={9}>
                    <h1 class="element-header" style={{ marginTop: 0 }}>
                      Configuration
                    </h1>
                  </Grid>
                  <Grid item xs={3}>
                    <Tooltip title="setS Database Type For Project">
                      <NativeSelect
                        value={databaseType}
                        onChange={(e) => setDatabaseType(e.target.value)}
                        style={{ width: '100%', paddingTop: 7 }}
                      >
                        <option value={'local'}>Local</option>
                        <option value={'firestore'}>Firestore</option>
                        <option value={'mysql'}>MySQL</option>
                      </NativeSelect>
                    </Tooltip>
                  </Grid>
                </Grid>
                <Grid item xs={12} style={{ marginBottom: 30 }}>
                  <ExpansionPanel
                    style={{ clear: 'both' }}
                    onChange={(e) => setUpdateEmail(!updateEmail)}
                  >
                    <ExpansionPanelSummary
                      expandIcon={<KeyboardArrowDown />}
                      aria-controls="panel1a-content"
                      id="panel1a-header"
                    >
                      <Typography>Email Configuration</Typography>
                    </ExpansionPanelSummary>
                    <ExpansionPanelDetails>
                      <Box
                        margin="auto"
                        width="90%"
                        display="flex"
                        flexDirection="column"
                        textAlign="center"
                        padding="16px"
                      >
                        <input
                          id="host"
                          name="host"
                          placeholder="Host"
                          value={host}
                          onChange={(e) => setHost(e.target.value)}
                          style={{ marginTop: '20px' }}
                        />
                        <input
                          id="port"
                          name="port"
                          placeholder="Port"
                          value={port}
                          onChange={(e) => setPort(e.target.value)}
                          style={{ marginTop: '20px' }}
                        />
                        <input
                          id="username"
                          name="username"
                          placeholder="Username"
                          value={username}
                          onChange={(e) => setUsername(e.target.value)}
                          style={{ marginTop: '20px' }}
                        />
                        <input
                          id="password"
                          name="password"
                          placeholder="Password"
                          type="password"
                          value={password}
                          onChange={(e) => setPassword(e.target.value)}
                          style={{ marginTop: '20px' }}
                        />
                      </Box>
                    </ExpansionPanelDetails>
                  </ExpansionPanel>
                </Grid>
                {!isStateless ? (
                  <Grid item xs={12}>
                    {getConfigPanel()}
                  </Grid>
                ) : null}
              </Grid>
            </Grid>
          </div>
          <div class="element-container">
            <div style={{ height: 40 }}></div>
          </div>
        </div>
        <LoadingDialog loading={loading} message={'Saving setTings'} />
        <YesNoDialog
          open={open}
          closeDialog={handleClose}
          title={'Update configuration?'}
          message={
            'Are you sure you want to update the configuration? Doing so will overwrite current setTings.'
          }
          action={setConfig}
          actionProcess={loading}
        />
        <MessageDialog
          open={messageOpen}
          closeDialog={handleMessageClose}
          title={'Error'}
          message={message}
        />
      </Paper>
    </div>
  );
};

export default Settings;