// Domain-accurate mock data for KaratScan
// Mirrors the public API shapes: PublicItemSummary / PricingSummary / WeightSummary etc.
// NOTE: monetary/ratio/weight numbers would arrive as strings from the API; we keep
// numbers here and format in the UI layer.

const SAMPLE_TITLES = [
  "14K Yellow Gold Rope Chain Necklace 24in 18.4g — Italy",
  "Vintage 18K Solid Gold Cuban Link Bracelet 8in",
  "10K Gold Diamond Tennis Bracelet 7.25in — 4.2ctw",
  "22K Indian Wedding Bangle Pair — 32.6g Hallmarked",
  "Estate 14K Gold Signet Ring Sz 10 — 12.8g",
  "Solid 18K Yellow Gold Curb Chain 22in — 41.7g",
  "Antique Victorian 9K Rose Gold Locket — 8.9g",
  "Men's 14K White Gold Wedding Band 7mm — 9.2g",
  "Vintage Italian 18K Gold Mariner Chain 20in — 22.1g",
  "Solid 14K Gold Hoop Earrings 30mm — 5.4g Pair",
  "Estate 18K Gold Emerald Cocktail Ring Sz 7",
  "10K Gold Figaro Chain Necklace 26in — 14.8g",
  "18K Gold Byzantine Chain Bracelet 7.5in",
  "Heavy 21K Gold Bangle — 28.4 grams, stamped",
  "14K Gold Herringbone Necklace 18in — 11.2g",
  "24K Pure Gold Baby Bracelet — 5.1g CGT",
  "18K Gold Rolo Chain 16in — weight not stated",
  "Vintage 14K Gold Charm Bracelet w/ 9 charms",
];

// API reference taxonomies (would come from GET /reference/*)
const ITEM_TYPES = ["ring","necklace","bracelet","earrings","pendant","chain","brooch","bangle","pin","watch","charm","anklet","set","other"];
const METALS = ["gold","silver","platinum","palladium","titanium","stainless_steel","brass","copper","other","unknown"];
const KARAT_PURITY = { 8:0.3333, 9:0.375, 10:0.4167, 12:0.50, 14:0.5833, 18:0.75, 20:0.8333, 21:0.875, 22:0.9167, 24:1.0 };
const KARATS = [8,9,10,12,14,18,20,21,22,24];
const CONDITIONS = ["new","like_new","excellent","good","fair","poor"];
const CONDITION_LABEL = { new:"New", like_new:"Like new", excellent:"Excellent", good:"Good", fair:"Fair", poor:"Poor" };
const CONFIDENCE_LEVELS = ["high","medium","low"];
const SORT_OPTIONS = [
  { value:"newest", label:"Newest" },
  { value:"price_to_melt_asc", label:"Best deals" },
  { value:"deal_score_desc", label:"Deal score" },
  { value:"listing_time_desc", label:"Listing time" },
];

const SELLERS = ["midwest_estate_co","goldlinks_nyc","vintage_jewels_ltd","the_karat_room","italianjewelry_direct","pawn_premium_la","estatejeweler99","gold_loop_treasures"];
const LOCATIONS = ["Los Angeles, CA","New York, NY","Miami, FL","Chicago, IL","Brooklyn, NY","Dallas, TX","Boston, MA","Atlanta, GA","Phoenix, AZ"];

// Title builder — keeps title coherent with the item's actual attributes
const GOLD_COLORS = ["Yellow", "White", "Rose", "Two-Tone"];
const TYPE_STYLES = {
  necklace: ["Rope Chain Necklace","Herringbone Necklace","Byzantine Necklace","Figaro Necklace"],
  chain: ["Cuban Link Chain","Mariner Chain","Figaro Chain","Curb Chain","Rope Chain"],
  bracelet: ["Cuban Link Bracelet","Tennis Bracelet","Byzantine Bracelet","Charm Bracelet"],
  bangle: ["Bangle","Wedding Bangle","Hinged Bangle","Bangle Pair"],
  ring: ["Signet Ring","Band Ring","Cocktail Ring","Wedding Band"],
  earrings: ["Hoop Earrings","Stud Earrings","Drop Earrings"],
  pendant: ["Heart Pendant","Cross Pendant","Pavé Pendant","Locket Pendant"],
  brooch: ["Estate Brooch","Floral Brooch"],
  pin: ["Lapel Pin","Stick Pin"],
  watch: ["Dress Watch","Bracelet Watch"],
  charm: ["Charm","Bracelet Charm"],
  anklet: ["Anklet","Chain Anklet"],
  set: ["Jewelry Set","Necklace & Earring Set"],
  other: ["Gold Piece","Estate Lot"],
};
const PREFIXES = ["", "Vintage ", "Estate ", "Antique ", "Solid ", "Designer ", "Heavy "];
const SUFFIXES = ["", " — Italy", " Hallmarked", ", Stamped", " — Estate Find", ""];

