-- Farm_Seeds.lua
-- What Farm? :: Curated seed farms
--
-- Seeds are inserted into the DB once (deduped by seedKey) and also act as the
-- starter farm pool.
--
-- Keep shipped seed identities stable.
--   - Display names may change over time.
--   - If a shipped name changes, set an explicit seedKey to preserve identity.
--
-- Aim/focus are normalized for both HelpWindow and MainWindow/session capture.
--
-- Optional rich fields supported per seed:
--   description          Longform detail text
--   coords               { Coord(x, y, label, note), ... }
--   expected             Expected result string, ex: "13,000g 0s 0c"
--   image                Optional texture path / atlas key / file ID for this farm
--   fallbackPreviewItems Seed-only preview items used when no farm history exists
--   requirements         { "Skinning", "Druid" }
--   targets              { "Dampscale Basilisk", "Basilisk" }
--   tips                 { "Pull clockwise.", "Skin before moving." }
--   route                {
--                          kind = "loop" | "line" | "hub",
--                          label = "North basilisk loop",
--                          waypoints = { Coord(...), ... },
--                          steps = { "Start here", "Rotate south", ... },
--                        }

local ADDON_NAME, ns = ...
local WF = ns.WF

WF.FARM_SEED_VERSION = 6

local function Trim(s)
  if type(s) ~= "string" then
    return ""
  end
  return (s:gsub("^%s+", ""):gsub("%s+$", ""))
end

