import type { Listing } from "@/features/listings/api/listings";

export interface ListingDisplayChip {
  label: string;
  value: string;
}

export interface ListingDisplayResource {
  key: string;
  label: string;
  price: string;
  quantity: number;
  mode: string;
  amount: number;
}

export function getCoinWan(item: Listing) {
  return Math.round(Number(item.haf_coin_amount || 0) / 10000);
}

export function getCoinM(item: Listing) {
  return getCoinWan(item) / 100;
}

export function formatListingCode(item: Listing) {
  return `SP${String(item.id).padStart(6, "0")}`;
}

export function formatHafCoinM(amountWan: number) {
  const amountM = amountWan / 100;
  const rounded = Math.round(amountM * 10) / 10;
  return `${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}M`;
}

export function getListingDisplayPrice(item: Listing) {
  return Number(item.price || 0);
}

export function getListingRentPrice(item: Listing) {
  const buyerCoinBasePrice = readPriceBreakdownNumber(item, "buyer_coin_base_price");
  if (buyerCoinBasePrice > 0) return roundMoney(buyerCoinBasePrice);
  return Math.max(0, roundMoney(getListingDisplayPrice(item) - getListingConsumablePrice(item)));
}

export function getListingConsumablePrice(item: Listing) {
  const consumablePrice = readPriceBreakdownNumber(item, "consumable_price");
  if (consumablePrice > 0) return roundMoney(consumablePrice);
  return getListingResources(item).reduce((sum, resource) => sum + resource.amount, 0);
}

export function getListingSellerPrice(item: Listing) {
  const priceBreakdown = item.asset_summary?.price_breakdown;
  if (typeof priceBreakdown === "object" && priceBreakdown !== null) {
    const price = readUnknownNumber((priceBreakdown as Record<string, unknown>).seller_total_price);
    if (price > 0) return price;
  }
  return getListingDisplayPrice(item);
}

export function getRatioValue(item: Listing) {
  const ratio = readAssetNumber(item, "publish_ratio");
  if (ratio > 0) return ratio;
  const price = getListingDisplayPrice(item);
  if (price <= 0) return 0;
  return getCoinWan(item) / price;
}

export function formatRatio(item: Listing) {
  const ratio = getRatioValue(item);
  return ratio > 0 ? `1:${formatRatioNumber(ratio)}` : "--";
}

export function getValuePerYuanText(item: Listing) {
  return formatRatio(item);
}

export function getLoginMethod(item: Listing) {
  return item.login_platform.trim();
}

export function getServerRegion(item: Listing) {
  return item.server_region.trim();
}

export function getListingTitle(item: Listing) {
  const parts = [
    `纯币${formatHafCoinM(getCoinWan(item))}`,
    formatInsuranceSlotText(readAssetString(item, "season_insurance")),
    formatLevelShort(readAssetString(item, "stamina_level"), "体"),
    formatLevelShort(readAssetString(item, "load_level"), "负"),
    formatResourceShort(item, "armor6", "六甲"),
    formatResourceShort(item, "helmet6", "六头"),
    ...getSkinNames(item).slice(0, 4),
  ].filter(Boolean);
  return parts.join("/");
}

export function getListingSubtitle(item: Listing) {
  return getValuePerYuanText(item);
}

export function getListingChips(item: Listing): ListingDisplayChip[] {
  const totalAsset = readAssetNumber(item, "total_asset_wan");
  const chips: ListingDisplayChip[] = [
    { label: "哈夫币", value: formatHafCoinM(getCoinWan(item)) },
    { label: "保险格数", value: readAssetString(item, "season_insurance") },
    { label: "体力", value: readAssetString(item, "stamina_level") },
    { label: "负重", value: readAssetString(item, "load_level") },
    { label: "段位", value: item.rank_level },
  ];
  const awmAmmo = getResourceQuantity(item, "awmAmmo");
  if (awmAmmo > 0) {
    chips.push({ label: "AWM", value: `${awmAmmo}发` });
  }
  if (totalAsset > 0) {
    chips.push({ label: "总资产", value: formatHafCoinM(totalAsset) });
  }
  const online = getOnlineTimeText(item);
  if (online) {
    chips.push({ label: "方便上号", value: online });
  }
  return chips.filter((chip) => chip.value);
}

export function getListingResources(item: Listing): ListingDisplayResource[] {
  const resources = item.asset_summary?.resources;
  if (!Array.isArray(resources)) return [];
  return resources
    .map((resource) => {
      if (typeof resource !== "object" || resource === null) return null;
      const row = resource as Record<string, unknown>;
      return {
        key: typeof row.key === "string" ? row.key : "",
        label: typeof row.label === "string" ? row.label : "",
        price: typeof row.price === "string" ? row.price : "",
        quantity: readUnknownNumber(row.quantity),
        mode: typeof row.mode === "string" ? row.mode : "",
        amount:
          row.mode === "收费"
            ? roundMoney(readUnknownNumber(row.quantity) * readUnitPrice(typeof row.price === "string" ? row.price : ""))
            : 0,
      };
    })
    .filter((resource): resource is ListingDisplayResource => {
      return Boolean(resource?.key && resource.label && resource.quantity > 0);
    });
}

export function getResourceQuantity(item: Listing, resourceKey: string) {
  return getListingResources(item).find((resource) => resource.key === resourceKey)?.quantity || 0;
}

export function hasGiftResources(item: Listing) {
  return getListingResources(item).some((resource) => resource.mode === "赠送");
}

