// 社交 BI v2 的全局筛选与可下钻视图状态：日期/App/区域/运营人员/趋势粒度，以及数据明细模式，
// 统一同步到 URL query，保证筛选结果和“数据需求”目标分组都可以直接作为链接分享。

import { lastDaysRange, thisMonthRange, todayRange } from "../utils/time.js";

export const ALL = "all";

const TABLE_MODES = new Set(["wide", "requirements"]);
const REQUIREMENT_SECTIONS = new Set(["revenue", "new_users", "active", "gift", "game", "lucky_gift_v3", "retention"]);

export function createDefaultTableState() {
  return {
    mode: "wide",
    requirementSection: "revenue"
  };
}

export const DATE_PRESETS = [
  { key: "today", label: "今日" },
  { key: "yesterday", label: "昨日" },
  { key: "last7", label: "近 7 日" },
  { key: "last30", label: "近 30 日" },
  { key: "month", label: "本月" },
  { key: "prevMonth", label: "上月" },
  { key: "custom", label: "自定义" }
];

export const GRANULARITIES = [
  { key: "day", label: "日" },
  { key: "week", label: "周" },
  { key: "month", label: "月" }
];

export function createDefaultFilters() {
  return {
    apps: [ALL],
    customEnd: "",
    customStart: "",
    granularity: "day",
    operator: ALL,
    preset: "yesterday",
    regions: [ALL]
  };
}

export function resolveDateRange(filters, timeZone) {
  const today = todayRange(timeZone).start;
  switch (filters.preset) {
    case "today":
      return { end: today, start: today };
    case "yesterday": {
      const yesterday = shiftDate(today, -1);
      return { end: yesterday, start: yesterday };
    }
    case "last7": {
      const range = lastDaysRange(7, timeZone);
      return { end: range.end, start: range.start };
    }
    case "last30": {
      const range = lastDaysRange(30, timeZone);
      return { end: range.end, start: range.start };
    }
    case "month": {
      const range = thisMonthRange(timeZone);
      return { end: range.end, start: range.start };
    }
    case "prevMonth": {
      const monthStart = thisMonthRange(timeZone).start;
      const prevEnd = shiftDate(monthStart, -1);
      return { end: prevEnd, start: `${prevEnd.slice(0, 7)}-01` };
    }
    case "custom": {
      const start = normalizeDateText(filters.customStart) || shiftDate(today, -7);
      const end = normalizeDateText(filters.customEnd) || today;
      return end < start ? { end: start, start: end } : { end, start };
    }
    default: {
      const yesterday = shiftDate(today, -1);
      return { end: yesterday, start: yesterday };
    }
  }
}

export function rangeDayCount(range) {
  const start = Date.parse(`${range.start}T00:00:00Z`);
  const end = Date.parse(`${range.end}T00:00:00Z`);
  if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) {
    return 1;
  }
  return Math.round((end - start) / 86400000) + 1;
}

export function rangeLabel(range) {
  return range.start === range.end ? range.start : `${range.start} ~ ${range.end}`;
}

export function shiftDate(dateText, days) {
  const [year, month, day] = String(dateText).split("-").map(Number);
  const date = new Date(Date.UTC(year || 1970, (month || 1) - 1, (day || 1) + days));
  return `${date.getUTCFullYear()}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())}`;
}

function normalizeDateText(value) {
  const text = String(value || "").trim();
  return /^\d{4}-\d{2}-\d{2}$/.test(text) ? text : "";
}

function pad2(value) {
  return String(value).padStart(2, "0");
}

// stat_day → 周/月粒度的分桶 key；周取周一为锚点，与运营周报口径一致。
export function bucketDay(statDay, granularity) {
  if (granularity === "month") {
    return String(statDay).slice(0, 7);
  }
  if (granularity === "week") {
    const time = Date.parse(`${statDay}T00:00:00Z`);
    if (!Number.isFinite(time)) {
      return statDay;
    }
    const date = new Date(time);
    const weekday = (date.getUTCDay() + 6) % 7;
    date.setUTCDate(date.getUTCDate() - weekday);
    return `${date.getUTCFullYear()}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())}`;
  }
  return statDay;
}

