import { API_OPERATIONS, apiEndpointPath } from "../../src/shared/api/generated/endpoints.ts";
import { API_BASE_URL } from "../../src/shared/config/env.js";
import { countryFlag, stripCountryFlagPrefix } from "./data/countryMeta.js";

const TOKEN_KEY = "hyapp-admin.access-token";
const APP_CODE_KEY = "hyapp-admin.app-code";
const APP_CODE_HEADER = "X-App-Code";
const DEFAULT_APP_CODE = "lalu";
const ALL_APP_OPTION = { code: "", label: "全部", value: "" };
const DEFAULT_APP_OPTION = { code: DEFAULT_APP_CODE, label: "Lalu", value: DEFAULT_APP_CODE };
const FIXED_APP_OPTIONS = [
  { code: "aslan", label: "Aslan", value: "aslan" },
  { code: "yumi", label: "Yumi", value: "yumi" }
];
const SOCIAL_BI_ALL_VALUE = "all";
const SOCIAL_BI_OPERATION_TEAM_ID = 2;

export function getDefaultAppOptions() {
  return mergeAppOptions([ALL_APP_OPTION, DEFAULT_APP_OPTION, ...FIXED_APP_OPTIONS]);
}

export function getCurrentAppCode() {
  const stored = window.localStorage.getItem(APP_CODE_KEY);
  return stored === null ? DEFAULT_APP_CODE : normalizeAppCode(stored);
}

export function setCurrentAppCode(value) {
  const appCode = normalizeAppCode(value);
  window.localStorage.setItem(APP_CODE_KEY, appCode);
  return appCode;
}

export async function fetchStatisticsOverview({ appCode, countryId, endMs, regionId, seriesEndMs, seriesStartMs, startMs, statTz }) {
  const query = appScopedQuery(appCode);
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (seriesStartMs) {
    query.series_start_ms = String(seriesStartMs);
  }
  if (seriesEndMs) {
    query.series_end_ms = String(seriesEndMs);
  }
  if (countryId) {
    query.country_id = String(countryId);
  }
  if (regionId && regionId !== "all") {
    query.region_id = String(regionId);
  }

  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.statisticsOverview), { appCode, query });
}

export async function fetchPlatformGrantUsers({ appCode, countryId, endMs, page, pageSize, regionId, startMs, statDay, statTz }) {
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.listPlatformGrantUsers), {
    appCode,
    query: platformGrantQuery({ appCode, countryId, endMs, page, pageSize, regionId, startMs, statDay, statTz })
  });
}

export async function fetchPlatformGrantRecords({ appCode, countryId, endMs, page, pageSize, regionId, source, startMs, statDay, statTz, userId }) {
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.listPlatformGrantRecords), {
    appCode,
    query: platformGrantQuery({ appCode, countryId, endMs, page, pageSize, regionId, source, startMs, statDay, statTz, userId })
  });
}

export async function fetchSelfGameStatisticsOverview({ appCode, countryId, endMs, gameId, regionId, startMs, statTz }) {
  const query = appScopedQuery(appCode);
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (countryId) {
    query.country_id = String(countryId);
  }
  if (regionId && regionId !== "all") {
    query.region_id = String(regionId);
  }
  if (gameId && gameId !== "all") {
    query.game_id = String(gameId);
  }

  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.selfGameStatisticsOverview), { appCode, query });
}

function platformGrantQuery({ appCode, countryId, endMs, page, pageSize, regionId, source, startMs, statDay, statTz, userId }) {
  const query = appScopedQuery(appCode);
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (statDay) {
    query.stat_day = statDay;
  }
  if (countryId) {
    query.country_id = String(countryId);
  }
  if (regionId && regionId !== "all") {
    query.region_id = String(regionId);
  }
  if (userId) {
    query.user_id = String(userId);
  }
  if (source && source !== "all") {
    query.source = String(source);
  }
  if (page) {
    query.page = String(page);
  }
  if (pageSize) {
    query.page_size = String(pageSize);
  }
  return query;
}

export async function fetchFilterOptions({ appCode } = {}) {
  const [apps, regions, countries] = await Promise.all([
    fetchDatabiData(apiEndpointPath(API_OPERATIONS.listApps), { appCode }),
    fetchDatabiData(apiEndpointPath(API_OPERATIONS.listRegions), { appCode, query: { status: "active" } }),
    fetchDatabiData(apiEndpointPath(API_OPERATIONS.listCountries), { appCode, query: { enabled: true } })
  ]);

  return normalizeFilterOptions({ apps, countries, regions });
}

export async function fetchSocialBiFilterOptions({ appCode } = {}) {
  const [apps, operators] = await Promise.all([
    fetchDatabiData(apiEndpointPath(API_OPERATIONS.listApps), { appCode }),
    fetchDatabiData(apiEndpointPath(API_OPERATIONS.listTeamUsers, { team_id: SOCIAL_BI_OPERATION_TEAM_ID }), {
      appCode,
      query: { page_size: 200, status: "active" }
    })
  ]);

  return {
    appOptions: normalizeSocialBiAppOptions(apps),
    operatorOptions: normalizeSocialBiOperatorOptions(operators)
  };
}

