import { createTranslationFunc } from '../utils';

const t = createTranslationFunc({
  pl_PL: {
    Loading: 'Wczytywanie',
    'Previous page': 'Poprzednia strona',
    'Next page': 'Następna strona',
    'Something went wrong while loading the data':
      'Coś poszło nie tak podczas wczytywania danych',
  },
});

export type DialogTableColumn<T> = {
  header: string;
  accessor: (row: T, index: number, rows: T[]) => string;
};

export type Cursor = {
  next?: string;
  self?: string;
};

export type LoadDataResult<T> = {
  cursor?: Cursor;
  data: T[];
};

export class DialogTable<T> {
  private readonly prevPageId: string;
  private readonly nextPageId: string;

  private readonly prevCursors: Cursor[] = [];

  constructor(
    private readonly id: string,
    private readonly columns: DialogTableColumn<T>[],
    private readonly limit: number,
    private readonly loadData: (
      cursor: string | undefined,
      limit: number
    ) => Promise<LoadDataResult<T>>
  ) {
    this.prevPageId = `${this.id}_page_prev`;
    this.nextPageId = `${this.id}_page_next`;
  }

  public async render() {
    await this.renderPage();
  }

  private async renderPage(pageCursor?: string) {
    window.Dialog.show(this.id, `<p>${t('Loading')}...</p>`);

    try {
      const { data, cursor } = await this.loadData(pageCursor, this.limit);

      window.Dialog.show(
        this.id,
        `
      ${this.buildPagination(cursor)}
      ${this.buildTable(data)}
    `
      );

      this.addEventListeners(cursor);
    } catch (err) {
      console.error(err);
      window.Dialog.close();
      window.UI.ErrorMessage(t('Something went wrong while loading the data'));
    }
  }

  private buildPagination(cursor?: Cursor): string {
    return `
      <div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
          <button title="${t(
            'Previous page'
          )}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${
            this.prevCursors.length === 0 ? ' disabled' : ''
          }>&lt;</button>
          <button title="${t('Next page')}" class="btn" id="${
            this.nextPageId
          }"${!cursor?.next ? ' disabled' : ''}>&gt;</button>
      </div>    
    `;
  }

  private buildTable(data: T[]) {
    return `
      <table style="width: 100%" class="vis">
        <tbody>
          <tr>
            ${this.columns.map((col) => `<th>${col.header}</th>`).join('')}
          </tr>
          ${data
            .map(
              (r, index) => `
            <tr>
                ${this.columns
                  .map((col) => `<td>${col.accessor(r, index, data)}</td>`)
                  .join('')}
            </tr>
          `
            )
            .join('')}
        </tbody>
      </table>      
      `;
  }

  private addEventListeners(cursor?: Cursor) {
    document
      .querySelector('#' + this.prevPageId)
      ?.addEventListener('click', () => {
        const prev = this.prevCursors.pop();
        if (!prev) {
          return;
        }
        this.renderPage(prev.self);
      });

    document
      .querySelector('#' + this.nextPageId)
      ?.addEventListener('click', () => {
        if (!cursor) {
          return;
        }
        this.prevCursors.push(cursor);
        this.renderPage(cursor.next);
      });
  }
}
