/**
 * Copyright IBM Corp. 2016, 2025
 * SPDX-License-Identifier: BUSL-1.1
 */

import { action } from '@ember/object';
import { service } from '@ember/service';
import { waitFor } from '@ember/test-waiters';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { parseAPITimestamp } from 'core/utils/date-formatters';
import { sanitizePath } from 'core/utils/sanitize-path';
import { isSameMonth } from 'date-fns';
import { task } from 'ember-concurrency';

/**
 * @module ClientsPageHeader
 * ClientsPageHeader components are used to render a header and check for export capabilities before rendering an export button.
 *
 * @example
 * ```js
 * <Clients::PageHeader @startTimestamp="2022-06-01T23:00:11.050Z" @endTimestamp="2022-12-01T23:00:11.050Z" @namespace="foo" @upgradesDuringActivity={{array (hash version="1.10.1" previousVersion="1.9.1" timestampInstalled= "2021-11-18T10:23:16Z") }} />
 * ```
 * @param {string} [billingStartTime] - ISO timestamp of billing start date, to be passed to date picker
 * @param {string} [activityTimestamp] -  ISO timestamp created in serializer to timestamp the response to be displayed in page header
 * @param {string} [startTimestamp] - ISO timestamp of start time, to be passed to export request
 * @param {string} [endTimestamp] - ISO timestamp of end time, to be passed to export request
 * @param {number} [retentionMonths = 48] - number of months for historical billing, to be passed to date picker
 * @param {string} [upgradesDuringActivity] - array of objects containing version history upgrade data
 * @param {boolean} [noData = false] - when true, export button will hide regardless of capabilities
 * @param {function} [onChange] - callback when a new date range is saved, to be passed to date picker
 */
export default class ClientsPageHeaderComponent extends Component {
  @service download;
  @service flags;
  @service namespace;
  @service router;
  @service store;
  @service version;

  @tracked canDownload = false;
  @tracked showEditModal = false;
  @tracked showExportModal = false;
  @tracked exportFormat = 'csv';
  @tracked downloadError = '';

  constructor() {
    super(...arguments);
    this.getExportCapabilities();
  }

  get showExportButton() {
    if (this.args.noData === true) return false;
    return this.canDownload;
  }

  @waitFor
  async getExportCapabilities() {
    const ns = this.namespace.path;
    try {
      // selected namespace usually ends in /
      const url = ns
        ? `${sanitizePath(ns)}/sys/internal/counters/activity/export`
        : 'sys/internal/counters/activity/export';
      const cap = await this.store.findRecord('capabilities', url);
      this.canDownload = cap.canSudo;
    } catch (e) {
      // if we can't read capabilities, default to show
      this.canDownload = true;
    }
  }

  get formattedStartDate() {
    if (!this.args.startTimestamp) return null;
    return parseAPITimestamp(this.args.startTimestamp, 'MMMM yyyy');
  }

  get formattedEndDate() {
    if (!this.args.endTimestamp) return null;
    return parseAPITimestamp(this.args.endTimestamp, 'MMMM yyyy');
  }

  get showEndDate() {
    // displays on CSV export modal, no need to display duplicate months and years
    if (!this.args.endTimestamp) return false;
    const startDateObject = parseAPITimestamp(this.args.startTimestamp);
    const endDateObject = parseAPITimestamp(this.args.endTimestamp);
    return !isSameMonth(startDateObject, endDateObject);
  }

  get formattedCsvFileName() {
    const endRange = this.showEndDate ? `-${this.formattedEndDate}` : '';
    const csvDateRange = this.formattedStartDate ? `_${this.formattedStartDate + endRange}` : '';
    const ns = this.namespace.path ? `_${this.namespace.path}` : '';
    return `clients_export${ns}${csvDateRange}`;
  }

  async getExportData() {
    const adapter = this.store.adapterFor('clients/activity');
    const { startTimestamp, endTimestamp } = this.args;
    return adapter.exportData({
      // the API only accepts json or csv
      format: this.exportFormat === 'jsonl' ? 'json' : 'csv',
      start_time: startTimestamp,
      end_time: endTimestamp,
      namespace: this.namespace.path,
    });
  }

  exportChartData = task({ drop: true }, async (filename) => {
    try {
      const contents = await this.getExportData();
      this.download.download(filename, contents, this.exportFormat);
      this.showExportModal = false;
    } catch (e) {
      this.downloadError = e.message;
    }
  });

  @action
  refreshRoute() {
    this.router.refresh(this.router.currentRoute.parent.name);
  }

  @action
  resetModal() {
    this.showExportModal = false;
    this.downloadError = '';
  }

  @action
  setEditModalVisible(visible) {
    this.showEditModal = visible;
  }

  @action
  setExportFormat(evt) {
    const { value } = evt.target;
    this.exportFormat = value;
  }

  // LOCAL TEMPLATE HELPERS
  parseAPITimestamp = (timestamp, format) => {
    return parseAPITimestamp(timestamp, format);
  };
}
