import { resolveCloudtentaclesConfig } from "../../platforms/cloudtentacles/shared.js";
import {
  maskCode as maskCodeValue,
  maskPhone as maskPhoneValue,
} from "../../../utils/masking.js";

export const KUAISHOU_CLOUD_FIXED_VN_KEY = "1";

export type JsonObject = Record<string, any>;

export function isKuaishouCloudTask(task) {
  return String(task?.executor_key || "").trim() === "kuaishou_ct_assisted";
}

export function normalizeKuaishouCloudFlow(value) {
  const source = value && typeof value === "object" ? value : {};
  const binding =
    source.binding && typeof source.binding === "object" ? source.binding : {};
  const role =
    source.role && typeof source.role === "object" ? source.role : {};
  const purchase =
    source.purchase && typeof source.purchase === "object"
      ? source.purchase
      : {};
  const dispatch =
    source.dispatch && typeof source.dispatch === "object"
      ? source.dispatch
      : {};
  const returnNumber =
    source.returnNumber && typeof source.returnNumber === "object"
      ? source.returnNumber
      : {};
  const consume =
    source.consume && typeof source.consume === "object" ? source.consume : {};
  const ticket =
    source.ticket && typeof source.ticket === "object" ? source.ticket : {};

  const roleName = String(role.name || binding.roleName || "").trim();
  const roleId = String(role.rid || binding.roleId || "").trim();
  const bindPreparedAt = binding.bindPreparedAt || null;
  const bindExpiresAt =
    binding.bindExpiresAt ||
    resolveKuaishouCloudBindUrlExpiresAt(bindPreparedAt);

  return {
    ...source,
    configId: String(source.configId || "").trim(),
    internalSkuCode: String(source.internalSkuCode || "").trim(),
    internalSkuName: String(source.internalSkuName || "").trim(),
    ticket: {
      code: String(ticket.code || "").trim(),
      status: String(ticket.status || "pending").trim() || "pending",
      capturedAt: ticket.capturedAt || null,
      capturedBy: ticket.capturedBy || null,
      verifiedAt: ticket.verifiedAt || null,
      oid: String(ticket.oid || "").trim(),
      formToken: String(ticket.formToken || "").trim(),
      leftCount: Number(ticket.leftCount || 0) || 0,
      goodsTitle: String(ticket.goodsTitle || "").trim(),
    },
    binding: {
      prepareStatus:
        String(binding.prepareStatus || "pending").trim() || "pending",
      cloudSourceKey:
        String(binding.cloudSourceKey || "default").trim() || "default",
      cloudSourceKeyFallbacks: normalizeStringArray(
        binding.cloudSourceKeyFallbacks
      ),
      resolvedSourceKey: String(binding.resolvedSourceKey || "").trim(),
      skuId: Number(binding.skuId || 0) || 0,
      skuName: String(binding.skuName || "").trim(),
      vnKey:
        String(binding.vnKey || KUAISHOU_CLOUD_FIXED_VN_KEY).trim() ||
        KUAISHOU_CLOUD_FIXED_VN_KEY,
      vnId: Number(binding.vnId || 0) || 0,
      vnPhone: String(binding.vnPhone || "").trim(),
      bindUrl: String(binding.bindUrl || "").trim(),
      bindPreparedAt,
      bindExpiresAt,
      bindProbeAt: binding.bindProbeAt || null,
      bindProbeStatus: String(binding.bindProbeStatus || "").trim(),
      bindProbeMessage: String(binding.bindProbeMessage || "").trim(),
      roleName,
      roleId,
    },
    role: {
      status:
        String(
          role.status || (roleName || roleId ? "ready" : "pending")
        ).trim() || "pending",
      name: roleName,
      rid: roleId,
      refreshedAt: role.refreshedAt || null,
      errorMessage: String(role.errorMessage || "").trim(),
      rawInfo:
        role.rawInfo && typeof role.rawInfo === "object" ? role.rawInfo : null,
    },
    purchase: {
      autoBuyEnabled: purchase.autoBuyEnabled !== false,
      minAssetReserve: Number(purchase.minAssetReserve || 0) || 0,
      usedKnapsack: purchase.usedKnapsack === true,
      purchaseTriggered: purchase.purchaseTriggered === true,
      assetBefore: Number(purchase.assetBefore || 0) || 0,
      assetAfter: Number(purchase.assetAfter || 0) || 0,
      purchaseAt: purchase.purchaseAt || null,
    },
    dispatch: {
      status: String(dispatch.status || "pending").trim() || "pending",
      dispatchAt: dispatch.dispatchAt || null,
      dispatchBy: dispatch.dispatchBy || null,
      sendType: Number(dispatch.sendType || 0) || 0,
      note: String(dispatch.note || "").trim(),
    },
    returnNumber: {
      status: String(returnNumber.status || "pending").trim() || "pending",
      returnedAt: returnNumber.returnedAt || null,
      returnedBy: returnNumber.returnedBy || null,
      autoReturnEnabled: returnNumber.autoReturnEnabled === true,
    },
    consume: {
      status: String(consume.status || "pending").trim() || "pending",
      shopId: String(consume.shopId || "").trim(),
      shopName: String(consume.shopName || "").trim(),
      autoConsumeEnabled: consume.autoConsumeEnabled === true,
      consumedAt: consume.consumedAt || null,
      errorMessage: String(consume.errorMessage || "").trim(),
    },
    notes: String(source.notes || "").trim(),
  };
}

export function normalizeKuaishouCloudRoleInfo(value) {
  const rawInfo = value && typeof value === "object" ? value : null;
  const nestedBindInfo =
    rawInfo?.sBindInfo && typeof rawInfo.sBindInfo === "object"
      ? rawInfo.sBindInfo
      : null;
  const source = nestedBindInfo || rawInfo;

  return {
    name: String(
      source?.name ||
        source?.roleName ||
        source?.nickname ||
        source?.sRoleName ||
        ""
    ).trim(),
    rid: String(
      source?.rid ||
        source?.roleId ||
        source?.uid ||
        source?.sRoleId ||
        source?.sUserId ||
        ""
    ).trim(),
    rawInfo,
  };
}

export function maskPhone(value) {
  return maskPhoneValue(value);
}

export function maskCode(value) {
  return maskCodeValue(value);
}

export function resolveKuaishouCloudBindUrlExpiresAt(preparedAt) {
  const preparedTime = Date.parse(String(preparedAt || ""));
  if (!Number.isFinite(preparedTime)) {
    return null;
  }

  const config = resolveCloudtentaclesConfig();
  const ttlSeconds = Number(config.bindUrlTtlSeconds || 600);
  return new Date(preparedTime + Math.max(1, ttlSeconds) * 1000).toISOString();
}

export function isKuaishouCloudBindUrlFresh(flow, now = new Date()) {
  const normalizedFlow = normalizeKuaishouCloudFlow(flow);
  if (!normalizedFlow.binding.bindUrl) {
    return false;
  }

  const expiresAt = normalizedFlow.binding.bindExpiresAt;
  if (!expiresAt) {
    return false;
  }

  const expiresTime = Date.parse(String(expiresAt || ""));
  if (!Number.isFinite(expiresTime)) {
    return false;
  }

  return expiresTime > now.getTime();
}

export function normalizeStringArray(value) {
  if (Array.isArray(value)) {
    return value.map((v) => String(v || "").trim()).filter(Boolean);
  }
  if (typeof value === "string") {
    return value
      .split(",")
      .map((v) => v.trim())
      .filter(Boolean);
  }
  return [];
}
