/**
 * @module modules/commit-detail-picker-sk
 * @description <h2><code>commit-detail-picker-sk</code></h2>
 *
 * @evt commit-selected - Emitted when a commit is selected. The details are of
 * the form CommitDetailPanelSkCommitSelectedDetails
 */

import '../commit-detail-panel-sk';
import 'elements-sk/styles/buttons';
import 'elements-sk/spinner-sk';
import '../day-range-sk';

import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow';
import { errorMessage } from '../errorMessage';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { Commit, CommitNumber, RangeRequest } from '../json';
import { CommitDetailPanelSkCommitSelectedDetails } from '../commit-detail-panel-sk/commit-detail-panel-sk';
import { DayRangeSkChangeDetail } from '../day-range-sk/day-range-sk';

const NO_COMMIT_SELECTED_MSG = 'Choose a commit.';

const initialRange = {
  begin: Math.floor(Date.now() / 1000 - 24 * 60 * 60),
  end: Math.floor(Date.now() / 1000),
};

export class CommitDetailPickerSk extends ElementSk {
  private range: DayRangeSkChangeDetail = initialRange;

  private _selection: CommitNumber = -1;

  private selected: number = -1;

  private details: Commit[];

  private dialog: HTMLDialogElement | null = null;

  private updatingCommits: boolean = false;

  constructor() {
    super(CommitDetailPickerSk.template);
    this.details = [];
  }

  private static _titleFrom = (ele: CommitDetailPickerSk) => {
    const index = ele.selected;
    if (index === -1) {
      return NO_COMMIT_SELECTED_MSG;
    }
    const d = ele.details[index];
    if (!d) {
      return NO_COMMIT_SELECTED_MSG;
    }
    return `${d.author} -  ${d.message}`;
  };

  private static template = (ele: CommitDetailPickerSk) => html`
    <button @click=${ele.open}>${CommitDetailPickerSk._titleFrom(ele)}</button>
    <dialog>
    <h2>Choose a commit</h2>
      <commit-detail-panel-sk
        @commit-selected="${ele.panelSelect}"
        .details="${ele.details}"
        selectable
        selected=${ele.selected}
      ></commit-detail-panel-sk>
      <button @click=${ele.close}>Close</button>

      <hr>
      <p class=tiny>Change the range of commits displayed:</p>
      <details>
        <summary>
          Date Range
        </summary>
        <day-range-sk
          id="range"
          @day-range-change=${ele.rangeChange}
          begin=${ele.range.begin}
          end=${ele.range.end}
        ></day-range-sk>
        <spinner-sk ?active=${ele.updatingCommits}></spinner-sk>
      </details>
    </dialog>
  `;

  connectedCallback(): void {
    super.connectedCallback();
    this._upgradeProperty('details');
    this._upgradeProperty('selection');
    this._render();
    this.dialog = this.querySelector('dialog')!;
    this.updateCommitSelections();
  }

  attributeChangedCallback(): void {
    this._render();
  }

  private rangeChange(e: CustomEvent<DayRangeSkChangeDetail>) {
    this.range = e.detail;
    this.updateCommitSelections();
  }

  private async updateCommitSelections() {
    this.updatingCommits = true;
    this._render();

    const body: RangeRequest = {
      begin: this.range.begin,
      end: this.range.end,
      offset: this.selection,
    };

    try {
      const resp = await fetch('/_/cidRange/', {
        method: 'POST',
        body: JSON.stringify(body),
        headers: {
          'Content-Type': 'application/json',
        },
      });
      const cids = await jsonOrThrow(resp) as Commit[];
      cids.reverse();

      this.details = cids;

      for (let i = 0; i < cids.length; i++) {
        if (((cids[i] as unknown) as Commit).offset === this.selection) {
          this.selected = i;
          break;
        }
      }
      this.range.begin = cids[cids.length - 1].ts;
      this.range.end = cids[0].ts;
      this._render();
    } catch (error: any) {
      errorMessage(error);
    } finally {
      this.updatingCommits = false;
      this._render();
    }
  }

  private panelSelect(e: Event) {
    this.selected = (e as CustomEvent<
      CommitDetailPanelSkCommitSelectedDetails
    >).detail.selected;
    this._render();
    this.close();
  }

  private close() {
    this.dialog!.close();
    this._render();
  }

  private open() {
    this.dialog!.showModal();
    this._render();
  }

  /** The CommitNumber that is selected. */
  get selection(): CommitNumber { return this._selection; }

  set selection(val: CommitNumber) {
    this._selection = val;
    this.updateCommitSelections();
  }
}

define('commit-detail-picker-sk', CommitDetailPickerSk);
