/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React from 'react';
import pgAdmin from 'sources/pgadmin';
import getApiInstance from 'sources/api_instance';
import { makeStyles } from '@material-ui/core/styles';
import { Box, Switch } from '@material-ui/core';
import { generateCollectionURL } from '../../browser/static/js/node_ajax';
import Notify from '../../static/js/helpers/Notifier';
import gettext from 'sources/gettext';
import 'wcdocker';
import PgTable from 'sources/components/PgTable';
import Theme from 'sources/Theme';
import PropTypes from 'prop-types';
import { PgIconButton } from '../../static/js/components/Buttons';
import DeleteIcon from '@material-ui/icons/Delete';
import DeleteSweepIcon from '@material-ui/icons/DeleteSweep';
import EmptyPanelMessage from '../../static/js/components/EmptyPanelMessage';
import Loader from 'sources/components/Loader';

const useStyles = makeStyles((theme) => ({
  emptyPanel: {
    minHeight: '100%',
    minWidth: '100%',
    background: theme.otherVars.emptySpaceBg,
    overflow: 'auto',
    padding: '8px',
    display: 'flex',
  },
  panelIcon: {
    width: '80%',
    margin: '0 auto',
    marginTop: '25px !important',
    position: 'relative',
    textAlign: 'center',
  },
  panelMessage: {
    marginLeft: '0.5rem',
    fontSize: '0.875rem',
  },
  searchPadding: {
    flex: 2.5
  },
  searchInput: {
    flex: 1,
    margin: '4 0 4 0',
    borderLeft: 'none',
    paddingLeft: 5
  },
  propertiesPanel: {
    height: '100%'
  },
  autoResizer: {
    height: '100% !important',
    width: '100% !important',
    background: theme.palette.grey[400],
    padding: '8px',
    overflow: 'hidden !important',
    overflowX: 'auto !important'
  },
  dropButton: {
    marginRight: '8px !important'
  },
  readOnlySwitch: {
    opacity: 0.75,
    '& .MuiSwitch-track': {
      opacity: theme.palette.action.disabledOpacity,
    }
  }
}));

