import { isCompleted } from "../constants/swiDocumentStatus.js";
import { chartScaleMax } from "./documentCreationTrend.js";

export const ASSIGNMENT_PERIOD_OPTIONS = [
  { id: "monthly", label: "Monthly" },
  { id: "quarterly", label: "Quarterly" },
  { id: "halfyearly", label: "Half-yearly" },
  { id: "yearly", label: "Yearly" },
];

function parseAssignedAt(doc) {
  const raw = doc?.assigned_at;
  if (!raw) return null;
  const date = new Date(raw);
  return Number.isNaN(date.getTime()) ? null : date;
}

function monthKey(date) {
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
}

function quarterKey(date) {
  const quarter = Math.floor(date.getMonth() / 3) + 1;
  return `${date.getFullYear()}-Q${quarter}`;
}

function halfKey(date) {
  const half = date.getMonth() < 6 ? 1 : 2;
  return `${date.getFullYear()}-H${half}`;
}

function addMonths(date, offset) {
  return new Date(date.getFullYear(), date.getMonth() + offset, 1);
}

function quarterLabel(date) {
  const quarter = Math.floor(date.getMonth() / 3) + 1;
  return `Q${quarter} ${String(date.getFullYear()).slice(-2)}`;
}

function halfLabel(date) {
  const half = date.getMonth() < 6 ? 1 : 2;
  return `H${half} ${String(date.getFullYear()).slice(-2)}`;
}

function buildMonthlyBuckets(count = 12) {
  const now = new Date();
  const buckets = new Map();
  for (let offset = count - 1; offset >= 0; offset -= 1) {
    const date = addMonths(now, -offset);
    const key = monthKey(date);
    buckets.set(key, {
      period: key,
      label: date.toLocaleDateString(undefined, {
        month: "short",
        year: "2-digit",
      }),
      count: 0,
    });
  }
  return buckets;
}

function buildQuarterlyBuckets(count = 8) {
  const now = new Date();
  const buckets = new Map();
  const startMonth =
    Math.floor(now.getMonth() / 3) * 3 - (count - 1) * 3;
  const start = new Date(now.getFullYear(), startMonth, 1);

  for (let i = 0; i < count; i += 1) {
    const date = new Date(start.getFullYear(), start.getMonth() + i * 3, 1);
    const key = quarterKey(date);
    buckets.set(key, {
      period: key,
      label: quarterLabel(date),
      count: 0,
    });
  }
  return buckets;
}

function buildHalfYearlyBuckets(count = 6) {
  const now = new Date();
  const items = [];
  let year = now.getFullYear();
  let half = now.getMonth() < 6 ? 1 : 2;

  for (let i = 0; i < count; i += 1) {
    const date = new Date(year, half === 1 ? 0 : 6, 1);
    const key = halfKey(date);
    items.unshift({
      period: key,
      label: halfLabel(date),
      count: 0,
    });
    half -= 1;
    if (half < 1) {
      half = 2;
      year -= 1;
    }
  }

  return new Map(items.map((item) => [item.period, item]));
}

function buildYearlyBuckets(assignments = []) {
  const now = new Date();
  const years = new Set();
  for (const doc of assignments) {
    const date = parseAssignedAt(doc);
    if (date) years.add(date.getFullYear());
  }

  let startYear = years.size ? Math.min(...years) : now.getFullYear() - 4;
  const endYear = now.getFullYear();
  if (endYear - startYear > 12) {
    startYear = endYear - 12;
  }

  const buckets = new Map();
  for (let year = startYear; year <= endYear; year += 1) {
    const key = String(year);
    buckets.set(key, {
      period: key,
      label: key,
      count: 0,
    });
  }
  return buckets;
}

function incrementBucket(buckets, key) {
  if (buckets.has(key)) {
    buckets.get(key).count += 1;
  }
}

/** Assignment counts grouped by month, quarter, half-year, or year. */
export function buildUserAssignmentTrend(
  assignments = [],
  periodId = "monthly"
) {
  let buckets;

  if (periodId === "quarterly") {
    buckets = buildQuarterlyBuckets(8);
    for (const doc of assignments) {
      const date = parseAssignedAt(doc);
      if (date) incrementBucket(buckets, quarterKey(date));
    }
  } else if (periodId === "halfyearly") {
    buckets = buildHalfYearlyBuckets(6);
    for (const doc of assignments) {
      const date = parseAssignedAt(doc);
      if (date) incrementBucket(buckets, halfKey(date));
    }
  } else if (periodId === "yearly") {
    buckets = buildYearlyBuckets(assignments);
    for (const doc of assignments) {
      const date = parseAssignedAt(doc);
      if (date) incrementBucket(buckets, String(date.getFullYear()));
    }
  } else {
    buckets = buildMonthlyBuckets(12);
    for (const doc of assignments) {
      const date = parseAssignedAt(doc);
      if (date) incrementBucket(buckets, monthKey(date));
    }
  }

  return Array.from(buckets.values());
}

export { chartScaleMax };

export function buildLocationWiseSeries(documents = []) {
  const map = new Map();

  for (const doc of documents) {
    const label = (doc.location_name || "Unknown plant").trim() || "Unknown plant";
    if (!map.has(label)) {
      map.set(label, { label, value: 0, tone: "opened" });
    }
    map.get(label).value += 1;
  }

  return Array.from(map.values()).sort((a, b) => b.value - a.value);
}

export function getUndoneAssignments(assignments = []) {
  return assignments
    .filter((doc) => !isCompleted(doc.document_status_id))
    .sort((a, b) => {
      const ta = a.assigned_at ? new Date(a.assigned_at).getTime() : 0;
      const tb = b.assigned_at ? new Date(b.assigned_at).getTime() : 0;
      return tb - ta;
    });
}

export function remainingSwiSummary(assignments = []) {
  const total = assignments.length;
  const undone = getUndoneAssignments(assignments);
  const remaining = undone.length;
  const completed = total - remaining;
  const progress = total > 0 ? Math.round((completed / total) * 100) : 0;

  return { total, completed, remaining, progress, undone };
}
