/**
 * @module modules/domain-picker-sk
 * @description <h2><code>domain-picker-sk</code></h2>
 *
 * Allows picking either a date range for commits, or for
 * picking a number of commits to show before a selected
 * date.
 *
 * @attr {string} force_request_type - A value of 'dense' or 'range' will
 *   force the corresponding request_type to be always set.
 *
 */
import { html } from 'lit/html.js';
import { define } from '../../../elements-sk/modules/define';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { RequestType } from '../json';

import '../../../elements-sk/modules/radio-sk';
import '../calendar-input-sk';

// Types of domain ranges we can choose.
// TODO(jcgregorio) Make the underlying dataframe.RequestType a string.
const RANGE = 0; // Specify a begin and end time.
const DENSE = 1; // Specify an end time and the number of commits with data.

type ForceRequestType = 'range' | 'dense' | '';

const toDate = (seconds: number) => new Date(seconds * 1000);

const toForceRequestType = (s: string | null): ForceRequestType => {
  if (s === 'range') {
    return 'range';
  }
  if (s === 'dense') {
    return 'dense';
  }
  return '';
};

/** The state of the DomainPickerSk control. */
export interface DomainPickerState {
  /**  Beginning of time range in Unix timestamp seconds. */
  begin: number;
  /**  End of time range in Unix timestamp seconds. */
  end: number;
  /**
   * If RequestType is REQUEST_COMPACT (1), then this value is the number of
   * commits to show before End, and the value of Begin is ignored.
   */
  num_commits: number;
  request_type: RequestType;
}

export class DomainPickerSk extends ElementSk {
  private _state: DomainPickerState;

  constructor() {
    super(DomainPickerSk.template);
    const now = Date.now();
    this._state = {
      begin: Math.floor(now / 1000 - 24 * 60 * 60),
      end: Math.floor(now / 1000),
      num_commits: 50,
      request_type: RANGE,
    };
  }

  private static template = (ele: DomainPickerSk) => html`
    ${DomainPickerSk._showRadio(ele)}
    <div class="ranges">
      ${DomainPickerSk._requestType(ele)}
      <label>
        <span class="prefix">End:</span>
        <calendar-input-sk
          @input=${ele.endChange}
          .displayDate=${toDate(ele._state.end)}></calendar-input-sk>
      </label>
    </div>
  `;

  private static _showRadio = (ele: DomainPickerSk) => {
    if (!ele.force_request_type) {
      return html`
        <radio-sk
          @change=${ele.typeRange}
          ?checked=${ele._state.request_type === RANGE}
          label="Date Range"
          name="daterange"></radio-sk>
        <radio-sk
          @change=${ele.typeDense}
          ?checked=${ele._state.request_type === DENSE}
          label="Dense"
          name="daterange"></radio-sk>
      `;
    }
    return html``;
  };

  private static _requestType = (ele: DomainPickerSk) => {
    if (ele._state.request_type === RANGE) {
      return html`
        <p>Display all points in the date range.</p>
        <label>
          <span class="prefix">Begin:</span>
          <calendar-input-sk
            @input=${ele.beginChange}
            .displayDate=${toDate(ele._state.begin)}></calendar-input-sk>
        </label>
      `;
    }
    return html`
      <p>Display only the points that have data before the date.</p>
      <label>
        <span class="prefix">Points</span>
        <input
          @change=${ele.numChanged}
          type="number"
          .value="${ele._state.num_commits.toString()}"
          min="1"
          max="5000"
          list="defaultNumbers"
          title="The number of points." />
      </label>
      <datalist id="defaultNumbers">
        <option value="50"></option>
        <option value="100"></option>
        <option value="250"></option>
        <option value="500"></option>
      </datalist>
    `;
  };

  connectedCallback(): void {
    super.connectedCallback();
    this._upgradeProperty('state');
    this._upgradeProperty('force_request_type');
    this.render();
  }

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

  render(): void {
    if (this.force_request_type === 'dense') {
      this._state.request_type = DENSE;
    } else if (this.force_request_type === 'range') {
      this._state.request_type = RANGE;
    }
    super._render();
  }

  private typeRange() {
    this._state.request_type = RANGE;
    this.render();
  }

  private typeDense() {
    this._state.request_type = DENSE;
    this.render();
  }

  private beginChange(e: CustomEvent<Date>) {
    this._state.begin = Math.floor(e.detail.valueOf() / 1000);
    this.render();
  }

  private endChange(e: CustomEvent<Date>) {
    this._state.end = Math.floor(e.detail.valueOf() / 1000);
    this.render();
  }

  private numChanged(e: MouseEvent) {
    this._state.num_commits = +(e.target! as HTMLInputElement).value;
    this.render();
  }

  static get observedAttributes(): string[] {
    return ['force_request_type'];
  }

  get state(): DomainPickerState {
    return this._state;
  }

  set state(val: DomainPickerState) {
    if (!val) {
      return;
    }
    this._state = {
      begin: val.begin,
      end: val.end,
      num_commits: val.num_commits,
      request_type: val.request_type,
    };
    this.render();
  }

  /**  A value of DENSE or RANGE will force the corresponding request_type to be always set.
   */
  get force_request_type(): ForceRequestType {
    return toForceRequestType(this.getAttribute('force_request_type'));
  }

  set force_request_type(val: ForceRequestType) {
    this.setAttribute('force_request_type', toForceRequestType(val));
  }
}

define('domain-picker-sk', DomainPickerSk);
