import { parseLocalizedPublicPath } from "@/lib/i18n-urls";

export const MARKETING_ATTRIBUTION_COOKIE = "official_mail_marketing_source";
export const MARKETING_SESSION_MS = 30 * 60 * 1000;
export const UNKNOWN_MARKETING_CHANNEL = "직접 방문 / 출처 미확인";
export const INTERNAL_MARKETING_CHANNEL = "내부 이동 / 최초 유입 미확인";

const MARKETING_PATHS = new Set([
  "/", "/ai-email-summary", "/business-email", "/domain-email",
  "/domain-mail-check", "/faq", "/guide", "/secure-business-email",
  "/signup", "/team-mailbox", "/blog", "/partner", "/terms",
  "/privacy", "/refund-policy", "/account-deletion",
  "/login", "/find-id", "/reset-password", "/mail", "/mail-setup", "/dashboard",
  "/payments/toss/billing/register", "/payments/toss/success", "/payments/toss/fail",
]);

export const MARKETING_PLATFORMS = [
  { label: "스레드", hosts: ["threads.com", "threads.net"], browser: "Threads", agent: "(^|[^a-z])(barcelona|threads)[ /;]", packages: ["com.instagram.barcelona"] },
  { label: "인스타그램", hosts: ["instagram.com"], browser: "Instagram", agent: "instagram[ /]", packages: ["com.instagram.android"] },
  { label: "페이스북", hosts: ["facebook.com", "fb.com"], browser: "Facebook", agent: "fban/|fbav/", packages: ["com.facebook.katana", "com.facebook.lite"] },
  { label: "카카오톡", hosts: ["talk.kakao.com"], browser: "KakaoTalk", agent: "kakaotalk", packages: ["com.kakao.talk"] },
  { label: "네이버", hosts: ["naver.com"], browser: "Naver", agent: "naver[( /]", packages: ["com.nhn.android.search"] },
  { label: "다음", hosts: ["daum.net"], browser: "Daum", agent: "daumapps", packages: ["net.daum.android.daum"] },
  { label: "라인", hosts: [], browser: "LINE", agent: "(^|[ ;])line/", packages: ["jp.naver.line.android"] },
  { label: "X", hosts: ["x.com", "twitter.com", "t.co"], browser: "X", agent: "twitter[ /]", packages: ["com.twitter.android"] },
  { label: "구글", hosts: [], browser: "Google App", agent: "gsa/", packages: ["com.google.android.googlequicksearchbox"] },
] as const;

export function detectMarketingApp(userAgent: string | null | undefined, requestedWith?: string | null) {
  const packageName = requestedWith?.trim().toLowerCase();
  const fromPackage = MARKETING_PLATFORMS.find((platform) => platform.packages.some((name) => name === packageName));
  if (fromPackage) return fromPackage.browser;
  return MARKETING_PLATFORMS.find((platform) => new RegExp(platform.agent, "i").test(userAgent ?? ""))?.browser ?? null;
}

export function isMarketingAppPath(path: string) {
  return /^\/(mail(?:\?|$)|mail-setup$|dashboard$|payments\/)/.test(path);
}

export type MarketingAttribution = {
  sourceApp: string;
  referrerHost: string;
  referrerPath: string;
  utmSource: string;
  utmMedium: string;
  utmCampaign: string;
  utmContent: string;
  utmTerm: string;
};

type StoredAttribution = MarketingAttribution & {
  visitorId: string;
  updatedAt: number;
};

function clean(value: unknown, length: number) {
  return typeof value === "string"
    ? value.trim().replace(/[\u0000-\u001f\u007f]/g, "").slice(0, length)
    : "";
}

