// Functions used by more than one element.
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
import { TemplateResult, html, Part } from 'lit-html';
import { diffDate } from '../../infra-sk/modules/human';
import { Note, ParamSet } from './json';

const linkRe = /(http[s]?:\/\/[^\s]*)/gm;

/**
 * Returns the full name of a silence.
 */
export function getSilenceFullName(paramSet: ParamSet): string {
  const ret: string[] = [];
  Object.keys(paramSet!).forEach((key) => {
    if (key.startsWith('__')) {
      return;
    }
    ret.push(`${paramSet![key]!.join(', ')}`);
  });
  return ret.join(' ');
}

/**
 * Formats the text for a silence header.
 */
export function displaySilence(paramSet: ParamSet): TemplateResult {
  const fullName = getSilenceFullName(paramSet);
  let displayName = fullName;
  if (displayName.length > 33) {
    displayName = `${displayName.slice(0, 30)}...`;
  }
  if (!displayName.length) {
    displayName = '(*)';
  }
  return html`<span title="${fullName}">${displayName}</span>`;
}

/**
 * Returns the params.abbr to be appended to a string, if present.
 */
export function abbr(paramsAbbr: string): string {
  if (paramsAbbr) {
    return ` - ${paramsAbbr}`;
  }
  return '';
}

/**
 * Convert all URLs in a string into links in a lit-html TemplateResult.
 */
// eslint-disable-next-line @typescript-eslint/type-annotation-spacing
export function linkify(s: string): (part: Part) => void {
  return unsafeHTML(
    s.replace(linkRe, '<a href="$&" rel=noopener target=_blank>$&</a>')
  );
}

/**
 * Templates notes to be displayed.
 */
export function displayNotes(
  notes: Note[],
  stateKey: string,
  eventName: string
): TemplateResult[] {
  if (!notes) {
    return [];
  }
  return notes.map(
    (note: Note, index: number) =>
      html`<section class="note">
        <p class="note-text">${linkify(note.text)}</p>
        <div class="meta">
          <span class="author">${note.author}</span>
          <span class="date">${diffDate(note.ts * 1000)}</span>
          <delete-icon-sk
            title="Delete comment."
            @click=${(e: Event) =>
              deleteNote(index, stateKey, eventName, e)}></delete-icon-sk>
        </div>
      </section>`
  );
}

/**
 * Deletes notes in the specified event's target.
 */
function deleteNote(
  index: number,
  key: string,
  eventName: string,
  e: Event
): void {
  const detail = {
    key: key,
    index: index,
  };
  e.target!.dispatchEvent(
    new CustomEvent(eventName, { detail: detail, bubbles: true })
  );
}

const TIME_DELTAS = [
  { units: 'w', delta: 7 * 24 * 60 * 60 },
  { units: 'd', delta: 24 * 60 * 60 },
  { units: 'h', delta: 60 * 60 },
  { units: 'm', delta: 60 },
  { units: 's', delta: 1 },
];

/**
 * Returns the parsed duration in seconds.
 *
 * @param {string} d - The duration, e.g. "2h" or "4d".
 * @returns {number} The duration in seconds.
 *
 * TODO(jcgregorio) Move into common-sk/modules/human.js with tests.
 */
export function parseDuration(d: string): number {
  const units = d.slice(-1);
  const scalar = +d.slice(0, -1);
  for (let i = 0; i < TIME_DELTAS.length; i++) {
    const o = TIME_DELTAS[i];
    if (o.units === units) {
      return o.delta * scalar;
    }
  }
  return 0;
}

export function expiresIn(
  active: boolean,
  created: number,
  duration: string
): string {
  if (active) {
    return diffDate((created + parseDuration(duration)) * 1000);
  }
  return '';
}

/**
 * Returns the human.diffDate str for the duration from the current date
 * till the next day of the week at the specified time.
 *
 * @param {number} day - Possible values range from 0 to 6 for Sun to Sat.
 * @param {number} hour - Possible values range from 0 to 23 for the hour.
 */
export function getDurationTillNextDay(day: number, hour: number): string {
  const now = new Date();
  const y = now.getFullYear();
  const m = now.getMonth();
  let d = now.getDate();

  // Increment d till we reach the target day.
  let tmp = new Date();
  do {
    tmp = new Date(y, m, ++d);
  } while (tmp.getDay() !== day);
  const target = new Date(y, m, d, hour, 0, 0);

  return diffDate(target.toString());
}
