/**
 * @license
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '../../../styles/shared-styles';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-date-formatter_html';
import {TooltipMixin} from '../../../mixins/gr-tooltip-mixin/gr-tooltip-mixin';
import {property, customElement} from '@polymer/decorators';
import {
  parseDate,
  fromNow,
  isValidDate,
  isWithinDay,
  isWithinHalfYear,
  formatDate,
  utcOffsetString,
  wasYesterday,
} from '../../../utils/date-util';
import {TimeFormat, DateFormat} from '../../../constants/constants';
import {assertNever} from '../../../utils/common-util';
import {Timestamp} from '../../../types/common';
import {appContext} from '../../../services/app-context';

const TimeFormats = {
  TIME_12: 'h:mm A', // 2:14 PM
  TIME_12_WITH_SEC: 'h:mm:ss A', // 2:14:00 PM
  TIME_24: 'HH:mm', // 14:14
  TIME_24_WITH_SEC: 'HH:mm:ss', // 14:14:00
};

const DateFormats = {
  STD: {
    short: 'MMM DD', // Aug 29
    full: 'MMM DD, YYYY', // Aug 29, 1997
  },
  US: {
    short: 'MM/DD', // 08/29
    full: 'MM/DD/YY', // 08/29/97
  },
  ISO: {
    short: 'MM-DD', // 08-29
    full: 'YYYY-MM-DD', // 1997-08-29
  },
  EURO: {
    short: 'DD. MMM', // 29. Aug
    full: 'DD.MM.YYYY', // 29.08.1997
  },
  UK: {
    short: 'DD/MM', // 29/08
    full: 'DD/MM/YYYY', // 29/08/1997
  },
};

interface DateFormatPair {
  short: string;
  full: string;
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-date-formatter': GrDateFormatter;
  }
}

// This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
const base = TooltipMixin(PolymerElement);

@customElement('gr-date-formatter')
export class GrDateFormatter extends base {
  static get template() {
    return htmlTemplate;
  }

  @property({type: String, notify: true})
  dateStr: string | null = null;

  @property({type: Boolean})
  showDateAndTime = false;

  /**
   * When true, the detailed date appears in a GR-TOOLTIP rather than in the
   * native browser tooltip.
   */
  @property({type: Boolean})
  override hasTooltip = false;

  @property({type: Boolean})
  showYesterday = false;

  /**
   * The title to be used as the native tooltip or by the tooltip behavior.
   */
  @property({
    type: String,
    reflectToAttribute: true,
    computed: '_computeFullDateStr(dateStr, _timeFormat, _dateFormat)',
  })
  override title = '';

  /** @type {?{short: string, full: string}} */
  @property({type: Object})
  _dateFormat?: DateFormatPair;

  @property({type: String})
  _timeFormat?: string;

  @property({type: Boolean})
  _relative = false;

  @property({type: Boolean})
  forceRelative = false;

  @property({type: Boolean})
  relativeOptionNoAgo = false;

  private readonly restApiService = appContext.restApiService;

  constructor() {
    super();
  }

  override connectedCallback() {
    super.connectedCallback();
    this._loadPreferences();
  }

  _getUtcOffsetString() {
    return utcOffsetString();
  }

  _loadPreferences() {
    return this._getLoggedIn().then(loggedIn => {
      if (!loggedIn) {
        this._timeFormat = TimeFormats.TIME_24;
        this._dateFormat = DateFormats.STD;
        this._relative = this.forceRelative;
        return;
      }
      return Promise.all([this._loadTimeFormat(), this._loadRelative()]);
    });
  }

  _loadTimeFormat() {
    return this._getPreferences().then(preferences => {
      if (!preferences) {
        throw Error('Preferences is not set');
      }
      this._decideTimeFormat(preferences.time_format);
      this._decideDateFormat(preferences.date_format);
    });
  }

  _decideTimeFormat(timeFormat: TimeFormat) {
    switch (timeFormat) {
      case TimeFormat.HHMM_12:
        this._timeFormat = TimeFormats.TIME_12;
        break;
      case TimeFormat.HHMM_24:
        this._timeFormat = TimeFormats.TIME_24;
        break;
      default:
        assertNever(timeFormat, `Invalid time format: ${timeFormat}`);
    }
  }

  _decideDateFormat(dateFormat: DateFormat) {
    switch (dateFormat) {
      case DateFormat.STD:
        this._dateFormat = DateFormats.STD;
        break;
      case DateFormat.US:
        this._dateFormat = DateFormats.US;
        break;
      case DateFormat.ISO:
        this._dateFormat = DateFormats.ISO;
        break;
      case DateFormat.EURO:
        this._dateFormat = DateFormats.EURO;
        break;
      case DateFormat.UK:
        this._dateFormat = DateFormats.UK;
        break;
      default:
        assertNever(dateFormat, `Invalid date format: ${dateFormat}`);
    }
  }

  _loadRelative() {
    return this._getPreferences().then(prefs => {
      // prefs.relative_date_in_change_table is not set when false.
      this._relative =
        this.forceRelative || !!(prefs && prefs.relative_date_in_change_table);
    });
  }

  _getLoggedIn() {
    return this.restApiService.getLoggedIn();
  }

  _getPreferences() {
    return this.restApiService.getPreferences();
  }

  _computeDateStr(
    dateStr?: Timestamp,
    timeFormat?: string,
    dateFormat?: DateFormatPair,
    relative?: boolean,
    showDateAndTime?: boolean,
    showYesterday?: boolean
  ) {
    if (!dateStr || !timeFormat || !dateFormat) {
      return '';
    }
    const date = parseDate(dateStr);
    if (!isValidDate(date)) {
      return '';
    }
    if (relative) {
      return fromNow(date, this.relativeOptionNoAgo);
    }
    const now = new Date();
    let format = dateFormat.full;
    if (isWithinDay(now, date)) {
      format = timeFormat;
    } else if (showYesterday && wasYesterday(now, date)) {
      return `Yesterday at ${formatDate(date, timeFormat)}`;
    } else {
      if (isWithinHalfYear(now, date)) {
        format = dateFormat.short;
      }
      if (this.showDateAndTime || showDateAndTime) {
        format = `${format} ${timeFormat}`;
      }
    }
    return formatDate(date, format);
  }

  _timeToSecondsFormat(timeFormat: string | undefined) {
    return timeFormat === TimeFormats.TIME_12
      ? TimeFormats.TIME_12_WITH_SEC
      : TimeFormats.TIME_24_WITH_SEC;
  }

  _computeFullDateStr(
    dateStr?: Timestamp,
    timeFormat?: string,
    dateFormat?: DateFormatPair
  ) {
    // Polymer 2: check for undefined
    if ([dateStr, timeFormat].includes(undefined) || !dateFormat) {
      return undefined;
    }

    if (!dateStr) {
      return '';
    }
    const date = parseDate(dateStr);
    if (!isValidDate(date)) {
      return '';
    }
    let format = dateFormat.full + ', ';
    format += this._timeToSecondsFormat(timeFormat);
    return formatDate(date, format) + this._getUtcOffsetString();
  }
}