export function CollectionNodeView({
  node,
  treeNodeInfo,
  itemNodeData,
  item,
  pgBrowser
}) {
  const classes = useStyles();

  const [data, setData] = React.useState([]);
  const [infoMsg, setInfoMsg] = React.useState('Please select an object in the tree view.');
  const [selectedObject, setSelectedObject] = React.useState([]);
  const [reload, setReload] = React.useState(false);
  const [loaderText, setLoaderText] = React.useState('');

  //Reload the collection node on refresh or change in children count
  React.useEffect(() => {
    setReload(!reload);
  }, [item?._children]);

  const [pgTableColumns, setPgTableColumns] = React.useState([
    {
      Header: 'properties',
      accessor: 'Properties',
      sortable: true,
      resizable: true,
      disableGlobalFilter: false,
    },
    {
      Header: 'value',
      accessor: 'value',
      sortable: true,
      resizable: true,
      disableGlobalFilter: false,
    },
  ]);

  const getTableSelectedRows = (selRows) => {
    setSelectedObject(selRows);
  };

  const onDrop = (type) => {
    let selRowModels = selectedObject,
      selRows = [],
      selItem = pgBrowser.tree.selected(),
      selectedItemData = selItem ? pgBrowser.tree.itemData(selItem) : null,
      selNode = selectedItemData && pgBrowser.Nodes[selectedItemData._type],
      url = undefined,
      msg = undefined,
      title = undefined;

    if (selNode && selNode.type && selNode.type == 'coll-constraints') {
      // In order to identify the constraint type, the type should be passed to the server
      selRows = selRowModels.map((row) => ({
        id: row.original.oid,
        _type: row.original._type,
      }));
    } else {
      selRows = selRowModels.map((row) => row.original.oid);
    }

    if (selRows.length === 0) {
      Notify.alert(
        gettext('Drop Multiple'),
        gettext('Please select at least one object to delete.')
      );
      return;
    }

    if (!selNode) return;

    if (type === 'dropCascade') {
      url = selNode.generate_url(selItem, 'delete');
      msg = gettext(
        'Are you sure you want to drop all the selected objects and all the objects that depend on them?'
      );
      title = gettext('DROP CASCADE multiple objects?');
    } else {
      url = selNode.generate_url(selItem, 'drop');
      msg = gettext('Are you sure you want to drop all the selected objects?');
      title = gettext('DROP multiple objects?');
    }

    const api = getApiInstance();
    let dropNodeProperties = function () {
      api
        .delete(url, {
          data: JSON.stringify({ ids: selRows }),
          contentType: 'application/json; charset=utf-8',
        })
        .then(function (res) {
          if (res.success == 0) {
            pgBrowser.report_error(res.errormsg, res.info);
          }
          pgAdmin.Browser.tree.refresh(selItem);
          setReload(!reload);
        })
        .catch(function (error) {
          Notify.alert(
            gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
            _.isUndefined(error.response) ? error.message : error.response.data.errormsg
          );
        });
    };

    if (confirm) {
      Notify.confirm(title, msg, dropNodeProperties, null);
    } else {
      dropNodeProperties();
    }
  };

  React.useEffect(() => {
    if (node){

      let nodeObj =
      pgAdmin.Browser.Nodes[itemNodeData?._type.replace('coll-', '')];

      let url = generateCollectionURL.call(nodeObj, item, 'properties');

      const api = getApiInstance();

      let tableColumns = [];
      let column = {};
      setLoaderText('Loading...');

      if (itemNodeData._type.indexOf('coll-') > -1 && !_.isUndefined(nodeObj.getSchema)) {
        let schema = nodeObj.getSchema?.call(nodeObj, treeNodeInfo, itemNodeData);
        schema.fields.forEach((field) => {
          if (node.columns.indexOf(field.id) > -1) {
            if (field.label.indexOf('?') > -1) {
              column = {
                Header: field.label,
                accessor: field.id,
                sortable: true,
                resizable: true,
                disableGlobalFilter: false,
                minWidth: 0,
                // eslint-disable-next-line react/display-name
                Cell: ({ value }) => {
                  return (<Switch color="primary" checked={value} className={classes.readOnlySwitch} value={value} readOnly title={String(value)} />);
                }
              };
            } else {
              column = {
                Header: field.label,
                accessor: field.id,
                sortable: true,
                resizable: true,
                disableGlobalFilter: false,
                minWidth: 0,
              };
            }
            tableColumns.push(column);
          }
        });
      }else{
        node.columns.forEach((field) => {
          column = {
            Header: field,
            accessor: field,
            sortable: true,
            resizable: true,
            disableGlobalFilter: false,
            minWidth: 0,
          };
          tableColumns.push(column);
        });
      }

      api({
        url: url,
        type: 'GET',
      })
        .then((res) => {
          res.data.forEach((element) => {
            element['icon'] = '';
          });
          setPgTableColumns(tableColumns);
          setData(res.data);
          setInfoMsg('No properties are available for the selected object.');
          setLoaderText('');
        })
        .catch((err) => {
          Notify.alert(
            gettext('Failed to retrieve data from the server.'),
            gettext(err.message)
          );
        });
    }
  }, [itemNodeData, node, item, reload]);

  const CustomHeader = () => {
    return (
      <Box >
        <PgIconButton
          className={classes.dropButton}
          icon={<DeleteIcon/>}
          aria-label="Delete/Drop"
          title={gettext('Delete/Drop')}
          onClick={() => {
            onDrop('drop');
          }}
          disabled={
            (selectedObject.length > 0)
              ? !node.canDrop
              : true
          }
        ></PgIconButton>
        <PgIconButton
          className={classes.dropButton}
          icon={<DeleteSweepIcon />}
          aria-label="Drop Cascade"
          title={gettext('Drop Cascade')}
          onClick={() => {
            onDrop('dropCascade');
          }}
          disabled={
            (selectedObject.length > 0)
              ? !node.canDropCascade
              : true
          }
        ></PgIconButton>
      </Box>);
  };

  return (
    <Theme className='obj_properties'>
      <Box className={classes.propertiesPanel}>
        {data.length > 0 ?
          (
            <PgTable
              isSelectRow={!('catalog' in treeNodeInfo) && (itemNodeData.label !== 'Catalogs') && _.isUndefined(node?.canSelect)}
              CustomHeader={CustomHeader}
              className={classes.autoResizer}
              columns={pgTableColumns}
              data={data}
              type={'panel'}
              isSearch={false}
              getSelectedRows={getTableSelectedRows}
            />
          )
          :
          (
            <div className={classes.emptyPanel}>
              {loaderText ? (<Loader message={loaderText}/>) :
                <EmptyPanelMessage text={gettext(infoMsg)}/>
              }
            </div>
          )
        }
      </Box>
    </Theme>
  );
}

CollectionNodeView.propTypes = {
  node: PropTypes.func,
  itemData: PropTypes.object,
  itemNodeData: PropTypes.object,
  treeNodeInfo: PropTypes.object,
  item: PropTypes.object,
  pgBrowser: PropTypes.object,
  preferences: PropTypes.object,
  sid: PropTypes.number,
  did: PropTypes.number,
  row: PropTypes.object,
  serverConnected: PropTypes.bool,
  value: PropTypes.bool,
};
