var _excluded = ["extra"];
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import dayjs from 'dayjs';
import { useEffect, useRef } from 'react';
import { sendWarningLog } from '@pisell/utils';

/** localStorage 持久化 key */
var STORAGE_KEY = 'pisell2_eftpos_paylog';

/** 异常关键词，命中时不压缩 */
var ERROR_KEYWORDS = ['失败', '错误', '异常', 'error', 'fail', 'timeout', '超时'];

// ─── 类型定义 ───

/** 压缩后的日志条目 */

/** 持久化到 localStorage 的会话结构 */

// ─── 工具函数 ───

function generateSessionKey() {
  var ts = Date.now();
  var rand = Math.random().toString(36).substring(2, 8);
  return "eft_".concat(ts, "_").concat(rand);
}

/**
 * 判断 title 是否包含异常关键词
 */
function isErrorLog(title) {
  var lower = title.toLowerCase();
  return ERROR_KEYWORDS.some(function (kw) {
    return lower.includes(kw);
  });
}

/**
 * 浅比较两个值是否"相同"（用于 data 去重）
 */
function shallowEqual(a, b) {
  if (a === b) return true;
  if (a == null && b == null) return true;
  if (a == null || b == null) return false;
  try {
    return JSON.stringify(a) === JSON.stringify(b);
  } catch (_unused) {
    return false;
  }
}

/**
 * 将原始日志列表压缩：连续同名非异常日志合并
 */
function compressLogs(logs) {
  if (logs.length === 0) return [];
  var result = [];
  var i = 0;
  while (i < logs.length) {
    var current = logs[i];
    if (isErrorLog(current.t)) {
      result.push({
        t: current.t,
        ts: current.ts,
        d: current.d
      });
      i++;
      continue;
    }
    var j = i + 1;
    while (j < logs.length && logs[j].t === current.t && !isErrorLog(logs[j].t)) {
      j++;
    }
    var count = j - i;
    if (count === 1) {
      result.push({
        t: current.t,
        ts: current.ts,
        d: current.d
      });
    } else {
      var last = logs[j - 1];
      var entry = {
        t: current.t,
        ts: current.ts,
        count: count,
        lastTs: last.ts
      };
      if (current.d !== undefined) entry.d = current.d;
      if (!shallowEqual(current.d, last.d) && last.d !== undefined) {
        entry.lastD = last.d;
      }
      result.push(entry);
    }
    i = j;
  }
  return result;
}

