// Copyright 2022 Northern.tech AS
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link as RouterLink, useNavigate } from 'react-router-dom';

import { Button } from '@mui/material';
import { makeStyles } from 'tss-react/mui';

import { ContentSection } from '@northern.tech/common-ui/ContentSection';
import DocsLink from '@northern.tech/common-ui/DocsLink';
import EnterpriseNotification from '@northern.tech/common-ui/EnterpriseNotification';
import { TwoColumnData } from '@northern.tech/common-ui/TwoColumnData';
import storeActions from '@northern.tech/store/actions';
import { ALL_DEVICE_STATES, BENEFITS, DEVICE_LIST_DEFAULTS, DEVICE_STATES, SORTING_OPTIONS } from '@northern.tech/store/constants';
import { getCurrentSession, getDevicesById, getIdAttribute, getIsPreview, getOrganization } from '@northern.tech/store/selectors';
import { getSystemDevices } from '@northern.tech/store/thunks';
import { getDemoDeviceAddress, toggle } from '@northern.tech/utils/helpers';

import { getHeaders } from '../AuthorizedDevices';
import { routes } from '../BaseDevices';
import Devicelist from '../DeviceList';
import ConnectToGatewayDialog from '../dialogs/ConnectToGatewayDialog';

const { setSnackbar } = storeActions;

const useStyles = makeStyles()(theme => ({ container: { maxWidth: 600, marginTop: theme.spacing(), marginBottom: theme.spacing() } }));

export const DeviceSystem = ({ columnSelection, device, onConnectToGatewayClick, openSettingsDialog }) => {
  const [columnHeaders, setColumnHeaders] = useState([]);
  const [headerKeys, setHeaderKeys] = useState([]);
  const [page, setPage] = useState(DEVICE_LIST_DEFAULTS.page);
  const [perPage, setPerPage] = useState(DEVICE_LIST_DEFAULTS.perPage);
  const { classes } = useStyles();
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const devicesById = useSelector(getDevicesById);
  const idAttribute = useSelector(getIdAttribute);

  const { systemDeviceIds = [], systemDeviceTotal = 0 } = device;
  const deviceIp = getDemoDeviceAddress([device]);

  const [sortOptions, setSortOptions] = useState([]);

  const onSortChange = attribute => {
    let changedOrder = SORTING_OPTIONS.asc;
    if (sortOptions.length && sortOptions[0].attribute == attribute.name) {
      changedOrder = sortOptions[0].order === SORTING_OPTIONS.desc ? SORTING_OPTIONS.asc : SORTING_OPTIONS.desc;
    }
    setSortOptions([{ attribute: attribute.name, scope: attribute.scope, order: changedOrder }]);
  };

  useEffect(() => {
    const columnHeaders = getHeaders(columnSelection, routes.allDevices.defaultHeaders, idAttribute, openSettingsDialog);
    setColumnHeaders(columnHeaders);
    setHeaderKeys(columnHeaders.map(({ attribute: { name, scope } }) => `${name}-${scope}`).join('-'));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [columnSelection, idAttribute.attribute, openSettingsDialog]);

  useEffect(() => {
    if (device.attributes) {
      dispatch(getSystemDevices({ id: device.id, page, perPage, sortOptions }));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dispatch, device.id, device.attributes?.mender_is_gateway, page, perPage, sortOptions]);

  const onDeviceClick = (device = {}) => {
    const deviceState = DEVICE_STATES[device.status] ?? ALL_DEVICE_STATES;
    navigate(`/devices/${deviceState}?id=${device.id}&open=true&tab=identity`, { state: { internal: true } });
  };

  return (
    <>
      <ContentSection postTitle={<EnterpriseNotification id={BENEFITS.gateway.id} />} title="Mender Gateway">
        <TwoColumnData data={{ 'Server IP': deviceIp }} setSnackbar={message => dispatch(setSnackbar(message))} />
      </ContentSection>
      <ContentSection className={classes.container} title="System for this gateway">
        {systemDeviceTotal ? (
          <Devicelist
            customColumnSizes={[]}
            columnHeaders={columnHeaders}
            devices={systemDeviceIds.map(id => devicesById[id])}
            deviceListState={{ page, perPage }}
            headerKeys={headerKeys}
            idAttribute={idAttribute}
            onChangeRowsPerPage={setPerPage}
            onExpandClick={onDeviceClick}
            onResizeColumns={false}
            onPageChange={setPage}
            onSelect={false}
            onSort={onSortChange}
            pageLoading={false}
            pageTotal={systemDeviceTotal}
          />
        ) : (
          <div className="dashboard-placeholder">
            <p>No devices have been connected to this gateway device yet.</p>
            <div>
              Visit the <DocsLink path="get-started/mender-gateway" title="full Mender Gateway documentation" /> to learn how to make the most of the gateway
              functionality.
            </div>
          </div>
        )}
      </ContentSection>
      <div className="flexbox">
        <Button color="secondary" component={RouterLink} to={`/deployments?deviceId=${device.id}&open=true`}>
          Create deployment for this system
        </Button>
        <Button onClick={onConnectToGatewayClick}>Connect devices</Button>
      </div>
    </>
  );
};

const DeviceSystemTab = ({ device, ...remainder }) => {
  const [open, setOpen] = useState(false);
  const isPreRelease = useSelector(getIsPreview);
  const { tenant_token: tenantToken } = useSelector(getOrganization);
  const { token } = useSelector(getCurrentSession);

  const gatewayIp = getDemoDeviceAddress([device]);
  const toggleDialog = () => setOpen(toggle);
  return (
    <>
      <DeviceSystem onConnectToGatewayClick={toggleDialog} {...{ device, ...remainder }} />
      {open && <ConnectToGatewayDialog gatewayIp={gatewayIp} isPreRelease={isPreRelease} onCancel={toggleDialog} tenantToken={tenantToken} token={token} />}
    </>
  );
};

export default DeviceSystemTab;