function buildTitle(a) {
  const style = pick(TYPE_STYLES[a.itemType] || TYPE_STYLES.other);
  const prefix = pick(PREFIXES);
  const suffix = pick(SUFFIXES);
  const wt = a.totalWeight != null ? ` — ${a.totalWeight}g` : " — weight not stated";
  if (a.isNonGold) {
    const m = a.primaryMetal === "silver" ? "Sterling Silver" : a.primaryMetal.charAt(0).toUpperCase() + a.primaryMetal.slice(1);
    return `${prefix}${m} ${style}${wt}`.trim();
  }
  const highKarat = a.karat >= 21;
  const colorPool = highKarat ? ["Yellow"] : GOLD_COLORS;
  const color = (a.itemType === "ring" || a.itemType === "pendant") && chance(0.4) ? "" : pick(colorPool) + " ";
  let metalWord = "Gold";
  if (a.isPlated) metalWord = "Gold Plated";
  else if (a.isFilled) metalWord = "Gold Filled";
  else if (a.isVermeil) metalWord = "Vermeil";
  return `${prefix}${a.karat}K ${color}${metalWord} ${style}${wt}${suffix}`.replace(/\s+/g, " ").trim();
}

// Tier thresholds on price-to-melt ratio (nested bands; lower ratio = better)
const TIER = {
  offer: { max: 0.80, label: "Offer", blurb: "Deepest discount" },
  deal:  { max: 0.90, label: "Deal",  blurb: "Strong value" },
  steal: { max: 1.10, label: "Steal", blurb: "Below or near melt" },
};
const SPOT_PER_GRAM = 77.42; // USD per gram pure gold (≈ $2,408/oz)

// Reason codes reference (would come from GET /reference/reason-codes)
const REASON_CODES = {
  explicit_gold_weight: { label: "Explicit gold weight", category: "priced",
    tooltip: "Listing stated the gold weight explicitly; melt value is computed directly from the stated weight." },
  clean_total_weight: { label: "Clean total weight", category: "priced",
    tooltip: "No stones present; the listing's total weight is treated as the metal weight." },
  hallmark_confirmed: { label: "Hallmark confirmed", category: "priced",
    tooltip: "A karat hallmark was detected in the listing photos or text." },
  image_scale_estimate: { label: "Weight estimated from photos", category: "review_required",
    tooltip: "Gold weight was inferred from image-scale analysis rather than a stated weight; treat as an estimate." },
  packaging_weight_risk: { label: "Packaging weight risk", category: "risk",
    tooltip: "Listed weight may include packaging; not safe to price as item weight." },
  hollow_requires_review: { label: "Hollow item requires review", category: "review_required",
    tooltip: "Item is hollow; actual gold content is below the nominal weight and the result needs human review." },
  missing_weight: { label: "Missing weight", category: "not_priced",
    tooltip: "Item weight could not be determined from the listing." },
  missing_purity: { label: "Missing purity", category: "not_priced",
    tooltip: "Gold purity (karat) could not be determined." },
  gold_plated_not_priced: { label: "Gold plated — not priced", category: "not_priced",
    tooltip: "Gold-plated items have negligible melt value and are not priced." },
  gold_filled_not_priced: { label: "Gold filled — not priced", category: "not_priced",
    tooltip: "Gold-filled items contain too little gold to price reliably." },
  vermeil_not_priced: { label: "Vermeil — not priced", category: "not_priced",
    tooltip: "Vermeil (gold-plated sterling silver) is not priced as gold." },
  non_gold_not_priced: { label: "Non-gold item — not priced", category: "non_jewelry",
    tooltip: "Primary metal is not gold; KaratScan only prices gold items." },
  stones_present: { label: "Stones deducted", category: "audit",
    tooltip: "Gemstones were detected; their estimated weight was deducted before valuing the gold." },
};

