import React from "react";
import { connect } from "react-redux";
import { translate } from "react-i18next";
import classNames from "classnames";
import styled from "styled-components";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
import { File, Repository } from "@scm-manager/ui-types";
import { DateFromNow, ErrorNotification, FileSize, Icon } from "@scm-manager/ui-components";
import { getSources } from "../modules/sources";
import FileButtonAddons from "../components/content/FileButtonAddons";
import SourcesView from "./SourcesView";
import HistoryView from "./HistoryView";

type Props = {
  loading: boolean;
  file: File;
  repository: Repository;
  revision: string;
  path: string;

  // context props
  t: (p: string) => string;
};

type State = {
  collapsed: boolean;
  showHistory: boolean;
  errorFromExtension?: Error;
};

const VCenteredChild = styled.div`
  align-items: center;
`;

const RightMarginIcon = styled(Icon)`
  margin-right: 0.5em;
`;

const RightMarginFileButtonAddons = styled(FileButtonAddons)`
  margin-right: 0.5em;
`;

const LighterGreyBackgroundPanelBlock = styled.div`
  background-color: #fbfbfb;
`;

const LighterGreyBackgroundTable = styled.table`
  background-color: #fbfbfb;
`;

class Content extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
      collapsed: true,
      showHistory: false
    };
  }

  toggleCollapse = () => {
    this.setState(prevState => ({
      collapsed: !prevState.collapsed
    }));
  };

  setShowHistoryState(showHistory: boolean) {
    this.setState({
      ...this.state,
      showHistory
    });
  }

  handleExtensionError = (error: Error) => {
    this.setState({
      errorFromExtension: error
    });
  };

  showHeader() {
    const { file, revision } = this.props;
    const { showHistory, collapsed } = this.state;
    const icon = collapsed ? "angle-right" : "angle-down";

    const selector = file._links.history ? (
      <RightMarginFileButtonAddons
        file={file}
        historyIsSelected={showHistory}
        showHistory={(changeShowHistory: boolean) => this.setShowHistoryState(changeShowHistory)}
      />
    ) : null;

    return (
      <span className="has-cursor-pointer">
        <VCenteredChild className={classNames("media", "is-flex")}>
          <div className="media-content" onClick={this.toggleCollapse}>
            <RightMarginIcon name={icon} color="inherit" />
            <span className="is-word-break">{file.name}</span>
          </div>
          <div className="buttons is-grouped">
            {selector}
            <ExtensionPoint
              name="repos.sources.content.actionbar"
              props={{
                file,
                revision,
                handleExtensionError: this.handleExtensionError
              }}
              renderAll={true}
            />
          </div>
        </VCenteredChild>
      </span>
    );
  }

  showMoreInformation() {
    const collapsed = this.state.collapsed;
    const { file, revision, t, repository } = this.props;
    const date = <DateFromNow date={file.lastModified} />;
    const description = file.description ? (
      <p>
        {file.description.split("\n").map((item, key) => {
          return (
            <span key={key}>
              {item}
              <br />
            </span>
          );
        })}
      </p>
    ) : null;
    const fileSize = file.directory ? "" : <FileSize bytes={file.length} />;
    if (!collapsed) {
      return (
        <LighterGreyBackgroundPanelBlock className="panel-block">
          <LighterGreyBackgroundTable className="table">
            <tbody>
              <tr>
                <td>{t("sources.content.path")}</td>
                <td className="is-word-break">{file.path}</td>
              </tr>
              <tr>
                <td>{t("sources.content.branch")}</td>
                <td className="is-word-break">{revision}</td>
              </tr>
              <tr>
                <td>{t("sources.content.size")}</td>
                <td>{fileSize}</td>
              </tr>
              <tr>
                <td>{t("sources.content.lastModified")}</td>
                <td>{date}</td>
              </tr>
              <tr>
                <td>{t("sources.content.description")}</td>
                <td className="is-word-break">{description}</td>
              </tr>
              <ExtensionPoint
                name="repos.content.metadata"
                renderAll={true}
                props={{
                  file,
                  repository,
                  revision
                }}
              />
            </tbody>
          </LighterGreyBackgroundTable>
        </LighterGreyBackgroundPanelBlock>
      );
    }
    return null;
  }

  render() {
    const { file, revision, repository, path } = this.props;
    const { showHistory, errorFromExtension } = this.state;

    const header = this.showHeader();
    const content =
      showHistory && file._links.history ? (
        <HistoryView file={file} repository={repository} />
      ) : (
        <SourcesView revision={revision} file={file} repository={repository} path={path} />
      );
    const moreInformation = this.showMoreInformation();

    return (
      <div>
        <div className="panel">
          <div className="panel-heading">{header}</div>
          {moreInformation}
          {content}
        </div>
        {errorFromExtension && <ErrorNotification error={errorFromExtension} />}
      </div>
    );
  }
}

const mapStateToProps = (state: any, ownProps: Props) => {
  const { repository, revision, path } = ownProps;

  const file = getSources(state, repository, revision, path);

  return {
    file
  };
};

export default connect(mapStateToProps)(translate("repos")(Content));