export function normalizeMarketingLandingPath(value: unknown) {
  const raw = clean(value, 4096);
  const path = raw.split(/[?#]/)[0];
  if (!path.startsWith("/") || path.startsWith("//") || path.includes("://")) return null;
  const normalized = path.replace(/\/$/, "") || "/";
  const canonical = parseLocalizedPublicPath(normalized)?.pathname ?? normalized;
  if (canonical !== normalized && (isMarketingAppPath(canonical) || ["/login", "/signup", "/find-id", "/reset-password"].includes(canonical))) return null;
  if (/^\/reset-password\/[^/]+$/.test(normalized)) return "/reset-password";
  if (normalized === "/mail") {
    const query = new URL(raw, "https://mail.officialsite.kr").searchParams;
    const panel = query.get("panel");
    const section = query.get("section");
    if (panel === "setup") {
      return ["account", "domain", "assistant", "integrations", "members", "billing", "language"].includes(section ?? "")
        ? `/mail?panel=setup&section=${section}` : "/mail?panel=setup";
    }
    if (panel === "auto-send") return "/mail?panel=auto-send";
    if (["compose", "files"].includes(query.get("view") ?? "")) return `/mail?view=${query.get("view")}`;
    if (query.has("message") || query.get("detail") === "body") return "/mail?detail=body";
    const folder = query.get("folder");
    return ["all", "inbox", "sent", "drafts", "trash", "spam", "important"].includes(folder ?? "")
      ? `/mail?folder=${folder}` : "/mail";
  }
  return MARKETING_PATHS.has(canonical) || /^\/blog\/[^/]+$/.test(canonical)
    ? normalized.slice(0, 191) : null;
}

export function isInternalMarketingHost(host: string) {
  const hostname = host.toLowerCase().split(":")[0].replace(/\.$/, "");
  return hostname === "officialsite.kr" || hostname.endsWith(".officialsite.kr") ||
    hostname === "localhost" || hostname === "127.0.0.1";
}

export function normalizeMarketingAttribution(value: Partial<MarketingAttribution>): MarketingAttribution {
  const host = clean(value.referrerHost, 191).toLowerCase();
  const referrerHost = /^[a-z0-9.-]+(?::\d{1,5})?$/.test(host) ? host : "";
  let path = clean(value.referrerPath, 512).split(/[?#]/)[0];
  if (isInternalMarketingHost(referrerHost)) path = normalizeMarketingLandingPath(path) ?? "/";
  return {
    sourceApp: MARKETING_PLATFORMS.some((item) => item.browser === value.sourceApp) ? value.sourceApp! : "",
    referrerHost,
    referrerPath: referrerHost && path.startsWith("/") && !path.startsWith("//") ? path : "",
    utmSource: clean(value.utmSource, 120),
    utmMedium: clean(value.utmMedium, 120),
    utmCampaign: clean(value.utmCampaign, 160),
    utmContent: clean(value.utmContent, 160),
    utmTerm: clean(value.utmTerm, 160),
  };
}

export function getMarketingChannel(value: Partial<MarketingAttribution> & { browserName?: string | null; userAgent?: string | null }) {
  const source = normalizeMarketingAttribution(value);
  const campaign = [source.utmSource, source.utmMedium].filter(Boolean).join(" / ");
  if (campaign) return campaign;
  const platform = MARKETING_PLATFORMS.find((item) => item.hosts.some((host) => source.referrerHost === host || source.referrerHost.endsWith(`.${host}`)));
  if (platform) return platform.label;
  if (source.referrerHost && !isInternalMarketingHost(source.referrerHost)) return source.referrerHost;
  const browser = source.sourceApp || (MARKETING_PLATFORMS.some((item) => item.browser === value.browserName)
    ? value.browserName : detectMarketingApp(value.userAgent));
  const app = MARKETING_PLATFORMS.find((item) => item.browser === browser);
  if (app) return `${app.label} (인앱 추정)`;
  if (isInternalMarketingHost(source.referrerHost)) return INTERNAL_MARKETING_CHANNEL;
  return source.referrerHost || UNKNOWN_MARKETING_CHANNEL;
}

export function resolveMarketingAttribution(input: {
  url: string;
  referrer: string;
  previous?: StoredAttribution | null;
  visitorId: string;
  now: number;
  isNewDocument: boolean;
  userAgent?: string;
}): StoredAttribution {
  const url = new URL(input.url);
  let referrer: URL | null = null;
  let referrerApp: string | null = null;
  try {
    const candidate = new URL(input.referrer);
    if (candidate.protocol === "https:" || candidate.protocol === "http:") referrer = candidate;
    if (candidate.protocol === "android-app:") referrerApp = detectMarketingApp(null, candidate.hostname);
  } catch { /* Direct visits may not have a referrer. */ }
  const current = normalizeMarketingAttribution({
    sourceApp: referrerApp ?? detectMarketingApp(input.userAgent) ?? "",
    referrerHost: referrer?.host,
    referrerPath: referrer?.pathname,
    utmSource: url.searchParams.get("utm_source") ?? "",
    utmMedium: url.searchParams.get("utm_medium") ?? "",
    utmCampaign: url.searchParams.get("utm_campaign") ?? "",
    utmContent: url.searchParams.get("utm_content") ?? "",
    utmTerm: url.searchParams.get("utm_term") ?? "",
  });
  const previous = input.previous;
  const validPrevious = previous?.visitorId === input.visitorId &&
    Number.isFinite(previous.updatedAt) && previous.updatedAt <= input.now &&
    input.now - previous.updatedAt < MARKETING_SESSION_MS;
  const externalEntry = input.isNewDocument && (referrerApp || (current.referrerHost &&
    current.referrerHost !== url.host && !isInternalMarketingHost(current.referrerHost)));
  const hasCampaign = Boolean(current.utmSource || current.utmMedium || current.utmCampaign);
  const source = validPrevious && !externalEntry && !hasCampaign ? previous : current;
  return { ...normalizeMarketingAttribution(source), visitorId: input.visitorId, updatedAt: input.now };
}

let documentAttribution: StoredAttribution | null = null;

export function prepareMarketingAttribution(visitorId: string) {
  let previous = documentAttribution;
  if (!previous) {
    try {
      const cookie = document.cookie.split(";").map((part) => part.trim())
        .find((part) => part.startsWith(`${MARKETING_ATTRIBUTION_COOKIE}=`));
      previous = cookie ? JSON.parse(decodeURIComponent(cookie.slice(MARKETING_ATTRIBUTION_COOKIE.length + 1))) : null;
    } catch { /* Invalid or unavailable cookies must not break navigation. */ }
  }
  const attribution = resolveMarketingAttribution({
    url: window.location.href,
    referrer: document.referrer,
    previous,
    visitorId,
    now: Date.now(),
    isNewDocument: !documentAttribution,
    userAgent: typeof navigator === "undefined" ? "" : navigator.userAgent,
  });
  documentAttribution = attribution;
  const hostname = window.location.hostname.toLowerCase();
  const domain = hostname === "officialsite.kr" || hostname.endsWith(".officialsite.kr")
    ? "; domain=.officialsite.kr" : "";
  const secure = window.location.protocol === "https:" ? "; Secure" : "";
  let encoded = encodeURIComponent(JSON.stringify(attribution));
  if (encoded.length > 3500) {
    encoded = encodeURIComponent(JSON.stringify({
      ...attribution,
      referrerPath: attribution.referrerHost ? "/" : "",
      utmSource: attribution.utmSource.slice(0, 80),
      utmMedium: attribution.utmMedium.slice(0, 80),
      utmCampaign: attribution.utmCampaign.slice(0, 80),
      utmContent: "",
      utmTerm: "",
    }));
  }
  try {
    document.cookie = `${MARKETING_ATTRIBUTION_COOKIE}=${encoded}; path=/; max-age=1800; SameSite=Lax${domain}${secure}`;
  } catch { /* In-memory attribution still works when cookies are disabled. */ }
  return normalizeMarketingAttribution(attribution);
}
