/**
 * H5版本的字段格式化工具函数
 * 基于小程序版本改造，适配H5环境
 */

/**
 * 获取字典翻译 - H5版本
 * @param {string} cbName - 字典名称
 * @param {string|number} value - 值
 * @param {string} cacheKey - 缓存键
 * @param {Map} dictCache - 字典缓存
 * @param {Function} updateCallback - 更新回调函数
 */
const getDictTranslation = async (
  cbName,
  value,
  cacheKey,
  dictCache,
  updateCallback
) => {
  try {
    console.log(`🔍 获取字典翻译 [${cbName}:${value}]`);

    // 使用 loadObjpOpt 接口调用字典
    const result = await request.post(
      "/service?ssServ=loadObjpOpt&objectpickerdropdown1=1",
      {
        objectpickerparam: JSON.stringify({
          input: "false",
          codebook: cbName,
        }),
        objectpickertype: 2, // 2表示获取要回显的一项
        objectpickervalue: value, // 需回显的值
      },
      { loading: false, formData: true }
    );

    console.log(`字典翻译 [${cbName}:${value}] API返回:`, result);

    // 处理返回数据格式：{"result":{"622182":"会议室A"}}
    let translatedValue = value; // 默认返回原值
    if (result && result.data && result.data.result) {
      // 从result对象中根据value查找对应的翻译
      translatedValue = result.data.result[value] || value;
      console.log(`字典翻译结果: ${value} -> ${translatedValue}`);
    }

    dictCache.set(cacheKey, translatedValue);

    // 触发页面更新
    if (updateCallback) {
      updateCallback();
    }
  } catch (error) {
    console.error(`字典翻译失败 [${cbName}:${value}]:`, error);
    dictCache.set(cacheKey, value);
  }
};

/**
 * 格式化字段值（处理字典翻译、日期格式等）- H5版本
 * @param {Object} fieldObj - 字段对象 {field, value}
 * @param {Map} dictCache - 字典缓存
 * @param {Function} getDictTranslationFn - 字典翻译函数
 * @returns {string} 格式化后的值
 */
const formatFieldValue = (fieldObj, dictCache, getDictTranslationFn) => {
  if (!fieldObj || !fieldObj.field || fieldObj.value === undefined) {
    return "";
  }

  const { field, value } = fieldObj;

  // 空值处理
  if (value === null || value === undefined || value === "") {
    return "";
  }

  // 如果字段有字典配置，进行字典翻译
  if (field.cbName) {
    const cacheKey = `${field.cbName}_${value}`;

    // 先从缓存中查找
    if (dictCache.has(cacheKey)) {
      return dictCache.get(cacheKey);
    }

    // 缓存中没有，异步获取翻译
    if (getDictTranslationFn) {
      getDictTranslationFn(field.cbName, value, cacheKey, dictCache);
    }

    // 返回原值作为临时显示
    return value;
  }

  // 时间格式化（优先检查fmt字段）
  if (field.fmt) {
    return h5FormatDate(value, field.fmt);
  }

  // 日期格式化（兼容旧逻辑）
  if (
    field.type === "date" ||
    field.name.toLowerCase().includes("date") ||
    field.name.toLowerCase().includes("time")
  ) {
    return h5FormatDate(value);
  }

  // 数字格式化
  if (field.type === "number" && typeof value === "number") {
    return value.toLocaleString();
  }

  // 布尔值格式化
  if (field.type === "boolean" || typeof value === "boolean") {
    return value ? "是" : "否";
  }

  // 默认返回字符串
  return String(value);
};

/**
 * 规范化日期字符串，兼容异常空白符和乱码分隔符
 * @param {string|Date|number} value - 原始日期值
 * @returns {string} 规范化后的日期字符串
 */
const normalizeDateInput = (value) => {
  if (value === null || value === undefined) return "";

  return (
    String(value)
      // 功能说明：兼容接口里被错误转码的窄空格（如 â€¯PM），避免标题时间无法格式化 by xu 2026-03-06
      .replace(/â€¯/g, " ")
      .replace(/[\u00A0\u1680\u180E\u2000-\u200D\u202F\u205F\u3000]/g, " ")
      .replace(/(\d)(AM|PM)$/i, "$1 $2")
      .replace(/\s+/g, " ")
      .trim()
  );
};

