/**
 * 安卓竖屏锁定：
 * - 已安装 PWA / 部分 WebView：直接 orientation.lock
 * - Chrome 普通标签页：必须先全屏再 lock（系统策略）
 * - 仍失败：用 JS 把界面强制按竖屏坐标系渲染（程序不进横屏布局）
 */
import { isStandaloneDisplay } from "./install";

type OrientationLockType =
  | "any"
  | "natural"
  | "landscape"
  | "portrait"
  | "portrait-primary"
  | "portrait-secondary"
  | "landscape-primary"
  | "landscape-secondary";

let osLocked = false;

function isAndroid(): boolean {
  return /Android/i.test(navigator.userAgent || "");
}

function isPhoneLike(): boolean {
  const ua = navigator.userAgent || "";
  if (/iPhone|iPod|Windows Phone/i.test(ua)) return true;
  if (/Android/i.test(ua)) {
    if (/Mobile/i.test(ua)) return true;
    return Math.min(window.screen.width, window.screen.height) <= 600;
  }
  const coarse = window.matchMedia("(pointer: coarse)").matches;
  const shortSide = Math.min(window.screen.width, window.screen.height);
  return coarse && shortSide <= 520;
}

function isLandscape(): boolean {
  return window.innerWidth > window.innerHeight;
}

function tryLegacyLock(): boolean {
  const s = screen as Screen & {
    lockOrientation?: (o: string) => boolean;
    mozLockOrientation?: (o: string) => boolean;
    msLockOrientation?: (o: string) => boolean;
  };
  try {
    if (s.lockOrientation?.("portrait") || s.lockOrientation?.("portrait-primary")) {
      return true;
    }
    if (s.mozLockOrientation?.("portrait")) return true;
    if (s.msLockOrientation?.("portrait")) return true;
  } catch {
    /* ignore */
  }
  return false;
}

async function tryModernLock(): Promise<boolean> {
  const orient = screen.orientation as ScreenOrientation & {
    lock?: (orientation: OrientationLockType) => Promise<void>;
  };
  if (!orient?.lock) return false;
  for (const mode of ["portrait", "portrait-primary"] as OrientationLockType[]) {
    try {
      await orient.lock(mode);
      return true;
    } catch {
      /* try next */
    }
  }
  return false;
}

async function ensureFullscreen(): Promise<boolean> {
  if (document.fullscreenElement) return true;
  const el = document.documentElement as HTMLElement & {
    webkitRequestFullscreen?: () => void;
  };
  try {
    if (typeof el.requestFullscreen === "function") {
      await el.requestFullscreen(
        { navigationUI: "hide" } as FullscreenOptions,
      );
      return Boolean(document.fullscreenElement);
    }
    if (typeof el.webkitRequestFullscreen === "function") {
      el.webkitRequestFullscreen();
      return true;
    }
  } catch {
    return false;
  }
  return Boolean(document.fullscreenElement);
}

/** 系统级竖屏锁。fromGesture=true 时安卓浏览器可先全屏再锁。 */
export async function lockPortraitHard(fromGesture: boolean): Promise<boolean> {
  if (!isPhoneLike()) return false;
  if (tryLegacyLock()) {
    osLocked = true;
    return true;
  }
  if (await tryModernLock()) {
    osLocked = true;
    return true;
  }
  // Chrome 标签页：全屏是 lock 的前置条件
  if (fromGesture && isAndroid() && !isStandaloneDisplay()) {
    await ensureFullscreen();
    if (tryLegacyLock() || (await tryModernLock())) {
      osLocked = true;
      return true;
    }
  }
  return false;
}

function clearRootForce(root: HTMLElement): void {
  root.style.position = "";
  root.style.width = "";
  root.style.height = "";
  root.style.left = "";
  root.style.top = "";
  root.style.transform = "";
  root.style.transformOrigin = "";
  root.style.overflow = "";
  root.style.zIndex = "";
}

/** 系统锁失败且当前横屏时，强制竖屏坐标系（程序不走横屏布局）。 */
function syncForcedPortraitLayout(): void {
  const html = document.documentElement;
  const root = document.getElementById("root");
  if (!root) return;

  if (!isPhoneLike()) {
    html.classList.remove("phone-portrait-lock", "phone-landscape");
    clearRootForce(root);
    return;
  }

  html.classList.add("phone-portrait-lock");

  // 系统已锁且当前是竖屏：清强制样式
  if (osLocked && !isLandscape()) {
    html.classList.remove("phone-landscape");
    clearRootForce(root);
    return;
  }

  if (!isLandscape()) {
    html.classList.remove("phone-landscape");
    clearRootForce(root);
    return;
  }

  html.classList.add("phone-landscape");
  const w = window.innerHeight;
  const h = window.innerWidth;
  root.style.position = "fixed";
  root.style.width = `${w}px`;
  root.style.height = `${h}px`;
  root.style.left = "0px";
  root.style.top = `${w}px`;
  root.style.transformOrigin = "left top";
  root.style.transform = "rotate(-90deg)";
  root.style.overflow = "auto";
  root.style.zIndex = "1";
  root.style.setProperty("-webkit-overflow-scrolling", "touch");
}

function syncHint(): void {
  let hint = document.getElementById("portrait-lock-hint");
  const need =
    isPhoneLike() &&
    isAndroid() &&
    !isStandaloneDisplay() &&
    !osLocked &&
    !document.fullscreenElement;

  if (!need) {
    hint?.remove();
    return;
  }
  if (!hint) {
    hint = document.createElement("button");
    hint.id = "portrait-lock-hint";
    hint.type = "button";
    hint.className = "portrait-lock-hint";
    hint.textContent = "点击锁定竖屏";
    hint.addEventListener("click", (ev) => {
      ev.preventDefault();
      void (async () => {
        await lockPortraitHard(true);
        syncForcedPortraitLayout();
        syncHint();
      })();
    });
    document.body.appendChild(hint);
  }
}

/** 启动竖屏锁定。安卓浏览器需点一下（全屏+锁）；已装主屏幕应用通常自动锁。 */
export function initPortraitLock(): void {
  if (typeof window === "undefined") return;

  const sync = () => {
    syncForcedPortraitLayout();
    syncHint();
  };

  void lockPortraitHard(false).then(sync);
  sync();

  window.addEventListener("orientationchange", () => {
    window.setTimeout(sync, 50);
    void lockPortraitHard(false).then(sync);
  });
  window.addEventListener("resize", sync);
  document.addEventListener("fullscreenchange", () => {
    if (!document.fullscreenElement) osLocked = false;
    sync();
  });
  document.addEventListener("visibilitychange", () => {
    if (document.visibilityState === "visible") {
      void lockPortraitHard(false).then(sync);
    }
  });

  const onGesture = () => {
    void lockPortraitHard(true).then(sync);
  };
  // 捕获阶段，保证第一次触摸就能触发全屏+锁
  window.addEventListener("pointerdown", onGesture, {
    capture: true,
    passive: true,
  });
  window.addEventListener("touchstart", onGesture, {
    capture: true,
    passive: true,
  });
}