local function CopyStringList(list)
  if type(list) ~= "table" then
    return {}
  end

  local out = {}
  for i = 1, #list do
    local value = Trim(tostring(list[i] or ""))
    if value ~= "" then
      out[#out + 1] = value
    end
  end
  return out
end

local function Coord(x, y, label, note)
  local nx = tonumber(x)
  local ny = tonumber(y)
  if not nx or not ny then
    return nil
  end

  return {
    x = nx,
    y = ny,
    label = Trim(label or ""),
    note = Trim(note or ""),
  }
end

local function Item(name, count, note)
  local itemName = Trim(name or "")
  if itemName == "" then
    return nil
  end

  return {
    name = itemName,
    count = tonumber(count) or 0,
    note = Trim(note or ""),
  }
end

local function NormalizeCoords(value)
  if type(value) ~= "table" then
    return {}
  end

  local out = {}

  local function Push(entry)
    if type(entry) ~= "table" then
      return
    end

    local coord = Coord(
      entry.x or entry[1],
      entry.y or entry[2],
      entry.label or entry.name or entry[3],
      entry.note or entry.desc or entry[4]
    )

    if coord then
      out[#out + 1] = coord
    end
  end

  if value.x or value.y or value[1] or value[2] then
    Push(value)
    return out
  end

  for i = 1, #value do
    Push(value[i])
  end

  return out
end

local function NormalizePreviewItems(value)
  if type(value) ~= "table" then
    return {}
  end

  local out = {}

  local function Push(entry)
    if type(entry) == "string" then
      local preview = Item(entry, 0, "")
      if preview then
        out[#out + 1] = preview
      end
      return
    end

    if type(entry) ~= "table" then
      return
    end

    local preview = Item(
      entry.name or entry.item or entry[1],
      entry.count or entry.qty or entry.amount or entry[2],
      entry.note or entry.desc or entry[3]
    )

    if preview then
      out[#out + 1] = preview
    end
  end

  for i = 1, #value do
    Push(value[i])
  end

  return out
end

local function NormalizeRoute(route, fallbackCoords)
  if type(route) ~= "table" and type(fallbackCoords) ~= "table" then
    return nil
  end

  local out = {
    kind = "loop",
    label = "",
    waypoints = {},
    steps = {},
  }

  if type(route) == "table" then
    out.kind = Trim(route.kind or route.style or route.type or "loop")
    if out.kind == "" then
      out.kind = "loop"
    end

    out.label = Trim(route.label or route.name or "")
    out.waypoints = NormalizeCoords(route.waypoints or route.points or route.coords)
    out.steps = CopyStringList(route.steps)
  end

  if #out.waypoints == 0 and type(fallbackCoords) == "table" then
    out.waypoints = NormalizeCoords(fallbackCoords)
  end

  if out.label == "" and #out.waypoints > 0 then
    out.label = "Route"
  end

  if #out.waypoints == 0 and #out.steps == 0 then
    return nil
  end

  return out
end

local function MakeSeedKey(expansion, zone, name)
  local s = tostring(expansion or "") .. ":" .. tostring(zone or "") .. ":" .. tostring(name or "")
  s = s:lower()
  s = s:gsub("[^a-z0-9]+", "-")
  s = s:gsub("%-+", "-")
  s = s:gsub("^%-", ""):gsub("%-$", "")
  return s
end

local function Seed(t)
  t = t or {}

  t.name = Trim(t.name or "Farm")
  t.zone = Trim(t.zone or "Unknown")
  t.expansion = Trim(t.expansion or "Any")
  t.farmType = Trim(t.farmType or "Other")

  if not t.aim and t.focus then
    t.aim = t.focus
  end
  if not t.focus and t.aim then
    t.focus = t.aim
  end

  t.aim = Trim(t.aim or "Unknown")
  t.focus = Trim(t.focus or t.aim)

  t.tags = CopyStringList(t.tags)
  t.requirements = CopyStringList(t.requirements)
  t.targets = CopyStringList(t.targets or t.mobs)
  t.tips = CopyStringList(t.tips)

  t.notes = Trim(t.notes or t.description or "")
  t.description = Trim(t.description or t.notes or "")
  t.expected = Trim(t.expected or "")
  t.image = Trim(t.image or t.imagePath or t.previewImage or t.texture or "")

  -- Seed preview items are fallback-only.
  -- The UI should prefer live farm-history preview data whenever history exists.
  t.fallbackPreviewItems = NormalizePreviewItems(
    t.fallbackPreviewItems or t.seedPreviewItems or t.previewItems or t.preview
  )
  t.seedPreviewItems = t.fallbackPreviewItems
  t.previewItems = {}

  t.coords = NormalizeCoords(t.coords or t.coord)
  t.primaryCoord = t.primaryCoord or t.coords[1]
  t.route = NormalizeRoute(t.route, t.coords)

  t.seedKey = Trim(t.seedKey or "")
  if t.seedKey == "" then
    t.seedKey = MakeSeedKey(t.expansion, t.zone, t.name)
  end

  t.source = t.source or "seed"
  return t
end

WF.FARM_SEEDS = {
  Seed({
    name = "Basilisk Eyes",
    zone = "Terokkar Forest",
    expansion = "TBC",
    farmType = "OpenWorld",
    aim = "Reagents",
    tags = { "reagents", "skinning", "leather", "openworld" },
    requirements = { "Skinning" },
    targets = { "Dampscale Basilisk" },
    expected = "13,000g 0s 0c",
    image = "Interface\\AddOns\\WhatFarm\\Media\\FarmImages\\Dampscale_Basilisk.tga",
    description = "Kill and skin Dampscale Basilisks for basilisk eyes, Knothide Leather, and Fel Scales. Good premade seed for a simple, repeatable open-world loop.",
    coords = {
      Coord(38.7, 14.1, "Start", "North edge of the basilisk packs."),
      Coord(41.9, 17.5, "South sweep", "Rotate through the lower pack cluster before looping back."),
    },
    fallbackPreviewItems = {
      Item("Chunk o' Basilisk", 60),
      Item("Dampscale Basilisk Eye", 47),
      Item("Knothide Leather", 45),
      Item("Knothide Leather Scraps", 32),
      Item("Fel Scales", 25),
    },
    tips = {
      "Stay mounted between small pack gaps and skin on the move.",
      "If the north side feels thin, sweep south once and loop back as the first packs respawn.",
    },
    route = {
      kind = "loop",
      label = "North basilisk loop",
      steps = {
        "Start near 38.7, 14.1 and clear the northern edge first.",
        "Sweep south through the basilisk pockets instead of zig-zagging the whole area.",
        "Finish by cutting back north to meet the earliest respawns and repeat.",
      },
    },
  }),

  Seed({
    name = "Twilight Jasmine",
    zone = "Uldum",
    expansion = "Cata",
    farmType = "OpenWorld",
    aim = "Reagents",
    tags = { "reagents", "openworld", "herbalism" },
    requirements = { "Herbalism" },
    targets = { "Twilight Jasmine" },
    expected = "Route-based herb income",
    image = "Interface\\AddOns\\WhatFarm\\Media\\Farms\\twilight_jasmine",
    description = "A clean Uldum herb route focused on Twilight Jasmine spawns with smooth lap timing and strong repeatability.",
    coords = {
      Coord(56.2, 32.4, "Start", "Open on the eastern ridge."),
      Coord(61.8, 45.3, "River bend", "Check the lower valley spawns here."),
      Coord(49.5, 53.2, "Loop turn", "Swing west before climbing back north."),
    },
    fallbackPreviewItems = {
      Item("Twilight Jasmine", 85),
      Item("Volatile Life", 18),
    },
    tips = {
      "Keep the route wide enough to let nodes repopulate behind you.",
      "This farm feels best when you commit to clean loops instead of cutting across the center.",
    },
    route = {
      kind = "loop",
      label = "Uldum jasmine loop",
      steps = {
        "Begin on the eastern ridge and work south toward the river.",
        "Follow the lower basin west, checking the outer edge spawns first.",
        "Climb back north through the western side to restart the lap.",
      },
    },
  }),

  Seed({
    name = "The Botanica",
    zone = "Netherstorm",
    expansion = "TBC",
    farmType = "Instance",
    aim = "Raw Gold",
    tags = { "raw-gold", "vendor" },
    expected = "Fast repeatable vendor route",
    image = "Interface\\AddOns\\WhatFarm\\Media\\Farms\\the_botanica",
    description = "Quick instance clears with strong mob density and easy repeat value.",
    tips = {
      "Pull aggressively, then collapse packs together for cleaner clear times.",
      "Best used as a stable timed baseline farm.",
    },
  }),

  Seed({
    name = "Stratholme",
    seedKey = "classic-eastern-plaguelands-stratholme-undead-runecloth-mount",
    zone = "Eastern Plaguelands",
    expansion = "Classic",
    farmType = "Instance",
    aim = "Mounts",
    tags = { "cloth", "mount", "raw-gold" },
    expected = "Mount chance + runecloth",
    image = "Interface\\AddOns\\WhatFarm\\Media\\Farms\\stratholme",
    description = "Classic mount-focused route with reliable runecloth and vendor value on top.",
    tips = {
      "Run it for consistency, not just the jackpot.",
    },
  }),

  Seed({
    name = "Uldaman",
    seedKey = "classic-badlands-uldaman-transmog",
    zone = "Badlands",
    expansion = "Classic",
    farmType = "Instance",
    aim = "Transmog",
    tags = { "transmog" },
    expected = "Transmog-focused clear",
    image = "Interface\\AddOns\\WhatFarm\\Media\\Farms\\uldaman",
    description = "Old transmog staple with a clean identity and no junk packed into the farm name.",
    tips = {
      "Keep this one as a clean transmog benchmark seed.",
    },
  }),
}

WF.Seeds = WF.Seeds or {}
WF.Seeds.version = WF.FARM_SEED_VERSION
WF.Seeds.farms = WF.FARM_SEEDS