/**
 * 解析特殊日期格式：Jul 4, 2025, 6:00:00 AM
 * @param {string} dateStr - 日期字符串
 * @returns {object|null} 解析后的日期对象或null
 */
const parseSpecialDateFormat = (dateStr) => {
  try {
    const normalizedDateStr = normalizeDateInput(dateStr);

    // 匹配格式：Jul 4, 2025, 6:00:00 AM
    const regex =
      /^(\w{3})\s+(\d{1,2}),\s+(\d{4}),\s+(\d{1,2}):(\d{2}):(\d{2})\s+(AM|PM)$/i;
    const match = normalizedDateStr.match(regex);

    if (!match) return null;

    const [, monthStr, day, year, hour, minute, second, ampmRaw] = match;
    const ampm = String(ampmRaw).toUpperCase();

    // 月份映射
    const months = {
      Jan: 0,
      Feb: 1,
      Mar: 2,
      Apr: 3,
      May: 4,
      Jun: 5,
      Jul: 6,
      Aug: 7,
      Sep: 8,
      Oct: 9,
      Nov: 10,
      Dec: 11,
    };

    const month = months[monthStr];
    if (month === undefined) return null;

    // 处理12小时制
    let hour24 = parseInt(hour);
    if (ampm === "PM" && hour24 !== 12) {
      hour24 += 12;
    } else if (ampm === "AM" && hour24 === 12) {
      hour24 = 0;
    }

    return {
      year: parseInt(year),
      month: month,
      day: parseInt(day),
      hour: hour24,
      minute: parseInt(minute),
      second: parseInt(second),
    };
  } catch (error) {
    console.warn("解析特殊日期格式失败:", dateStr, error);
    return null;
  }
};

/**
 * 格式化日期对象
 * @param {object} dateObj - 日期对象 {year, month, day, hour, minute, second}
 * @param {string} format - 格式字符串
 * @returns {string} 格式化后的字符串
 */
const formatDateObject = (dateObj, format) => {
  const { year, month, day, hour, minute, second } = dateObj;

  return format
    .replace(/YYYY/g, year)
    .replace(/yyyy/g, year)
    .replace(/MM/g, String(month + 1).padStart(2, "0"))
    .replace(/DD/g, String(day).padStart(2, "0"))
    .replace(/dd/g, String(day).padStart(2, "0"))
    .replace(/HH/g, String(hour).padStart(2, "0"))
    .replace(/hh/g, String(hour).padStart(2, "0"))
    .replace(/mm/g, String(minute).padStart(2, "0"))
    .replace(/ss/g, String(second).padStart(2, "0"));
};

/**
 * 增强的日期格式化函数 - H5版本
 * @param {string|Date} date - 日期，支持多种格式如 "Jul 4, 2025, 6:00:00 AM"
 * @param {string} format - 格式，如 'YYYY-MM-DD HH:mm:ss'
 * @returns {string} 格式化后的日期
 */
const h5FormatDate = (date, format = "YYYY-MM-DD HH:mm:ss") => {
  if (!date) return "";

  try {
    const normalizedDate = normalizeDateInput(date);
    console.log(
      `🔧 h5FormatDate 开始处理:`,
      normalizedDate,
      "目标格式:",
      format
    );

    // 手动解析特殊格式：Jul 4, 2025, 6:00:00 AM
    const parseResult = parseSpecialDateFormat(normalizedDate);
    if (parseResult) {
      console.log(`🔧 手动解析成功:`, parseResult);
      const result = formatDateObject(parseResult, format);
      console.log(`✅ 手动格式化结果:`, result);
      return result;
    }

    // 使用 Day.js 解析日期（更强大的日期解析能力）
    if (typeof window !== "undefined" && window.dayjs) {
      const dayObj = window.dayjs(normalizedDate);
      console.log(`🔧 使用 Day.js 解析:`, dayObj.isValid(), dayObj.toString());

      if (dayObj.isValid()) {
        const result = dayObj.format(format);
        console.log(`✅ Day.js 格式化结果:`, result);
        return result;
      }
    }

    // 降级到原生 Date（如果 Day.js 未加载）
    console.log(`🔧 Day.js 未加载，使用原生 Date`);
    const d = new Date(normalizedDate);

    console.log(`🔧 解析后的日期对象:`, d, "是否有效:", !isNaN(d.getTime()));

    // 检查日期是否有效
    if (isNaN(d.getTime())) {
      console.warn("❌ 无效日期格式:", normalizedDate);
      return normalizedDate; // 无效日期返回原值
    }

    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    const hours = String(d.getHours()).padStart(2, "0");
    const minutes = String(d.getMinutes()).padStart(2, "0");
    const seconds = String(d.getSeconds()).padStart(2, "0");

    // 支持多种格式模式
    let result = format
      .replace(/YYYY/g, year)
      .replace(/yyyy/g, year)
      .replace(/MM/g, month)
      .replace(/DD/g, day)
      .replace(/dd/g, day)
      .replace(/HH/g, hours)
      .replace(/hh/g, hours)
      .replace(/mm/g, minutes)
      .replace(/ss/g, seconds);

    console.log(`日期格式化: ${date} -> ${result} (格式: ${format})`);
    return result;
  } catch (error) {
    console.error("日期格式化异常:", date, format, error);
    return date; // 异常时返回原值
  }
};

