import * as React from 'react';
import classNames from 'classnames/bind';
// import TextItem from 'components/items/TextItem';
import { options, models, transformFunctions } from 'config/root';
// import qs from 'query-string';
import GenericDisplayFields from 'components/pageItems/GenericDisplayFields';
import DetailLegend from 'components/items/DetailLegend';
import MosaicStructure from 'components/enhancers/MosaicStructure';
import { config, viewConfig } from 'config/general';
import { fieldsToList, getPageInfo, getPageTitle } from 'store/utils/adminHelpers';
import ModuleButton from 'components/items/ModuleButton';
import _ from 'lodash';
import { clone } from 'store/utils/helper';

import GenericHeader from 'components/pageItems/GenericHeader';
import styleIdentifiers from './detail.scss';

const GenericStructure = MosaicStructure(GenericDisplayFields);

const styles = classNames.bind(styleIdentifiers);

export interface DetailProps {
  detail: Record<string, any>;
  dialogShow: Function;
  deleteItem: Function;
  displayId?: boolean;
}

interface DetailState {}

export default class Detail extends React.Component<DetailProps, DetailState> {
  constructor(props) {
    super(props);

    this.state = {
      historySent: false,
      allOpened: false,
    };
  }

  componentDidMount() {
    this.handleLocation();
  }

  componentDidUpdate(prevProps) {
    const { location } = this.props;
    if (prevProps.location !== location) {
      this.historyToSend();
    }
    this.handleLocation();
  }

  historyToSend = () => {
    this.setState({
      historySent: false,
    });
  };

  getLocationTitle = (modelOptions, data, edit) => {
    const { content, lg } = this.props;

    return getPageTitle(modelOptions, data, {
      content,
      lg,
      type: 'detail',
    });
  };

  handleLocation = () => {
    const {
      match: { params },
      pushHistory,
      location,
    } = this.props;

    const { historySent } = this.state;

    if (historySent) return;

    const pageInfo = getPageInfo(this.props, options);

    if (typeof pageInfo === 'string') return;

    const { type, subData, listData, index, form, data, modelOptions } = pageInfo;

    if (!subData && _.isEmpty(data)) return;

    let name = this.getLocationTitle(modelOptions, data);
    let historyId = `${type}_detail`;

    if (form || subData || listData) {
      name = this.getLocationTitle(modelOptions, data);
      historyId += `_sublevel`;
    }
    if (listData && index) {
      name = this.getLocationTitle(modelOptions, data);
      historyId += `_detail`;
    }

    pushHistory({
      pathname: location.pathname,
      search: location.search,
      params,
      id: historyId,
      name,
    });

    this.setState({
      historySent: true,
    });
  };

  edit = (): void => {
    const {
      history,
      location,
      match: { params },
    } = this.props;

    const { type, listData, subData, id, index } = params;
    if (subData) {
      history.push({
        pathname: `/${config.resourcePath}/${type}/${id}/subdata/${subData}/update`,
        search: location.search,
      });
    } else if (listData) {
      history.push({
        pathname: `/${config.resourcePath}/${type}/${id}/listdata/${listData}/${index}/update`,
        search: location.search,
      });
    }
  };

  deleteListItem = () => {
    const { detail, update, history, deleteItem, deleteApollo, loadApollo } = this.props;

    const pageInfo = getPageInfo(this.props, options, models, transformFunctions);

    if (typeof pageInfo === 'string') return;

    const {
      index,
      id,
      listData,
      parentType,
      parentId,
      type,
      listDataOptions,
      modelOptions,
      resourceOptions,
      data,
    } = pageInfo;

    const resourceData = detail && detail.data;
    const toSend = clone(resourceData[listData]);

    if (!toSend) return;

    if (listDataOptions.apollo) {
      deleteApollo({
        id: data[config.idKey] || id,
        options: modelOptions,
        inputs: {
          [listDataOptions.parent]: id,
        },
        callback: () => {
          history.goBack();
          loadApollo({
            id,
            options: resourceOptions,
          });
        },
      });
      return;
    }

    toSend.splice(index, 1);

    if (listDataOptions.separatedDelete) {
      deleteItem({
        resourceId: data[config.idKey],
        resourceType: listData,
        parentId: id,
        parentType: type,
        callback: () => {
          if (modelOptions.deleteBack) {
            history.goBack();
          }
        },
      });
    } else {
      update({
        data: {
          ...resourceData,
          [listData]: toSend,
        },
        doLoading: true,
        resourceType: type,
        resourceId: id,
        parentId,
        parentType,
        callback: (): void => {
          history.goBack();
        },
      });
    }
  };

  render() {
    const {
      history,
      match: { params },
    } = this.props;

    const pageInfo = getPageInfo(this.props, options, models, transformFunctions);

    if (typeof pageInfo === 'string') return <span>{pageInfo}</span>;

    const {
      modelOptions,
      data,
      resourceData,
      transformedData,
      listDataOptions,
      dataOptions,
      fields,
    } = pageInfo;

    const { allOpened } = this.state;

    const listFields = fieldsToList(fields);

    return (
      <div className={styles('Detail', dataOptions && 'header')}>
        {dataOptions && (
          <GenericHeader
            title={this.getLocationTitle(dataOptions, data)}
            editAction={dataOptions && !dataOptions?.noUpdate && this.edit}
            deleteAction={listDataOptions && !listDataOptions?.noDelete && this.deleteListItem}
          />
        )}
        {data && (
          <div className={styles('content')}>
            <GenericStructure
              transformedData={transformedData}
              scrollableColumns
              minWidth={config.widthDetailColumn}
              data={data}
              resourceData={resourceData}
              items={listFields}
              oneSection={listFields.length === 1}
              allOpened={allOpened}
            />
          </div>
        )}
        {(modelOptions?.legend || listFields.length >= 3) && (
          <div className={styles('footer')}>
            <div className={styles('left')}>
              <DetailLegend legend={modelOptions.legend} data={transformedData} />
            </div>
            {listFields.length >= 3 && (
              <ModuleButton
                label={allOpened ? 'admin.buttons.closeAll' : 'admin.buttons.openAll'}
                noMargin
                small
                color="primary"
                relative
                action={() => {
                  this.setState({
                    allOpened: !allOpened,
                  });
                }}
              />
            )}
          </div>
        )}
      </div>
    );
  }
}
