// ─────────────────────────────────────────────────────────────────────────────
// Date formatting & period-based filtering
//
// Helpers for dashboard analytics: computing date ranges from a human-readable
// period token ("7days", "30days", …), filtering leads within that range, and
// grouping results into daily or monthly buckets for chart rendering.
// ─────────────────────────────────────────────────────────────────────────────

import { Lead } from "@/types"

// ── Range calculation ────────────────────────────────────────────────────────

/**
 * Convert a period token into a `{ start, end }` date range.
 *
 * | Token       | Range                  |
 * |-------------|------------------------|
 * | `"7days"`   | Last 7 days            |
 * | `"30days"`  | Last 30 days           |
 * | `"6months"` | Last 6 months (default)|
 * | `"12months"`| Last 12 months         |
 *
 * @param period - One of `"7days"`, `"30days"`, `"6months"`, `"12months"`.
 * @returns      `{ start, end }` where `end` is always `new Date()`.
 */
export function getPeriodDateRange(period: string): { start: Date; end: Date } {
  const end = new Date()
  const start = new Date()

  switch (period) {
    case "7days":
      start.setDate(start.getDate() - 7)
      break
    case "30days":
      start.setDate(start.getDate() - 30)
      break
    case "6months":
      start.setMonth(start.getMonth() - 6)
      break
    case "12months":
      start.setMonth(start.getMonth() - 12)
      break
    default:
      start.setMonth(start.getMonth() - 6)
  }

  return { start, end }
}

// ── Lead filtering ───────────────────────────────────────────────────────────

/**
 * Filter an array of leads so only those whose `createdAt` falls within the
 * period's date range remain.
 *
 * @param leads  - Full lead list.
 * @param period - Period token (see `getPeriodDateRange`).
 * @returns      Filtered leads.
 */
export function filterLeadsByPeriod(leads: Lead[], period: string): Lead[] {
  const { start, end } = getPeriodDateRange(period)
  return leads.filter((l) => {
    const d = new Date(l.createdAt)
    return d >= start && d <= end
  })
}

// ── Grouping for charts ──────────────────────────────────────────────────────

/**
 * Group leads into daily or monthly buckets based on the period length.
 *
 * - 7 or 30 days → daily buckets via `groupByDay`
 * - 6 or 12 months → monthly buckets via `groupByMonth`
 *
 * Each bucket returns the total lead count and the number of closed leads.
 *
 * @param leads  - Leads already filtered to the relevant period.
 * @param period - Period token.
 * @returns      Array of `{ label, leads, closed }` objects for charting.
 */
export function groupLeadsByInterval(
  leads: Lead[],
  period: string
): { label: string; leads: number; closed: number }[] {
  const { start, end } = getPeriodDateRange(period)

  if (period === "7days" || period === "30days") {
    return groupByDay(leads, start, end)
  }
  return groupByMonth(leads, start, end)
}

// ── Internal grouping implementations ────────────────────────────────────────

/**
 * Iterate day-by-day from `start` to `end`, counting total and closed leads
 * whose `createdAt` string starts with that day's ISO date prefix.
 */
function groupByDay(
  leads: Lead[],
  start: Date,
  end: Date
): { label: string; leads: number; closed: number }[] {
  const result: { label: string; leads: number; closed: number }[] = []
  const current = new Date(start)

  while (current <= end) {
    const dateStr = current.toISOString().slice(0, 10) // "2026-07-13"
    const dayLeads = leads.filter((l) => l.createdAt.startsWith(dateStr))
    const closedCount = dayLeads.filter((l) => l.status === "closed").length

    result.push({
      label: current.toLocaleDateString("en-US", { month: "short", day: "numeric" }),
      leads: dayLeads.length,
      closed: closedCount,
    })

    current.setDate(current.getDate() + 1)
  }

  return result
}

/**
 * Iterate month-by-month from `start` to `end`, counting total and closed leads
 * whose `createdAt` string starts with that month's `YYYY-MM` prefix.
 */
function groupByMonth(
  leads: Lead[],
  start: Date,
  end: Date
): { label: string; leads: number; closed: number }[] {
  const result: { label: string; leads: number; closed: number }[] = []
  const current = new Date(start.getFullYear(), start.getMonth(), 1)

  while (current <= end) {
    const yearMonth = `${current.getFullYear()}-${String(current.getMonth() + 1).padStart(2, "0")}`
    const monthLeads = leads.filter((l) => l.createdAt.startsWith(yearMonth))
    const closedCount = monthLeads.filter((l) => l.status === "closed").length

    result.push({
      label: current.toLocaleDateString("en-US", { month: "short", year: "2-digit" }),
      leads: monthLeads.length,
      closed: closedCount,
    })

    current.setMonth(current.getMonth() + 1)
  }

  return result
}