/**
 * 异步格式化字段值 - 支持字典转换
 * @param {object} fieldData - 字段数据 {field, value}
 * @param {Map} dictCache - 字典缓存
 * @returns {Promise<string>} 格式化后的值
 */
const formatFieldValueAsync = async (fieldData, dictCache) => {
  if (!fieldData || !fieldData.field) {
    return fieldData?.value || "";
  }

  const { field, value } = fieldData;

  // 空值处理
  if (value === null || value === undefined || value === "") {
    return "";
  }

  // 优先处理时间格式化（如果字段有fmt属性）
  if (field.fmt) {
    try {
      console.log(
        `🕐 格式化时间字段 [${field.name}]:`,
        value,
        "格式:",
        field.fmt
      );
      console.log(`🔧 调用 h5FormatDate 前...`);
      const formattedTime = h5FormatDate(value, field.fmt);
      console.log(`🔧 调用 h5FormatDate 后，结果:`, formattedTime);
      console.log(`✅ 时间格式化结果:`, formattedTime);
      return formattedTime;
    } catch (error) {
      console.error("❌ 时间格式化失败:", field.name, value, error);
      // 格式化失败，返回原值
      return value;
    }
  }

  // 如果字段有字典配置，进行字典转换
  if (field.cbName) {
    const cacheKey = `${field.cbName}_${value}`;

    // 先从缓存中查找
    if (dictCache && dictCache.has(cacheKey)) {
      return dictCache.get(cacheKey);
    }

    // 缓存中没有，异步获取翻译
    try {
      const result = await request.post(
        `/service?ssServ=loadObjpOpt&objectpickerdropdown1=1`,
        {
          objectpickerparam: JSON.stringify({
            input: "false",
            codebook: field.cbName,
          }),
          objectpickertype: 2,
          objectpickervalue: value,
        },
        {
          loading: false,
          formData: true,
        }
      );

      if (
        result &&
        result.data &&
        result.data.result &&
        result.data.result[value]
      ) {
        const translatedValue = result.data.result[value];
        // 缓存结果
        if (dictCache) {
          dictCache.set(cacheKey, translatedValue);
        }
        return translatedValue;
      }
    } catch (error) {
      console.warn("字典转换失败:", field.cbName, value, error);
    }

    // 转换失败，返回原值
    return value;
  }

  // 日期格式化
  if (field.type === 3 && field.fmt) {
    return h5FormatDate(value, field.fmt);
  }

  // 数字格式化
  if (field.type === 2 && typeof value === "number") {
    return value.toLocaleString();
  }

  // 默认返回字符串
  return value.toString();
};

/**
 * 获取字典所有选项 - 用于下拉菜单
 * @param {string} cbName - 字典名称
 * @param {Map} dictCache - 字典缓存
 * @returns {Promise<Array>} 选项列表 [{n: '显示名', v: '值'}]
 */
