/**
 * @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 '../gr-rest-api-interface/gr-rest-api-interface';
import '../../../styles/shared-styles';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
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;
  }
}

@customElement('gr-date-formatter')
export class GrDateFormatter extends TooltipMixin(
  GestureEventListeners(LegacyElementMixin(PolymerElement))
) {
  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})
  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)',
  })
  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 */
  attached() {
    super.attached();
    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();
  }
}
