/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {LitElement, html, CSSResultArray, TemplateResult} from 'lit';
import { customElement, property } from 'lit/decorators.js';
import {styles} from './nile-format-date.css';
import NileElement from '../internal/nile-element';


/**
 * Nile format-date component.
 *
 * @tag nile-format-date
 *
 */
@customElement('nile-format-date')
export class NileFormatDate extends NileElement {
  /**
   * The styles for nile-format-date
   * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]`
   */
  public static get styles(): CSSResultArray {
    return [styles];
  }

  /**
   * The date/time to format. If not set, the current date and time will be used. When passing a string, it's strongly
   * recommended to use the ISO 8601 format to ensure timezones are handled correctly. To convert a date to this format
   * in JavaScript, use [`date.toISOString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString).
   */
  @property() date: Date | string = new Date();

  /** The format for displaying the weekday. */
  @property() weekday: 'narrow' | 'short' | 'long';

  /** The format for displaying the era. */
  @property() era: 'narrow' | 'short' | 'long';

  /** The format for displaying the year. */
  @property() year: 'numeric' | '2-digit';

  /** The format for displaying the month. */
  @property() month: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long';

  /** The format for displaying the day. */
  @property() day: 'numeric' | '2-digit';

  /** The format for displaying the hour. */
  @property() hour: 'numeric' | '2-digit';

  /** The format for displaying the minute. */
  @property() minute: 'numeric' | '2-digit';

  /** The format for displaying the second. */
  @property() second: 'numeric' | '2-digit';

  /** The format for displaying the time. */
  @property({ attribute: 'time-zone-name' }) timeZoneName: 'short' | 'long';

  /** The time zone to express the time in. */
  @property({ attribute: 'time-zone' }) timeZone: string;

  /** The format for displaying the hour. */
  @property({ attribute: 'hour-format' }) hourFormat: 'auto' | '12' | '24' =
    'auto';

  /** The separator for the date format. */
  @property({ attribute: 'date-separator' }) dateSeparator: '-' | '/' = '-';

  formatDate(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string {
    dateToFormat = new Date(dateToFormat);
    const formatter = new Intl.DateTimeFormat('en-GB', options);
    const parts = formatter.formatToParts(dateToFormat);
    const formattedDate = parts.map(({ type, value }) => {
      if (type === 'day' || type === 'month' || type === 'year') {
        return value;
      }
      if (type === 'literal' && value === '/') {
        return this.dateSeparator;
      }
      return value;
    }).join('');
    return formattedDate;
  }

  // formatDate(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string {
  //   dateToFormat = new Date(dateToFormat);
  //   return new Intl.DateTimeFormat('en-GB', options).format(dateToFormat);
  // }


  render() {
    const date = new Date(this.date);
    const hour12 =
      this.hourFormat === 'auto' ? undefined : this.hourFormat === '12';

    // Check for an invalid date
    if (isNaN(date.getMilliseconds())) {
      return undefined;
    }

    return html`
      <time datetime=${date.toISOString()}>
        ${this.formatDate(date, {
          weekday: this.weekday,
          era: this.era,
          year: this.year,
          month: this.month,
          day: this.day,
          hour: this.hour,
          minute: this.minute,
          second: this.second,
          timeZoneName: this.timeZoneName,
          timeZone: this.timeZone,
          hour12: hour12,
        })}
      </time>
    `;
  }
}
	/* #endregion */

export default NileFormatDate;

declare global {
  interface HTMLElementTagNameMap {
    'nile-format-date': NileFormatDate;
  }
}
