/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import {FlagsService, KnownExperimentId} from './flags/flags';
import {
  areNotificationsEnabled,
  registerServiceWorker,
} from '../utils/worker-util';
import {UserModel} from '../models/user/user-model';
import {AccountDetailInfo} from '../api/rest-api';
import {until} from '../utils/async-util';
import {LifeCycle} from '../constants/reporting';
import {ReportingService} from './gr-reporting/gr-reporting';
import {define} from '../models/dependency';
import {Model} from '../models/base/model';
import {Observable} from 'rxjs';
import {select} from '../utils/observable-util';

/** Type of incoming messages for ServiceWorker. */
export enum ServiceWorkerMessageType {
  TRIGGER_NOTIFICATIONS = 'TRIGGER_NOTIFICATIONS',
  USER_PREFERENCE_CHANGE = 'USER_PREFERENCE_CHANGE',
  REPORTING = 'REPORTING',
}

export const TRIGGER_NOTIFICATION_UPDATES_MS = 5 * 60 * 1000;

export const serviceWorkerInstallerToken = define<ServiceWorkerInstaller>(
  'service-worker-installer'
);

/**
 * Service worker state:
 * initialized - True when service worker registered and event listeners added.
 *             - False otherwise
 * shouldShowPrompt - True when user didn't make decision about notifications
 *                  - False otherwise
 */
export interface ServiceWorkerInstallerState {
  initialized: boolean;
  shouldShowPrompt: boolean;
}

export class ServiceWorkerInstaller extends Model<ServiceWorkerInstallerState> {
  readonly initialized$: Observable<Boolean | undefined> = select(
    this.state$,
    state => state.initialized
  );

  readonly shouldShowPrompt$: Observable<Boolean | undefined> = select(
    this.initialized$,
    _ => this.shouldShowPrompt()
  );

  // Internal state, it's exposed in initialized$
  private initialized = false;

  account?: AccountDetailInfo;

  allowBrowserNotificationsPreference?: boolean;

  constructor(
    private readonly flagsService: FlagsService,
    private readonly reportingService: ReportingService,
    private readonly userModel: UserModel
  ) {
    super({initialized: false, shouldShowPrompt: false});
    if (!this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS)) {
      return;
    }
    this.userModel.account$.subscribe(acc => (this.account = acc));
    this.userModel.preferences$.subscribe(prefs => {
      if (
        this.allowBrowserNotificationsPreference !==
        prefs.allow_browser_notifications
      ) {
        this.allowBrowserNotificationsPreference =
          prefs.allow_browser_notifications;
        // flag can disable notifications similar to user setting
        navigator.serviceWorker.controller?.postMessage({
          type: ServiceWorkerMessageType.USER_PREFERENCE_CHANGE,
          allowBrowserNotificationsPreference:
            this.allowBrowserNotificationsPreference &&
            this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS),
        });
      }
    });
    Promise.all([
      until(this.userModel.account$, account => !!account),
      until(
        this.userModel.preferences$,
        prefs => !!prefs.allow_browser_notifications
      ),
    ]).then(() => {
      this.init();
    });
  }

  private async init() {
    if (this.initialized) return;
    if (!this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS)) {
      return;
    }
    if (!this.areNotificationsEnabled()) return;

    if (!('serviceWorker' in navigator)) {
      console.error('Service worker API not available');
      return;
    }
    await registerServiceWorker('/service-worker.js');
    const permission = Notification.permission;
    this.reportingService.reportLifeCycle(LifeCycle.NOTIFICATION_PERMISSION, {
      permission,
    });
    if (this.isPermitted(permission)) this.startTriggerTimer();
    this.initialized = true;
    this.updateState({initialized: true});
    // Assumption: service worker will send event only to 1 client.
    navigator.serviceWorker.onmessage = event => {
      if (event.data?.type === ServiceWorkerMessageType.REPORTING) {
        this.reportingService.reportLifeCycle(LifeCycle.SERVICE_WORKER_UPDATE, {
          eventName: event.data.eventName as string | undefined,
        });
      }
    };
  }

  // private, used in test
  shouldShowPrompt(): boolean {
    if (!this.initialized) return false;
    if (!this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS)) {
      return false;
    }
    if (!this.areNotificationsEnabled()) return false;
    return Notification.permission === 'default';
  }

  public async requestPermission() {
    const permission = await Notification.requestPermission();
    this.reportingService.reportLifeCycle(LifeCycle.NOTIFICATION_PERMISSION, {
      requested: true,
      permission,
    });
    if (this.isPermitted(permission)) this.startTriggerTimer();
  }

  areNotificationsEnabled() {
    // Push Notification developer can have notification enabled even if they
    // are disabled for this.account.
    if (
      !this.flagsService.isEnabled(
        KnownExperimentId.PUSH_NOTIFICATIONS_DEVELOPER
      ) &&
      !areNotificationsEnabled(this.account)
    ) {
      return false;
    }

    return this.allowBrowserNotificationsPreference;
  }

  /**
   * Every 5 minutes, we trigger service-worker to get
   * latest updates in attention set and service-worker will create
   * notifications.
   */
  startTriggerTimer() {
    setTimeout(() => {
      this.startTriggerTimer();
      navigator.serviceWorker.controller?.postMessage({
        type: ServiceWorkerMessageType.TRIGGER_NOTIFICATIONS,
        account: this.account,
      });
    }, TRIGGER_NOTIFICATION_UPDATES_MS);
  }

  isPermitted(permission: NotificationPermission) {
    return permission === 'granted';
  }
}
