/**
 * @author Martin Karkowski
 * @email m.karkowski@zema.de
 * @create date 2020-12-03 11:57:29
 * @modify date 2020-12-03 11:57:29
 * @desc [description]
 */

import { faHashtag } from "@fortawesome/free-solid-svg-icons";
import React from "react";
import {
  Alert,
  Button,
  Col,
  Container,
  Jumbotron,
  Row,
  Table
} from "react-bootstrap";
import { dynamicSort } from "../../lib/helpers/arrayMethods";
import { INopeDispatcher } from "../../lib/types/nope/nopeDispatcher.interface";
import { INopeModuleDescription } from "../../lib/types/nope/nopeModule.interface";
import { INopeObserver } from "../../lib/types/nope/nopeObservable.interface";
import AvailableDispatchers from "../../resources/admin-shell/dispatchers";
import Toolbar from "../../resources/ui/layout/toolbar";

class OverviewComponent extends React.Component<
  { dispatcher: INopeDispatcher },
  { instances: INopeModuleDescription[]; connected: boolean }
> {
  private _observer: INopeObserver[] = [];

  private __refresh() {
    const connected = this.props.dispatcher.communicator.connected.getContent();

    this.setState({
      instances: connected
        ? this.props.dispatcher.availableInstances
            .getContent()
            .sort(dynamicSort("identifier"))
        : [],
      connected
    });
  }

  /**
   * Function will be called if the Item has been rendered sucessfully.
   */
  componentDidMount() {
    if (this.props.dispatcher) {
      // Subscribe to the Instances.

      this.__refresh();

      const _this = this;

      this._observer.push(
        this.props.dispatcher.availableInstances.subscribe(() => {
          _this.__refresh();
        })
      );

      this._observer.push(
        this.props.dispatcher.communicator.connected.subscribe(() => {
          _this.__refresh();
        })
      );
    }
  }

  /**
   * Function, that will be called before the network fails.
   */
  componentWillUnmount() {
    // Call the unmount
    for (const _observer of this._observer) {
      _observer.unsubscribe();
    }
  }

  constructor(props) {
    super(props);
    this.state = {
      instances: [],
      connected: false
    };
  }

  public render() {
    let idx = 0;
    return (
      <>
        <Container>
          <Toolbar<undefined>
            toolbar={{
              items: [
                {
                  type: "link",
                  ref: "/docs",
                  label: "docs",
                  icon: faHashtag
                }
              ]
            }}
            generateData={() => undefined}
            brand={{
              ref: "/",
              type: "link",
              icon: "/nope/logo_light.png",
              label: " Overview"
            }}
          ></Toolbar>
          <Jumbotron>
            {this.state.connected ? (
              <Alert variant={"success"}>Backend online</Alert>
            ) : (
              <>
                <Alert variant={"danger"}>
                  Not able to connect to the Backend <b>:'(</b>
                </Alert>
                <p>
                  Please start a Nope-Backend with the following command:{" "}
                  <code>
                    node .\dist\lib\cli\runNopeBackend.js -c io-server
                  </code>
                </p>
              </>
            )}
            <Button
              variant="light"
              style={{ width: "100%" }}
              onClick={() => this.__refresh()}
            >
              Manual Refresh
            </Button>
          </Jumbotron>
          <Row>
            <Col>
              <AvailableDispatchers
                dispatcher={this.props.dispatcher}
              ></AvailableDispatchers>
            </Col>
          </Row>
          <Row>
            <Col>
              <Jumbotron>
                <h1>Instances</h1>
                <p>The Following instances has been found:</p>
                <Table striped bordered hover>
                  <thead>
                    <tr>
                      <th>Identifier</th>
                      <th>Type</th>
                      <th></th>
                    </tr>
                  </thead>
                  <tbody>
                    {this.state.instances.map((instance) => {
                      return (
                        <tr key={idx++}>
                          <td>{instance.identifier}</td>
                          <td>
                            <code>{instance.type}</code>
                          </td>
                          <td></td>
                        </tr>
                      );
                    })}
                  </tbody>
                </Table>
              </Jumbotron>
            </Col>
          </Row>
        </Container>
      </>
    );
  }
}

export default OverviewComponent;
