/*
 * Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
 * 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 { LogDomain, LogHelper } from '@ohos/basicutils';
import { AbstractObserverManager, ObserverAble } from '../base/AbstractObserverManager';
import { DeviceHelper } from '@ohos/frameworkwrapper';
import Queue from '@ohos.util.Queue';
import display from '@ohos.display';

const TAG = 'FrequentFoldManager';

const log: LogHelper = LogHelper.getLogHelper(LogDomain.KG, TAG);

const FOLD_LIMIT: number = 4;

const FOLD_LIMIT_INTERVAL: number = 10 * 1000;


/**
 * 频繁折叠开合状态变化监听
 */
export interface FrequentFoldChangeListener extends ObserverAble {
  /**
   * 频繁开合状态变化
   *
   * @param isFrequentFold 用户是否正在频繁折叠开合
   */
  onFrequentFoldChange(isFrequentFold: boolean): void;
}

/**
 * 频繁折叠管理,小折叠特有
 */
export class FrequentFoldManager extends AbstractObserverManager<FrequentFoldChangeListener> {
  private static sInstance: FrequentFoldManager;
  /**
   * 用户是否正在频繁开合(10s内折叠开合4次以上)
   */
  private _isFrequentFold: boolean = false;

  private _isFoldStatus: display.FoldStatus = display.FoldStatus.FOLD_STATUS_UNKNOWN;

  private _lastFoldTime: number = 0;

  private _intervalList: Queue<number> = new Queue();

  private _resetTimeoutId: number = 0;

  private foldStatusChangeCallback: Callback<display.FoldStatus> = (newFoldStatus: display.FoldStatus): void => {
    if (this._isFoldStatus === newFoldStatus) {
      return;
    }
    this._isFoldStatus = newFoldStatus;
    if (newFoldStatus !== display.FoldStatus.FOLD_STATUS_FOLDED &&
      newFoldStatus !== display.FoldStatus.FOLD_STATUS_EXPANDED) {
      return;
    }
    this.updateFrequentFoldScene();
  };

  public static getInstance(): FrequentFoldManager {
    if (FrequentFoldManager.sInstance == null) {
      FrequentFoldManager.sInstance = new FrequentFoldManager();
    }
    return FrequentFoldManager.sInstance;
  }

  public get isFrequentFoldChange(): boolean {
    return this._isFrequentFold;
  }

  public set isFrequentFoldChange(isFrequentFold: boolean) {
    if (this._isFrequentFold !== isFrequentFold) {
      log.showWarn(`set isFrequentFoldChange, _isFrequentFold: ${this._isFrequentFold}, isFrequentFold: ${isFrequentFold}`);
      this._isFrequentFold = isFrequentFold;
      this.broadcastDataChange((observer) => observer.onFrequentFoldChange(isFrequentFold));
    }
  }

  /**
   * 折叠开合时触发,更新此时是否处于频繁开合状态
   */
  private updateFrequentFoldScene(): void {
      return;
  }

  private calculateFrequentFoldScene(): boolean {
    if (this._lastFoldTime === 0) {
      this._lastFoldTime = Date.now();
      return false;
    }
    let currentTime = Date.now();
    let interval = currentTime - this._lastFoldTime;
    this._lastFoldTime = currentTime;
    // 新的间隔时间入队, 如果队列已满则队首出队
    if (this._intervalList.length >= FOLD_LIMIT) {
      this._intervalList.pop();
    }
    this._intervalList.add(interval);
    if (this._intervalList.length < FOLD_LIMIT) {
      return false;
    }
    // 获取最近4次开合的间隔总和, 如果小于10s, 认为处于频繁开合状态
    let duration: number = 0;
    this._intervalList.forEach((time) => {
      duration += time;
    });
    log.showInfo(`calculateFrequentFoldScene, length: ${this._intervalList.length}, duration: ${duration}`);
    return duration < FOLD_LIMIT_INTERVAL;
  }

  /**
   * 初始化
   */
  public doInit(): void {
    try {
      display.on('foldStatusChange', this.foldStatusChangeCallback);
    } catch (e) {
      log.showError(`doInit code: ${e?.code}, msg: ${e?.message}`);
    }
  }

  public doRelease(): void {
    try {
      display.off('foldStatusChange', this.foldStatusChangeCallback);
    } catch (e) {
      log.showError(`doRelease code: ${e?.code}, msg: ${e?.message}`);
    }
  }

  public registerObserver(observer: FrequentFoldChangeListener, isCallbackImmediately?: boolean,
    highPriory?: boolean): void {
    super.registerObserver(observer, isCallbackImmediately, highPriory);
    if (isCallbackImmediately) {
      this.broadcastDataChange((observer) => observer.onFrequentFoldChange(this._isFrequentFold));
    }
  }

  protected broadcastDataChange(callback: (observer: FrequentFoldChangeListener) => void): void {
    super.broadcastDataChange(callback);
  }
}