/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {ParsedChangeInfo} from '../types/types';
import {getReason} from '../utils/attention-set-util';
import {readJSONResponsePayload} from '../elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {filterAttentionChangesAfter} from '../utils/service-worker-util';
import {AccountDetailInfo} from '../api/rest-api';
import {
  ServiceWorkerMessageType,
  TRIGGER_NOTIFICATION_UPDATES_MS,
} from '../services/service-worker-installer';
import {
  getServiceWorkerState,
  putServiceWorkerState,
} from './service-worker-indexdb';
import {DashboardType, createDashboardUrl} from '../models/views/dashboard';
import {createChangeUrl} from '../models/views/change';
import {noAwait} from '../utils/async-util';

export class ServiceWorker {
  constructor(
    /* private but used in test */ public ctx: ServiceWorkerGlobalScope
  ) {}

  // private but used in test
  latestUpdateTimestampMs = Date.now();

  allowBrowserNotificationsPreference = false;

  /**
   * We cannot rely on a state in a service worker, because every time
   * service worker starts or stops, new instance is created. So every time
   * there is new instance we load state from indexdb.
   */
  async init() {
    await this.loadState();
    this.ctx.addEventListener('message', e => this.onMessage(e));
    this.ctx.addEventListener('notificationclick', e =>
      this.onNotificationClick(e)
    );
  }

  // private but used in test
  saveState() {
    return putServiceWorkerState({
      latestUpdateTimestampMs: this.latestUpdateTimestampMs,
      allowBrowserNotificationsPreference:
        this.allowBrowserNotificationsPreference,
    });
  }

  private async loadState() {
    const state = await getServiceWorkerState();
    if (state) {
      this.latestUpdateTimestampMs = state.latestUpdateTimestampMs;
      this.allowBrowserNotificationsPreference =
        state.allowBrowserNotificationsPreference;
    }
  }

  private onMessage(e: ExtendableMessageEvent) {
    if (e.data?.type === ServiceWorkerMessageType.TRIGGER_NOTIFICATIONS) {
      e.waitUntil(
        this.showLatestAttentionChangeNotification(
          e.data?.account as AccountDetailInfo | undefined
        )
      );
    } else if (
      e.data?.type === ServiceWorkerMessageType.USER_PREFERENCE_CHANGE
    ) {
      e.waitUntil(
        this.allowBrowserNotificationsPreferenceChanged(
          e.data?.allowBrowserNotificationsPreference as boolean
        )
      );
    }
  }

  private onNotificationClick(e: NotificationEvent) {
    e.notification.close();
    e.waitUntil(this.openWindow(e.notification.data.url));
  }

  async allowBrowserNotificationsPreferenceChanged(preference: boolean) {
    this.allowBrowserNotificationsPreference = preference;
    await this.saveState();
  }

  // private but used in test
  async showLatestAttentionChangeNotification(account?: AccountDetailInfo) {
    // Message always contains account, but we do not throw error.
    if (!account?._account_id) return;
    if (!this.allowBrowserNotificationsPreference) return;
    const latestAttentionChanges = await this.getChangesToNotify(account);
    const numOfChangesToNotifyAbout = latestAttentionChanges.length;
    if (numOfChangesToNotifyAbout === 1) {
      this.showNotificationForChange(latestAttentionChanges[0], account);
    } else if (numOfChangesToNotifyAbout > 1) {
      this.showNotificationForDashboard(numOfChangesToNotifyAbout);
    }
  }

  // Code based on code sample from
  // https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow
  private async openWindow(url?: string) {
    if (!url) return;
    const clientsArr = await this.ctx.clients.matchAll({type: 'window'});
    try {
      let client = clientsArr.find(c => c.url === url);
      if (!client)
        client = (await this.ctx.clients.openWindow(url)) ?? undefined;
      await client?.focus();
    } catch (e) {
      console.error(`Cannot open window about notified change - ${e}`);
    }
  }

  private showNotificationForChange(
    change: ParsedChangeInfo,
    account: AccountDetailInfo
  ) {
    const body = getReason(undefined, account, change);
    const changeUrl = createChangeUrl({
      change,
      usp: 'service-worker-notification',
    });
    // We are adding origin because each notification can have different origin
    // User can have different service workers for different origins/hosts.
    // TODO(milutin): Check if this works properly with getBaseUrl()
    const data = {url: `${self.location.origin}${changeUrl}`};
    const icon = `${self.location.origin}/favicon.ico`;
    this.ctx.registration.showNotification(change.subject, {
      body,
      data,
      icon,
    });
    this.sendReport('notify about 1 change');
  }

  private showNotificationForDashboard(numOfChangesToNotifyAbout: number) {
    const title = `You are in the attention set for ${numOfChangesToNotifyAbout} new changes.`;
    const dashboardUrl = createDashboardUrl({type: DashboardType.USER});
    const data = {url: `${self.location.origin}${dashboardUrl}`};
    const icon = `${self.location.origin}/favicon.ico`;
    this.ctx.registration.showNotification(title, {data, icon});
    this.sendReport(`notify about ${numOfChangesToNotifyAbout} changes`);
  }

  // private but used in test
  async getChangesToNotify(account: AccountDetailInfo) {
    // We throttle polling, since there can be many clients triggerring
    // always only one service worker.
    const durationFromLatestUpdateMS =
      Date.now() - this.latestUpdateTimestampMs;
    if (durationFromLatestUpdateMS < TRIGGER_NOTIFICATION_UPDATES_MS) {
      return [];
    }
    const prevLatestUpdateTimestampMs = this.latestUpdateTimestampMs;
    this.latestUpdateTimestampMs = Date.now();
    await this.saveState();
    noAwait(this.sendReport('polling'));
    const changes = await this.getLatestAttentionSetChanges();
    const latestAttentionChanges = filterAttentionChangesAfter(
      changes,
      account,
      prevLatestUpdateTimestampMs
    );
    return latestAttentionChanges;
  }

  // private but used in test
  async getLatestAttentionSetChanges(): Promise<ParsedChangeInfo[]> {
    // TODO(milutin): Implement more generic query builder
    const response = await fetch(
      '/changes/?O=1000081&S=0&n=25&q=attention%3Aself'
    );

    try {
      // Throws an error if response payload is not prefixed JSON.
      return (await readJSONResponsePayload(response))
        .parsed as unknown as ParsedChangeInfo[];
    } catch (err) {
      if (err instanceof Error) {
        console.warn(
          `Request for latest attention set changes failed. Error: ${err.message}`
        );
      }
      return [];
    }
  }

  /**
   * Send report event to 1 client (last focused one). The client will use
   * gr-reporting service to send event to metric event collectors.
   */
  async sendReport(eventName: string) {
    const clientsArr = await this.ctx.clients.matchAll({type: 'window'});
    const lastFocusedClient = clientsArr?.[0];
    if (!lastFocusedClient) return;

    lastFocusedClient.postMessage({
      type: ServiceWorkerMessageType.REPORTING,
      eventName,
    });
  }
}