export function hasAcceleratedSaleRatio(item: Listing) {
  if (item.is_accelerated_sale) return true;

  const priceBreakdown = item.asset_summary?.price_breakdown;
  if (typeof priceBreakdown !== "object" || priceBreakdown === null) return false;

  const row = priceBreakdown as Record<string, unknown>;
  const referenceRatio = readUnknownNumber(row.seller_reference_ratio);
  const sellerRatio = readUnknownNumber(row.seller_ratio);
  const acceleratedRatio = readUnknownNumber(row.accelerated_sale_ratio);

  if (referenceRatio <= 0) return false;
  return sellerRatio > referenceRatio || acceleratedRatio > referenceRatio;
}

export function getSkinGroup(item: Listing, groupKey: string) {
  const skinGroups = item.asset_summary?.skin_groups;
  if (
    typeof skinGroups !== "object" ||
    skinGroups === null ||
    !Array.isArray((skinGroups as Record<string, unknown>)[groupKey])
  ) {
    return [];
  }
  return ((skinGroups as Record<string, unknown>)[groupKey] as unknown[]).filter(
    (skin): skin is string => typeof skin === "string"
  );
}

export function getSkinNames(item: Listing) {
  const skinGroups = item.asset_summary?.skin_groups;
  if (typeof skinGroups !== "object" || skinGroups === null) return [];
  return Object.values(skinGroups as Record<string, unknown>)
    .flatMap((group) => (Array.isArray(group) ? group : []))
    .filter((skin): skin is string => typeof skin === "string");
}

export function assetRegions(item: Listing) {
  const regions = item.asset_summary?.common_regions;
  return Array.isArray(regions)
    ? regions.filter((region): region is string => typeof region === "string")
    : [];
}

export function getOnlineTimeText(item: Listing) {
  const onlineTime = item.asset_summary?.online_time;
  if (typeof onlineTime !== "object" || onlineTime === null) return "";
  const start = (onlineTime as Record<string, unknown>).start;
  const end = (onlineTime as Record<string, unknown>).end;
  if (typeof start !== "string" || typeof end !== "string" || !start || !end) return "";
  if (start === "全天" || end === "全天" || (start === "00:00" && end === "23:59")) return "全天";
  return `${start.replace(":00", "")}-${end.replace(":00", "")}点`;
}

export function getDailyLoss(item: Listing) {
  const dailyLossM = getDailyLossM(item);
  return dailyLossM > 0 ? `${formatCompactNumber(dailyLossM)}M` : "";
}

export function getDailyLossM(item: Listing) {
  const configuredLoss = readAssetNumber(item, "daily_loss_m");
  if (configuredLoss > 0) return configuredLoss;

  const coinWan = getCoinWan(item);
  if (coinWan >= 30000) return 30;
  if (coinWan >= 10000) return 20;
  return 10;
}

export function getEstimatedRentalDays(item: Listing) {
  const coinM = getCoinM(item);
  const dailyLossM = getDailyLossM(item);
  if (coinM <= 0 || dailyLossM <= 0) return 0;
  return coinM / dailyLossM;
}

export function formatEstimatedRentalDuration(item: Listing) {
  const days = getEstimatedRentalDays(item);
  if (days <= 0) return "--";
  return `${Math.max(1, Math.round(days))}天`;
}

export function readAssetString(item: Listing, key: string) {
  const value = item.asset_summary?.[key];
  return typeof value === "string" ? value : "";
}

export function readAssetNumber(item: Listing, key: string) {
  return readUnknownNumber(item.asset_summary?.[key]);
}

function readUnknownNumber(value: unknown) {
  if (typeof value === "number") return value;
  if (typeof value === "string" && value.trim()) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : 0;
  }
  return 0;
}

function readPriceBreakdownNumber(item: Listing, key: string) {
  const priceBreakdown = item.asset_summary?.price_breakdown;
  if (typeof priceBreakdown !== "object" || priceBreakdown === null) return 0;
  return readUnknownNumber((priceBreakdown as Record<string, unknown>)[key]);
}

function readUnitPrice(priceText: string) {
  const normalized = priceText.replace(/，/g, ",").trim();
  const fractionMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元\s*\/\s*(\d+(?:\.\d+)?)/);
  if (fractionMatch) {
    const amount = Number(fractionMatch[1]);
    const count = Number(fractionMatch[2]);
    return count > 0 ? amount / count : 0;
  }
  const singleMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元/);
  return singleMatch ? Number(singleMatch[1]) : 0;
}

function formatInsuranceSlotText(value: string) {
  const parts = value.split("*").map((item) => Number(item));
  const rows = parts[0] || 0;
  const cols = parts[1] || 0;
  if (!Number.isFinite(rows) || !Number.isFinite(cols) || rows <= 0 || cols <= 0) {
    return value;
  }
  return `${rows * cols}格`;
}

function formatLevelShort(value: string, suffix: string) {
  const level = value.match(/\d+/)?.[0];
  return level ? `${level}${suffix}` : value;
}

function formatResourceShort(item: Listing, key: string, label: string) {
  const quantity = getResourceQuantity(item, key);
  return quantity > 0 ? `${quantity}${label}` : "";
}

function roundMoney(value: number) {
  return Math.round(value * 100) / 100;
}

function formatRatioNumber(value: number) {
  const rounded = roundMoney(value);
  return rounded.toFixed(1);
}

function formatCompactNumber(value: number) {
  const rounded = Math.round(value * 10) / 10;
  return Number.isInteger(rounded) ? `${rounded}` : rounded.toFixed(1);
}