// ─── PayLog 单例类 ───
var PayLog = /*#__PURE__*/function () {
  function PayLog() {
    _classCallCheck(this, PayLog);
    _defineProperty(this, "sessionKey", null);
    _defineProperty(this, "context", {});
    _defineProperty(this, "logs", []);
    _defineProperty(this, "startTime", 0);
    _defineProperty(this, "flushed", false);
  }
  _createClass(PayLog, [{
    key: "init",
    value:
    /**
     * 初始化一次交易会话
     * - 生成唯一 sessionKey
     * - 恢复上报 localStorage 中残留的旧日志
     * - 接受部分 context（后续可通过 setContext 补充）
     */
    function init(context) {
      try {
        this.recoverOrphanedLogs();
        this.sessionKey = generateSessionKey();
        this.context = context || {};
        this.logs = [];
        this.startTime = Date.now();
        this.flushed = false;
        this.log('PayLog 初始化', context);
      } catch (error) {
        console.error('PayLog init error:', error);
      }
    }

    /**
     * 补充/更新上下文信息
     * 新值覆盖旧值，extra 做浅合并
     */
  }, {
    key: "setContext",
    value: function setContext(partial) {
      if (!this.sessionKey) return;
      var extra = partial.extra,
        rest = _objectWithoutProperties(partial, _excluded);
      Object.assign(this.context, rest);
      if (extra) {
        var _this$context;
        this.context.extra = _objectSpread(_objectSpread({}, ((_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.extra) || {}), extra || {});
      }
      this.persistToStorage();
    }

    /**
     * 记录一条日志
     */
  }, {
    key: "log",
    value: function log(title, data) {
      if (!this.sessionKey) {
        console.warn('PayLog: 未初始化，日志将被忽略 -', title);
        return;
      }
      var entry = {
        t: title,
        ts: dayjs().format('HH:mm:ss.SSS')
      };
      if (data !== undefined) {
        entry.d = data;
      }
      this.logs.push(entry);
      this.persistToStorage();
    }

    /**
     * 上报日志到飞书并清理 localStorage
     */
  }, {
    key: "flush",
    value: function flush(customTitle) {
      if (this.flushed || !this.sessionKey) return;
      this.flushed = true;
      try {
        var elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
        var compressed = compressLogs(this.logs);
        var _this$context2 = this.context,
          paymentType = _this$context2.paymentType,
          mode = _this$context2.mode,
          orderId = _this$context2.orderId;
        var title = customTitle || "[EFTPOS] ".concat(paymentType || 'Unknown', "-").concat(mode || 'unknown', "-").concat(orderId || 'Unknown');
        var content = this.buildContent(compressed, elapsed);
        sendWarningLog({
          title: title,
          content: content
        });
        this.removeFromStorage(this.sessionKey);
      } catch (error) {
        console.error('PayLog flush error:', error);
      } finally {
        // 无论上报成功与否，清空 sessionKey，防止 flush 后的 log() 调用
        // 将僵尸日志重新写回 localStorage，被下次 init() 误判为孤儿 session
        this.sessionKey = null;
      }
    }

    /**
     * flush + 重置内部状态
     */
  }, {
    key: "destroy",
    value: function destroy() {
      this.flush();
      this.sessionKey = null;
      this.context = {};
      this.logs = [];
      this.startTime = 0;
      this.flushed = false;
    }

    // ─── 私有方法 ───

    /**
     * 构建 sendWarningLog 所需的 content 数组
     */
  }, {
    key: "buildContent",
    value: function buildContent(compressed, elapsed) {
      var ctx = this.context;
      return [{
        key: 'sessionKey',
        value: this.sessionKey || ''
      }, {
        key: '发起时间',
        value: dayjs(this.startTime).format('YYYY-MM-DD HH:mm:ss')
      }, {
        key: '交易号',
        value: String(ctx.transactionNumber || '未知')
      }, {
        key: '订单ID',
        value: String(ctx.orderId || '未知')
      }, {
        key: '设备ID',
        value: String(ctx.deviceId || '未知')
      }, {
        key: '支付类型',
        value: String(ctx.paymentType || '未知')
      }, {
        key: '模式',
        value: String(ctx.mode || '未知')
      }, {
        key: '渠道',
        value: String(ctx.channel || '未知')
      }, {
        key: '总耗时',
        value: "".concat(elapsed, "s")
      },
      // { key: '日志条数(原始/压缩)', value: `${this.logs.length}/${compressed.length}` },
      {
        key: '时间线',
        value: JSON.stringify(compressed)
      }];
    }

    /**
     * 持久化当前会话到 localStorage
     */
  }, {
    key: "persistToStorage",
    value: function persistToStorage() {
      if (!this.sessionKey) return;
      try {
        var all = this.getAllSessions();
        all[this.sessionKey] = {
          sessionKey: this.sessionKey,
          context: this.context,
          logs: this.logs,
          startTime: this.startTime
        };
        localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
      } catch (error) {
        console.error('PayLog persist error:', error);
      }
    }

    /**
     * 从 localStorage 移除指定 session
     */
  }, {
    key: "removeFromStorage",
    value: function removeFromStorage(key) {
      try {
        var all = this.getAllSessions();
        delete all[key];
        if (Object.keys(all).length === 0) {
          localStorage.removeItem(STORAGE_KEY);
        } else {
          localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
        }
      } catch (error) {
        console.error('PayLog removeFromStorage error:', error);
      }
    }

    /**
     * 获取 localStorage 中所有 session
     */
  }, {
    key: "getAllSessions",
    value: function getAllSessions() {
      try {
        var raw = localStorage.getItem(STORAGE_KEY);
        if (!raw) return {};
        return JSON.parse(raw);
      } catch (_unused2) {
        return {};
      }
    }

    /**
     * 恢复上报 localStorage 中残留的旧日志（崩溃/异常退出场景）
     */
  }, {
    key: "recoverOrphanedLogs",
    value: function recoverOrphanedLogs() {
      try {
        var all = this.getAllSessions();
        var keys = Object.keys(all);
        if (keys.length === 0) return;
        for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
          var key = _keys[_i];
          var session = all[key];
          try {
            var elapsed = ((Date.now() - session.startTime) / 1000).toFixed(1);
            var compressed = compressLogs(session.logs);
            var ctx = session.context;
            var title = "[PRE][EFTPOS] ".concat(ctx.paymentType || '未知支付', "-").concat(ctx.mode || '未知模式', "-").concat(ctx.orderId || '未知订单ID');
            var content = [{
              key: 'sessionKey',
              value: session.sessionKey
            }, {
              key: '发起时间',
              value: dayjs(session.startTime).format('YYYY-MM-DD HH:mm:ss')
            }, {
              key: '交易号',
              value: String(ctx.transactionNumber || '未知')
            }, {
              key: '订单ID',
              value: String(ctx.orderId || '未知')
            }, {
              key: '设备ID',
              value: String(ctx.deviceId || '未知')
            }, {
              key: '支付类型',
              value: String(ctx.paymentType || '未知')
            }, {
              key: '模式',
              value: String(ctx.mode || '未知')
            }, {
              key: '总耗时',
              value: "".concat(elapsed, "s")
            }, {
              key: '日志条数(原始/压缩)',
              value: "".concat(session.logs.length, "/").concat(compressed.length)
            }, {
              key: '时间线',
              value: JSON.stringify(compressed)
            }];
            sendWarningLog({
              title: title,
              content: content
            });
            this.removeFromStorage(key);
          } catch (err) {
            console.error("PayLog: \u6062\u590D\u4E0A\u62A5\u5931\u8D25 (".concat(key, "):"), err);
            this.removeFromStorage(key);
          }
        }
      } catch (error) {
        console.error('PayLog recoverOrphanedLogs error:', error);
      }
    }
  }], [{
    key: "getInstance",
    value: function getInstance() {
      if (!PayLog.instance) {
        PayLog.instance = new PayLog();
      }
      return PayLog.instance;
    }
  }]);
  return PayLog;
}(); // ─── 单例导出 ───
_defineProperty(PayLog, "instance", void 0);
var payLog = PayLog.getInstance();
export default payLog;

// ─── usePayLog Hook ───

/**
 * 在根组件中使用，管理 PayLog 生命周期
 * - mount 时 init（+ 恢复上报残留日志）
 * - unmount 时 flush
 */
export function usePayLog(context) {
  var initialized = useRef(false);
  useEffect(function () {
    if (!initialized.current) {
      initialized.current = true;
      payLog.init(context);
    }
    return function () {
      payLog.log('流程结束，上报日志');
      payLog.flush();
    };
  }, []);
  return {
    log: function log(title, data) {
      return payLog.log(title, data);
    },
    setContext: function setContext(partial) {
      return payLog.setContext(partial);
    }
  };
}