/* eslint-disable no-underscore-dangle */
/*
 * @Author: Maple
 * @Date: 2021-03-22 09:35:02
 * @LastEditors: Do not edit
 * @LastEditTime: 2021-06-18 00:34:01
 * @Description: 全局缓存服务
 */
import { Injectable } from '@angular/core';
import { cacheConf } from '@conf/cache.conf';
import { CacheService } from '@delon/cache';
import { BehaviorSubject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

import { ICacheObj } from '../../interfaces/core/i-cache-obj';
import { EADateUtil } from '../../utils';

@Injectable({
  providedIn: 'root'
})
export class EACacheService {
  // 监听最后操作时间值变化
  private listen$ = new BehaviorSubject<number>(0);
  private listen = this.listen$.asObservable();
  constructor(private service: CacheService) {
    this.listen.pipe(distinctUntilChanged()).subscribe(res => {
      this.set(cacheConf.last_operation_time, res);
    });
  }

  /**
   * @description 设置缓存
   * @param key 缓存键值
   * @param data 缓存数据
   * @param vld 有效时间
   * @param encrypt 是否加密
   */
  set(key: string, data: any, vld: number = 0, encrypt: boolean = false) {
    // 去除缓存数据两侧空格
    if (typeof data === 'string') {
      data = data.trim();
    }
    const cahceObj: ICacheObj = {
      pd: new Date().getTime(),
      data,
      vld,
      encrypt
    };
    if (encrypt) {
      // 加密
      // cahceObj.data = EAEncryptUtil.encryptByEnAES(JSON.stringify(data));
    }
    this.service.set(key, cahceObj);
    // 更新系统最后操作时间
    this.refleshLastOperationTime();
  }

  /**
   * @description 获取缓存
   * @param key 缓存键名
   */
  get(key: string) {
    // 获取缓存对象
    const cacheObj = this.service.getNone<any>(key);
    // 判断是否存在
    if (!cacheObj) {
      // 更新系统最后操作时间
      this.refleshLastOperationTime();
      return null;
    }
    // 判断有效期
    if (cacheObj.vld > 0) {
      // 获取系统最后操作时间
      const last_operation_time: number = this.getLastOperationTime();
      const start = cacheObj.pd > last_operation_time ? cacheObj.pd : last_operation_time;
      const vld: Date = EADateUtil.timestampToDate(start + cacheObj.vld);
      const expired = EADateUtil.dateDiff(vld, new Date()) <= 0;
      if (expired) {
        // 已过期，清除缓存
        this.remove(key);
        // 更新系统最后操作时间
        this.refleshLastOperationTime();
        return null;
      }
    }

    // 判断是否加密
    if (cacheObj.encrypt) {
      // const encryptJson = EAEncryptUtil.deencryptByDeAES(cacheObj.data);
      // 更新系统最后操作时间
      this.refleshLastOperationTime();
      // return JSON.parse(encryptJson);
      return;
    }

    // 更新系统最后操作时间
    this.refleshLastOperationTime();
    return cacheObj.data;
  }

  /**
   * @description 移除缓存
   * @param key 缓存键名
   */
  remove(key: string) {
    this.service.remove(key);
  }

  /**
   * @description 清除所有缓存
   */
  clear(): void {
    this.service.clear();
  }

  /**
   * 刷新系统最后操作时间
   */
  refleshLastOperationTime() {
    this.listen$.next(new Date().getTime());
  }

  /**
   * 获取系统最后操作时间
   */
  private getLastOperationTime(): number {
    // 获取缓存对象
    const cacheObj: ICacheObj = this.service.getNone<ICacheObj>(cacheConf.last_operation_time);
    return cacheObj?.data || 0;
  }
}