const getDictOptions = async (cbName, dictCache) => {
  const cacheKey = `options_${cbName}`;

  // 检查缓存
  if (dictCache && dictCache.has(cacheKey)) {
    return dictCache.get(cacheKey);
  }

  try {
    console.log(`🔍 获取字典选项 [${cbName}]`);

    const result = await request.post(
      `/service?ssServ=loadObjpOpt&objectpickerdropdown1=1`,
      {
        objectpickerparam: JSON.stringify({
          input: "false",
          codebook: cbName,
        }),
        objectpickertype: 1,
        objectpickersearchAll: 1,
      },
      {
        loading: false,
        formData: true,
      }
    );

    console.log(`字典选项 [${cbName}] API返回:`, result);

    if (result && result.data && result.data.result) {
      const options = Object.entries(result.data.result).map(
        ([value, label]) => ({
          n: label,
          v: value,
        })
      );

      // 缓存结果
      if (dictCache) {
        dictCache.set(cacheKey, options);
      }

      return options;
    }

    return [];
  } catch (error) {
    console.error(`❌ 获取字典选项失败 [${cbName}]:`, error);
    return [];
  }
};

/**
 * 格式化对象列表数据 - 处理API返回的objectList
 * @param {Array} objectList - 原始对象列表
 * @param {Map} dictCache - 字典缓存
 * @returns {Promise<Array>} 格式化后的列表
 */
const formatObjectList = async (objectList, dictCache) => {
  if (!Array.isArray(objectList)) return [];

  const formattedList = [];

  for (const item of objectList) {
    const formattedItem = { ...item };

    // 格式化 first 字段
    if (item.first) {
      formattedItem.firstDisplay = await formatFieldValueAsync(
        item.first,
        dictCache
      );
    } else if (
      item.title &&
      typeof item.title === "object" &&
      item.title.val !== undefined
    ) {
      // 功能说明：兼容 title={val,fmt} 结构，标题字段为日期时间时按 fmt 格式化，避免卡片标题直接显示原始时间串 by xu 2026-03-06
      if (item.title.fmt) {
        formattedItem.firstDisplay = h5FormatDate(
          item.title.val,
          item.title.fmt
        );
      } else {
        formattedItem.firstDisplay =
          item.title.val === undefined || item.title.val === null
            ? ""
            : String(item.title.val);
      }
    } else if (typeof item.title === "string") {
      // 兼容 title 直出字符串结构 by xu 2026-03-03
      formattedItem.firstDisplay = item.title;
    }

    // 格式化 second 字段
    if (item.second) {
      formattedItem.secondDisplay = await formatFieldValueAsync(
        item.second,
        dictCache
      );
    } else {
      // 兼容 abs/desc/summary 结构（移动端接口常见） by xu 2026-03-03
      const secondFallback = item.abs ?? item.desc ?? item.summary;
      if (secondFallback !== undefined && secondFallback !== null) {
        formattedItem.secondDisplay = String(secondFallback);
      }
    }

    // 格式化 third 字段组
    if (item.third && Array.isArray(item.third)) {
      formattedItem.thirdDisplay = [];

      for (const group of item.third) {
        const formattedGroup = [];

        for (const fieldData of group) {
          const displayValue = await formatFieldValueAsync(
            fieldData,
            dictCache
          );
          formattedGroup.push({
            ...fieldData,
            displayValue,
          });
        }

        formattedItem.thirdDisplay.push(formattedGroup);
      }
    } else if (Array.isArray(item.catList)) {
      // 功能说明：兼容 catList 结构，若有 fmt 则按日期格式化，避免列表属性时间字段直接显示 Oracle 原始串 by xu 2026-03-06
      const formattedCatList = [];

      for (const catItem of item.catList) {
        const fieldData = {
          field: {
            desc: String(catItem?.desc || ""),
            fmt: catItem?.fmt || "",
          },
          value: catItem?.val,
        };

        const displayValue = await formatFieldValueAsync(fieldData, dictCache);

        formattedCatList.push({
          field: {
            desc: String(catItem?.desc || ""),
          },
          value: catItem?.val,
          displayValue,
        });
      }

      formattedItem.thirdDisplay = [formattedCatList];
    }

    formattedList.push(formattedItem);
  }

  return formattedList;
};

// 导出到全局
window.H5FieldFormatter = {
  getDictTranslation,
  formatFieldValue,
  formatFieldValueAsync,
  formatDate: h5FormatDate,
  getDictOptions,
  formatObjectList,
};

// 兼容性：也导出为全局函数
window.getDictTranslation = getDictTranslation;
window.formatFieldValue = formatFieldValue;
window.formatFieldValueAsync = formatFieldValueAsync;
window.getDictOptions = getDictOptions;
window.formatObjectList = formatObjectList;

console.log("✅ H5字段格式化工具加载完成");