const REASON_CAT_TONE = {
  priced: "live", review_required: "gold", not_priced: "neutral",
  non_jewelry: "neutral", risk: "hot", audit: "info", other: "neutral",
};

function rand(min, max) { return min + Math.random() * (max - min); }
function randi(min, max) { return Math.floor(rand(min, max + 1)); }
function pick(arr) { return arr[randi(0, arr.length - 1)]; }
function chance(p) { return Math.random() < p; }

let _id = 100000;
function nextId() { _id += randi(7, 113); return String(_id); }
function ebayId() { return "3" + randi(10000000, 99999999) + "" + randi(100, 999); }

// derive the tightest tier an item's ratio qualifies for
function tierFor(ratio) {
  if (ratio == null) return null;
  if (ratio <= TIER.offer.max) return "offer";
  if (ratio <= TIER.deal.max) return "deal";
  if (ratio <= TIER.steal.max) return "steal";
  return null;
}
// near-miss = just outside steal band (within +5%)
function isNearMiss(ratio) {
  if (ratio == null) return false;
  return ratio > TIER.steal.max && ratio <= TIER.steal.max * 1.05;
}

function dealScoreFor(ratio) {
  if (ratio == null) return null;
  // map ratio [0.5 .. 1.15] -> score [99 .. 5], higher better
  const s = Math.round((1.15 - ratio) / (1.15 - 0.5) * 94 + 5);
  return Math.max(1, Math.min(99, s));
}

function makeItem(opts = {}) {
  const id = nextId();
  const type = opts.item_type ?? pick(["necklace","bracelet","ring","chain","bangle","earrings","pendant"]);
  const seller = pick(SELLERS);
  const location = pick(LOCATIONS);

  // material posture
  const metalRoll = Math.random();
  const isSolidGold = metalRoll < 0.80;
  const isPlated = metalRoll >= 0.80 && metalRoll < 0.88;
  const isFilled = metalRoll >= 0.88 && metalRoll < 0.93;
  const isVermeil = metalRoll >= 0.93 && metalRoll < 0.96;
  const isNonGold = metalRoll >= 0.96;
  const primaryMetal = isNonGold ? pick(["silver","platinum","brass"]) : "gold";

  const karat = isNonGold ? null : (opts.karat ?? pick([9,10,14,18,21,22,24]));
  const purity = karat ? KARAT_PURITY[karat] : 0;

  // weight basis
  const weightUnknown = opts.needsWeight ?? (isSolidGold && chance(0.12));
  const weightBasis = weightUnknown ? "none" : (chance(0.72) ? "text" : "image");
  const totalWeight = weightUnknown ? null : +(rand(2.4, 48)).toFixed(1);
  const hasStones = chance(0.28);
  const goldWeight = weightUnknown ? null
    : +(totalWeight * (hasStones ? rand(0.78, 0.94) : 1)).toFixed(1);

  // pricing
  let pricingStatus, requiresReview = false, ratio = null, meltValue = null, dealScore = null;
  const reasonCodes = [];
  let weightConfidence = "high", weightRequiresReview = false;
  let overallConfidence = "high";

  if (isNonGold) {
    pricingStatus = "skipped"; reasonCodes.push("non_gold_not_priced");
    overallConfidence = "medium";
  } else if (isPlated) {
    pricingStatus = "skipped_policy"; reasonCodes.push("gold_plated_not_priced");
    overallConfidence = "medium";
  } else if (isFilled) {
    pricingStatus = "skipped_policy"; reasonCodes.push("gold_filled_not_priced");
    overallConfidence = "medium";
  } else if (isVermeil) {
    pricingStatus = "skipped_policy"; reasonCodes.push("vermeil_not_priced");
    overallConfidence = "medium";
  } else if (weightUnknown) {
    pricingStatus = "skipped"; reasonCodes.push("missing_weight");
    overallConfidence = "low";
  } else {
    // priced
    meltValue = +(goldWeight * purity * SPOT_PER_GRAM).toFixed(2);
    ratio = opts.ratio ?? +(rand(0.52, 1.16)).toFixed(2);
    dealScore = dealScoreFor(ratio);

    if (weightBasis === "image") {
      requiresReview = true; weightRequiresReview = true; weightConfidence = chance(0.5) ? "medium" : "low";
      reasonCodes.push("image_scale_estimate");
      overallConfidence = chance(0.5) ? "medium" : "low";
    } else {
      reasonCodes.push(hasStones ? "stones_present" : (chance(0.5) ? "explicit_gold_weight" : "clean_total_weight"));
      weightConfidence = chance(0.7) ? "high" : "medium";
      overallConfidence = chance(0.7) ? "high" : "medium";
    }
    // risk flags
    if (chance(0.10)) { requiresReview = true; weightRequiresReview = true; reasonCodes.push("packaging_weight_risk"); }
    if (type === "bangle" && chance(0.25)) { requiresReview = true; reasonCodes.push("hollow_requires_review"); }
    if (chance(0.2)) reasonCodes.push("hallmark_confirmed");

    pricingStatus = requiresReview ? "priced_review_required" : "priced";
  }

  const price = meltValue != null ? +(meltValue * ratio).toFixed(2) : +(rand(60, 1400)).toFixed(2);
  const shipping = pick([0, 0, 4.99, 6.95, 9.99, 12.5]);
  const allIn = +(price + shipping).toFixed(2);

  const coverage = weightUnknown ? pick(["indexed","enriched"]) : (chance(0.85) ? "parsed" : "enriched");
  const ageMin = opts.ageMin ?? randi(1, 900);

  const title = opts.title ?? buildTitle({ itemType: type, karat, totalWeight, primaryMetal, isNonGold, isPlated, isFilled, isVermeil });

  return {
    id, itemId: ebayId(), title, listingUrl: "#",
    itemType: type, primaryMetal, karat, purity,
    totalWeight, goldWeight, weightBasis, weightConfidence, weightRequiresReview,
    hasStones, isSolidGold, isPlated, isFilled, isVermeil, isNonGold,
    meltValue, ratio, dealScore, pricingStatus, requiresReview, reasonCodes,
    spotPerGram: SPOT_PER_GRAM,
    price, shipping, allIn, currency: "USD",
    overallConfidence, coverage,
    tier: tierFor(ratio), nearMiss: isNearMiss(ratio),
    seller, location,
    sellerFeedbackScore: randi(48, 12480),
    sellerFeedbackPercent: +(rand(96.2, 100)).toFixed(1),
    authenticityGuarantee: chance(0.22),
    bestOffer: chance(0.4), buyItNow: true,
    images: randi(1, 12),
    isSavedByMe: null, // null when anonymous
    ageMin,
    condition: pick(CONDITIONS),
    note: null,
  };
}