// 社交 BI 主数据：按当前登录用户的数据范围返回可见 App、区域目录、运营人员及权限开关。
export async function fetchSocialBiMaster() {
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.getSocialBiMaster));
}

export async function fetchSocialBiOverview({ appCodes, endMs, regionId, regionIds, startMs, statTz }) {
  const query = {};
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (appCodes?.length) {
    query.app_codes = appCodes.join(",");
  }
  if (regionId) {
    query.region_id = String(regionId);
  } else if (regionIds?.length) {
    query.region_ids = regionIds.join(",");
  }
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.getSocialBiOverview), { query });
}

export async function fetchSocialBiRequirements({ appCodes, endMs, newUserType, payerType, regionId, regionIds, section, signal, startMs, statTz, userRole }) {
  const query = {};
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (appCodes?.length) {
    query.app_codes = appCodes.join(",");
  }
  if (regionId) {
    query.region_id = String(regionId);
  } else if (regionIds?.length) {
    query.region_ids = regionIds.join(",");
  }
  if (section) {
    query.section = section;
  }
  if (userRole) {
    query.user_role = userRole;
  }
  if (payerType) {
    query.payer_type = payerType;
  }
  if (newUserType) {
    query.new_user_type = newUserType;
  }
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.getSocialBiRequirements), { query, signal });
}

export async function fetchSocialBiFunnel({ appCodes, endMs, regionId, startMs, statTz }) {
  const query = {};
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (appCodes?.length) {
    query.app_codes = appCodes.join(",");
  }
  if (regionId) {
    query.region_id = String(regionId);
  }
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.getSocialBiFunnel), { query });
}

export async function fetchSocialBiKpi({ appCodes, endMs, operatorUserId, periodMonth, startMs, statTz }) {
  const query = {};
  if (statTz) {
    query.stat_tz = statTz;
  }
  if (startMs) {
    query.start_ms = String(startMs);
  }
  if (endMs) {
    query.end_ms = String(endMs);
  }
  if (periodMonth) {
    query.period_month = periodMonth;
  }
  if (appCodes?.length) {
    query.app_codes = appCodes.join(",");
  }
  if (operatorUserId) {
    query.operator_user_id = String(operatorUserId);
  }
  return fetchDatabiData(apiEndpointPath(API_OPERATIONS.getSocialBiKpi), { query });
}

async function fetchDatabiData(path, { appCode, body, method, query, signal } = {}) {
  const headers = requestHeaders(appCode);
  const init = {
    credentials: "include",
    headers,
    method: method || "GET",
    signal
  };
  if (body !== undefined) {
    headers["Content-Type"] = "application/json";
    init.body = JSON.stringify(body);
  }
  const response = await fetch(buildURL(path, query), init);
  const payload = await readJSON(response);
  if (isAuthExpired(response, payload)) {
    redirectToLogin(window);
    throw new Error(payload.message || "访问凭证已失效");
  }
  if (!response.ok || payload.code !== 0) {
    throw new Error(payload.message || response.statusText || "请求失败");
  }
  return payload.data;
}

function buildURL(path, query) {
  const url = new URL(`${API_BASE_URL}${path}`, window.location.origin);
  if (query) {
    Object.entries(query).forEach(([key, value]) => {
      if (value !== undefined && value !== null && value !== "") {
        url.searchParams.set(key, String(value));
      }
    });
  }
  return url.toString();
}

function requestHeaders(appCode) {
  const headers = {};
  const token = window.localStorage.getItem(TOKEN_KEY);
  if (token) {
    headers.Authorization = `Bearer ${token}`;
  }
  const normalized = normalizeAppCode(appCode);
  if (normalized) {
    headers[APP_CODE_HEADER] = normalized;
  }
  return headers;
}

async function readJSON(response) {
  const text = await response.text();
  if (!text) {
    return {};
  }
  try {
    return JSON.parse(text);
  } catch {
    return { code: response.ok ? 0 : response.status, message: text };
  }
}

export function isAuthExpired(response, payload) {
  return response.status === 401 || Number(payload?.code) === 40100;
}

export function redirectToLogin(targetWindow = window) {
  targetWindow.localStorage.removeItem(TOKEN_KEY);
  if (targetWindow.location.pathname !== "/login") {
    targetWindow.location.replace("/login");
  }
}

function normalizeAppCode(value) {
  return String(value || "").trim().toLowerCase();
}

function appScopedQuery(appCode) {
  const normalized = normalizeAppCode(appCode);
  // “全部”使用空 appCode，让请求层省略 X-App-Code 和 app_code，避免把 all 当成真实 App 传给后端。
  return normalized ? { app_code: normalized } : {};
}

