import * as React from 'react';
import { observable, computed, makeObservable } from 'mobx';
import { observer, inject } from 'mobx-react';
import { pages } from 'utils/helpers';
import { withRouter } from 'next/router';
import { withTranslation, WithTranslation } from 'utils/i18n';
import { replaceQuery } from 'utils/routing';
import { IAccountTransaction } from 'typings';
import { Pagination, Box } from '@nova-hf/ui';
import { StickyItem } from 'components/sticky-bar/StickyItem';
import StickyBar from 'components/sticky-bar/StickyBar';
import Checkbox from 'components/checkbox/Checkbox';

import {
  TransactionList,
  ITransactionTableHeaders,
} from '../components/transaction-list/TransactionList';
import { TransactionListItem } from '../components/transaction-list/TransactionListItem';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';

interface ITransactionsProps extends WithTranslation {
  color: string;
  totalCount: number;
  transactions: IAccountTransaction[];
  router?: any;
  profiles?: any;
  ssn: string;
  tableHeaders: ITransactionTableHeaders;
  perPage: number;
  ui?: any;
}

class TransactionsContainer extends React.Component<ITransactionsProps> {
  constructor(props: ITransactionsProps) {
    super(props);

    makeObservable(this, {
      totalCount: observable,
      loading: observable,
      allTransactionsSelected: computed,
    });
  }

  componentWillUnmount() {
    this.props.ui.setIsStickyBar(false);
  }

  totalCount = '';

  loading = false;

  get allTransactionsSelected() {
    const { transactions, profiles } = this.props;

    return (
      transactions.filter((t) => t.pdfUrl).length ===
      profiles.transactions.filter((t: IAccountTransaction) => t.pdfUrl).length
    );
  }

  onSelectPdf = (transaction: IAccountTransaction) => {
    const { profiles, ssn } = this.props;

    profiles.transactionsPdf({ id: [transaction.voucherNumber], ssn });
  };

  onSelectTransaction = (transaction: IAccountTransaction) => {
    const { profiles } = this.props;

    profiles.addTransaction(transaction);
  };

  onSelectAll = (transactions: IAccountTransaction[]) => {
    const { profiles } = this.props;

    this.allTransactionsSelected
      ? profiles.clearTransactions()
      : (profiles.transactions = transactions.filter((t) => t.pdfUrl));
  };

  onClick = async () => {
    const { profiles, ssn } = this.props;
    const { transactions } = profiles;
    const id = transactions.map((trans: IAccountTransaction) => trans.voucherNumber);

    this.loading = true;
    try {
      await profiles.transactionsPdf({ id, ssn });
      this.loading = false;
      profiles.clearTransactions();
    } catch (e) {
      this.loading = false;
      // TODO error handling
    }
  };

  onSelectPage = (page: number, max: number) => {
    const { router, profiles } = this.props;
    if (page < 1 || page > max) return null;

    profiles.clearTransactions();
    replaceQuery({
      router,
      params: {
        page: page.toString(),
      },
    });
    window.scroll({ top: 0, behavior: 'smooth' });
  };

  render() {
    const { color, router, totalCount, profiles, transactions, t, tableHeaders, perPage, ui } =
      this.props;
    const pagesCount = pages(totalCount, perPage);
    const currentPage = router?.query.page && parseInt(router.query.page as string, 10);
    const showStickyBar = profiles.transactions.length > 0;

    if (showStickyBar) {
      ui.setIsStickyBar(true);
    }

    return (
      <>
        <TransactionList
          transactions={transactions}
          color={color}
          onSelect={this.onSelectAll}
          selected={this.allTransactionsSelected}
          headers={tableHeaders}
        >
          {transactions.map((transaction: IAccountTransaction) => (
            <TransactionListItem
              key={transaction.transactionId}
              transaction={transaction}
              color={color}
              onMultiSelect={this.onSelectTransaction}
              onSelect={this.onSelectPdf}
              selected={profiles.transactions.some(
                (i: IAccountTransaction) => i.transactionId === transaction.transactionId,
              )}
              headers={tableHeaders}
            />
          ))}
        </TransactionList>
        {pagesCount > 1 && (
          <Box display="flex" placeItems="center" width="100%" paddingY={3}>
            <Pagination
              color={color as MainColorType}
              currentPage={currentPage || 1}
              onNext={(n) => this.onSelectPage(n + 1, pagesCount)}
              onPage={(n) => this.onSelectPage(n, pagesCount)}
              onPrev={(n) => this.onSelectPage(n - 1, pagesCount)}
              pages={pagesCount}
            />
          </Box>
        )}
        {showStickyBar && (
          <StickyBar
            button={t('download')}
            color={color}
            onClick={this.onClick}
            loading={this.loading}
          >
            <StickyItem color={color}>
              <Checkbox type="radio" large defaultChecked name="transaction">
                {`${profiles.transactions.length} ${
                  profiles.transactions.length === 1
                    ? t('chosenTransaction')
                    : t('chosenTransactions')
                }`}
              </Checkbox>
            </StickyItem>
          </StickyBar>
        )}
      </>
    );
  }
}
export default withTranslation('transactions')(
  withRouter(inject('profiles', 'ui')(observer(TransactionsContainer))),
);