// Build a seed set with good tier distribution
function buildSeed(n) {
  const arr = [];
  // guarantee a spread of tiers
  for (let i = 0; i < n; i++) {
    let it;
    const r = i / n;
    if (r < 0.18) it = makeItem({ ratio: +rand(0.55, 0.79).toFixed(2) });       // offers
    else if (r < 0.40) it = makeItem({ ratio: +rand(0.80, 0.90).toFixed(2) });  // deals
    else if (r < 0.66) it = makeItem({ ratio: +rand(0.90, 1.10).toFixed(2) });  // steals
    else if (r < 0.78) it = makeItem({ ratio: +rand(1.11, 1.155).toFixed(2) }); // near-miss
    else if (r < 0.88) it = makeItem({ needsWeight: true });                    // needs weight
    else it = makeItem();                                                        // random
    arr.push(it);
  }
  return arr;
}

const SEED_ITEMS = buildSeed(30);
SEED_ITEMS.sort((a,b) => a.ageMin - b.ageMin);

// Gold spot (GET /gold/spot)
const GOLD_SPOT = {
  pricePerGram: SPOT_PER_GRAM,
  pricePerOz: +(SPOT_PER_GRAM * 31.1035).toFixed(2),
  source: "live",            // live | stale_cache | fallback
  isAuthoritative: true,
  ageSeconds: 42,
  change24h: +0.42,
};

const SAVED_SEARCHES = [
  { id:"s1", name: "Solid 14K+ under melt", count: 12, color: "var(--accent)", crit: "14K,18K,22K · solid · ≤0.90×" },
  { id:"s2", name: "Heavy chains > 20g", count: 7, color: "var(--accent-deep)", crit: "chain · ≥20g · 14K+" },
  { id:"s3", name: "Cuban link 18K offers", count: 2, color: "var(--hot)", crit: "“cuban” · 18K · ≤0.80×" },
  { id:"s4", name: "22K hallmarked steals", count: 5, color: "var(--info)", crit: "22K · hallmark · ≤1.10×" },
];