const URL_KEYS = ["preset", "start", "end", "apps", "regions", "operator", "view", "granularity", "mode", "section"];

export function readStateFromURL(location = window.location) {
  const params = new URLSearchParams(location.search);
  const filters = createDefaultFilters();
  const table = createDefaultTableState();
  let view = "";
  if (params.get("preset") && DATE_PRESETS.some((item) => item.key === params.get("preset"))) {
    filters.preset = params.get("preset");
  }
  filters.customStart = normalizeDateText(params.get("start"));
  filters.customEnd = normalizeDateText(params.get("end"));
  if (params.get("apps")) {
    filters.apps = params.get("apps").split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
  }
  if (params.get("regions")) {
    filters.regions = params.get("regions").split(",").map((item) => item.trim()).filter(Boolean);
  }
  if (/^\d+$/.test(params.get("operator") || "")) {
    filters.operator = params.get("operator");
  }
  if (params.get("granularity") && GRANULARITIES.some((item) => item.key === params.get("granularity"))) {
    filters.granularity = params.get("granularity");
  }
  if (params.get("view")) {
    view = params.get("view");
  }
  const requestedTableMode = params.get("mode");
  if (view === "table" && TABLE_MODES.has(requestedTableMode)) {
    table.mode = requestedTableMode;
    if (requestedTableMode === "requirements" && REQUIREMENT_SECTIONS.has(params.get("section"))) {
      table.requirementSection = params.get("section");
    }
  }
  if (!filters.apps.length) {
    filters.apps = [ALL];
  }
  if (!filters.regions.length) {
    filters.regions = [ALL];
  }
  return { filters, table, view };
}

export function writeStateToURL(filters, view, table, history = window.history, location = window.location) {
  const params = new URLSearchParams(location.search);
  URL_KEYS.forEach((key) => params.delete(key));
  if (filters.preset !== "yesterday") {
    params.set("preset", filters.preset);
  }
  if (filters.preset === "custom") {
    if (filters.customStart) {
      params.set("start", filters.customStart);
    }
    if (filters.customEnd) {
      params.set("end", filters.customEnd);
    }
  }
  if (filters.apps.length && !filters.apps.includes(ALL)) {
    params.set("apps", filters.apps.join(","));
  }
  if (filters.regions.length && !filters.regions.includes(ALL)) {
    params.set("regions", filters.regions.join(","));
  }
  if (filters.operator !== ALL) {
    params.set("operator", filters.operator);
  }
  if (filters.granularity !== "day") {
    params.set("granularity", filters.granularity);
  }
  if (view && view !== "overview") {
    params.set("view", view);
  }
  if (view === "table" && table?.mode === "requirements") {
    // 非默认分组与数据需求模式一起入 URL，保证概览下钻和复制后的链接都能落到同一个业务明细视图。
    params.set("mode", "requirements");
    if (REQUIREMENT_SECTIONS.has(table.requirementSection) && table.requirementSection !== "revenue") {
      params.set("section", table.requirementSection);
    }
  }
  const query = params.toString();
  history.replaceState(null, "", `${location.pathname}${query ? `?${query}` : ""}`);
}

// 区域选择值格式：整 App = `app:<appCode>`，单区域 = `<appCode>:<regionId>`。
export function regionSelectionMatches(selection, appCode, regionId) {
  if (!selection?.length || selection.includes(ALL)) {
    return true;
  }
  return selection.includes(`app:${appCode}`) || selection.includes(`${appCode}:${regionId}`);
}

export function appSelectionMatches(selection, appCode) {
  if (!selection?.length || selection.includes(ALL)) {
    return true;
  }
  return selection.includes(String(appCode || "").toLowerCase());
}

export function toggleMultiValue(current, value, allValues) {
  if (value === ALL) {
    return [ALL];
  }
  const withoutAll = current.filter((item) => item !== ALL);
  const next = withoutAll.includes(value) ? withoutAll.filter((item) => item !== value) : [...withoutAll, value];
  if (!next.length || (allValues?.length && allValues.every((item) => next.includes(item)))) {
    return [ALL];
  }
  return next;
}