function normalizeFilterOptions({ apps, countries, regions }) {
  const regionItems = normalizeList(regions);
  const regionOptions = [
    { countryCodes: [], id: "all", label: "全部区域", value: "all" },
    ...regionItems
      .filter((region) => String(region.regionCode || "").toUpperCase() !== "GLOBAL")
      .map((region) => {
        const id = String(region.regionId ?? region.id ?? region.regionCode ?? "");
        return {
          countryCodes: normalizeCodes(region.countries),
          id,
          label: [region.name, region.regionCode].filter(Boolean).join(" · ") || `区域 ${id}`,
          value: id
        };
      })
      .filter((region) => region.id)
  ];
  const countryRegionIds = buildCountryRegionIndex(regionOptions);
  const countryOptions = [
    { countryCode: "", id: 0, label: "全部国家", regionIds: [], searchText: "全部国家 all", value: 0 },
    ...normalizeList(countries)
      .map((country) => normalizeCountryOption(country, countryRegionIds))
      .filter(Boolean)
  ];
  const apiAppOptions = normalizeList(apps)
    .map((app) => {
      const code = normalizeAppCode(app.appCode ?? app.app_code ?? app.code);
      return {
        code,
        label: app.appName || app.app_name || app.name || code,
        value: code
      };
    })
    .filter((app) => app.code);
  const appOptions = mergeAppOptions([ALL_APP_OPTION, ...apiAppOptions, DEFAULT_APP_OPTION, ...FIXED_APP_OPTIONS]);

  return {
    appOptions,
    countryOptions,
    regionOptions
  };
}

function normalizeSocialBiAppOptions(apps) {
  const options = normalizeList(apps)
    .map((app) => {
      const code = normalizeAppCode(app.appCode ?? app.app_code ?? app.code);
      if (!code) {
        return null;
      }
      return {
        label: app.appName || app.app_name || app.name || code,
        value: code
      };
    })
    .filter(Boolean);
  const fixedOptions = FIXED_APP_OPTIONS.map((app) => ({ label: app.label, value: app.value }));
  return [{ label: "全部 App", value: SOCIAL_BI_ALL_VALUE }, ...dedupeOptions([...options, ...fixedOptions])];
}

function normalizeSocialBiOperatorOptions(operators) {
  const options = normalizeList(operators)
    .map((user) => {
      const id = user.id ?? user.userId ?? user.user_id ?? user.account;
      const label = user.name || user.nickname || user.account || String(id || "");
      if (!id || !label) {
        return null;
      }
      return {
        label,
        searchText: [label, user.account, user.teamName, user.team].filter(Boolean).join(" ").toLowerCase(),
        value: String(id)
      };
    })
    .filter(Boolean);
  return [{ label: "全部人员", searchText: "all 全部人员", value: SOCIAL_BI_ALL_VALUE }, ...dedupeOptions(options)];
}

function dedupeOptions(options) {
  const seen = new Set();
  return options.filter((option) => {
    const key = String(option.value || option.label || "").trim().toLowerCase();
    if (!key || seen.has(key)) {
      return false;
    }
    seen.add(key);
    return true;
  });
}

function mergeAppOptions(options) {
  const seen = new Set();
  return options.filter((option) => {
    const code = normalizeAppCode(option.code ?? option.value);
    if (seen.has(code)) {
      return false;
    }
    seen.add(code);
    return true;
  });
}

function normalizeList(value) {
  if (Array.isArray(value)) {
    return value;
  }
  if (Array.isArray(value?.items)) {
    return value.items;
  }
  if (Array.isArray(value?.list)) {
    return value.list;
  }
  return [];
}

function normalizeCodes(value) {
  return Array.isArray(value) ? value.map((item) => String(item || "").trim().toUpperCase()).filter(Boolean) : [];
}

function buildCountryRegionIndex(regions) {
  const index = new Map();
  regions.forEach((region) => {
    if (region.id === "all") {
      return;
    }
    region.countryCodes.forEach((code) => {
      const ids = index.get(code) || [];
      ids.push(region.id);
      index.set(code, ids);
    });
  });
  return index;
}

function normalizeCountryOption(country, countryRegionIds) {
  const countryCode = String(country.countryCode ?? country.country_code ?? country.code ?? "").trim().toUpperCase();
  const id = Number(country.countryId ?? country.country_id ?? country.id ?? 0);
  if (!countryCode && !id) {
    return null;
  }
  const rawName = country.countryDisplayName || country.country_display_name || country.countryName || country.country_name || country.name || countryCode;
  const name = stripCountryFlagPrefix(rawName);
  const flag = country.flag || countryFlag(countryCode);
  const label = [flag, name].filter(Boolean).join(" ");
  const searchText = [flag, rawName, name, countryCode, country.isoAlpha3, country.iso_alpha3, country.phoneCountryCode, country.phone_country_code]
    .filter(Boolean)
    .join(" ")
    .toLowerCase();
  return {
    countryCode,
    flag,
    id,
    label,
    name,
    regionIds: countryRegionIds.get(countryCode) || [],
    searchText,
    value: id
  };
}