// Alert rules (GET /me/alert-rules)
const ALERTS = [
  { id:"a1", name:"Underpriced 18K (≥10g)", enabled:true, version:4,
    criteria:"18K · solid · ≥10g · ≤0.80× melt", channels:["discord"],
    lastTriggered:"4m ago", matches24h:11, tier:"offer" },
  { id:"a2", name:"Heavy 22K bangles", enabled:true, version:2,
    criteria:"22K · bangle · ≥20g · ≤0.90×", channels:["discord","email"],
    lastTriggered:"38m ago", matches24h:6, tier:"deal" },
  { id:"a3", name:"Any chain below melt", enabled:false, version:7,
    criteria:"chain · 14K+ · ≤1.00× · conf ≥ medium", channels:["discord"],
    lastTriggered:"yesterday", matches24h:0, tier:"steal" },
  { id:"a4", name:"24K pure gold drops", enabled:true, version:1,
    criteria:"24K · any type · ≤0.85× · solid only", channels:["web_push"],
    lastTriggered:"2h ago", matches24h:3, tier:"offer" },
];

// Alert history (GET /me/alerts)
const ALERT_HISTORY = [
  { id:"h1", rule:"Underpriced 18K (≥10g)", ruleVersion:4, status:"sent", sentAt:"4m ago", item:"18K Cuban Link Bracelet · 14.2g", ratio:0.74, channel:"discord", attempts:1 },
  { id:"h2", rule:"Heavy 22K bangles", ruleVersion:2, status:"sent", sentAt:"38m ago", item:"22K Wedding Bangle Pair · 32.6g", ratio:0.83, channel:"discord", attempts:1 },
  { id:"h3", rule:"Underpriced 18K (≥10g)", ruleVersion:4, status:"pending", sentAt:"—", item:"18K Curb Chain · 41.7g", ratio:0.71, channel:"email", attempts:2, nextRetry:"in 3m" },
  { id:"h4", rule:"24K pure gold drops", ruleVersion:1, status:"failed", sentAt:"2h ago", item:"24K Baby Bracelet · 5.1g", ratio:0.80, channel:"web_push", attempts:3, error:"endpoint expired" },
  { id:"h5", rule:"Heavy 22K bangles", ruleVersion:2, status:"sent", sentAt:"3h ago", item:"21K Gold Bangle · 28.4g", ratio:0.88, channel:"discord", attempts:1 },
];

// Notification channels (GET /me/notification-channels)
const CHANNELS = [
  { id:"c1", type:"discord_webhook", label:"#deal-hunting", fingerprint:"a91f…7c2", enabled:true, status:"verified" },
  { id:"c2", type:"discord_webhook", label:"Personal DMs", fingerprint:"4b30…e9a", enabled:true, status:"verified" },
  { id:"c3", type:"email", label:"me@example.com", fingerprint:null, enabled:false, status:"coming_soon" },
  { id:"c4", type:"web_push", label:"This browser", fingerprint:null, enabled:false, status:"coming_soon" },
];

const ACTIVITY = [
  { t:"now", text:"Live stream connected", kind:"ok" },
  { t:"12s", text:"New offer · 18K cuban bracelet · 0.74× melt", kind:"match" },
  { t:"1m", text:"Alert fired · Underpriced 18K (≥10g)", kind:"alert" },
  { t:"3m", text:"412 new listings analyzed", kind:"info" },
  { t:"6m", text:"2 deals matched · Heavy 22K bangles", kind:"match" },
  { t:"9m", text:"Gold spot refreshed · $77.42/g", kind:"info" },
  { t:"14m", text:"New steal · 14K herringbone · 1.02× melt", kind:"match" },
];

Object.assign(window, {
  SEED_ITEMS, SAVED_SEARCHES, ALERTS, ALERT_HISTORY, CHANNELS, ACTIVITY, GOLD_SPOT,
  ITEM_TYPES, METALS, KARATS, KARAT_PURITY, CONDITIONS, CONDITION_LABEL,
  CONFIDENCE_LEVELS, SORT_OPTIONS, TIER, REASON_CODES, REASON_CAT_TONE, SPOT_PER_GRAM,
  makeItem, buildSeed, tierFor, isNearMiss, dealScoreFor, rand, randi, pick, chance,
});
