import { Copy, X } from "lucide-react";
import { useEffect, useState, type ReactNode } from "react";
import { createPortal } from "react-dom";
import { useI18n } from "../i18n";
import { useToast } from "./Toast";
import {
  IN_APP_DOWNLOAD_GUIDE_EVENT,
  type InAppDownloadGuideDetail,
} from "./messageStream/utils/downloadFile";
import { inAppBrowserName } from "../utils/inAppBrowser";

async function copyTextToClipboard(text: string): Promise<boolean> {
  try {
    if (
      typeof navigator !== "undefined" &&
      navigator.clipboard &&
      typeof navigator.clipboard.writeText === "function"
    ) {
      await navigator.clipboard.writeText(text);
      return true;
    }
  } catch {
    // fall through to legacy path
  }
  try {
    const ta = document.createElement("textarea");
    ta.value = text;
    ta.setAttribute("readonly", "");
    ta.style.position = "fixed";
    ta.style.top = "0";
    ta.style.left = "0";
    ta.style.opacity = "0";
    document.body.append(ta);
    ta.select();
    const ok = document.execCommand("copy");
    ta.remove();
    return ok;
  } catch {
    return false;
  }
}

export function InAppDownloadGuideProvider({
  children,
}: {
  children: ReactNode;
}) {
  const { t } = useI18n();
  const { showToast } = useToast();
  const [detail, setDetail] = useState<InAppDownloadGuideDetail | null>(null);

  useEffect(() => {
    const onShow = (event: Event) => {
      const ce = event as CustomEvent<InAppDownloadGuideDetail>;
      if (!ce.detail) return;
      setDetail(ce.detail);
    };
    window.addEventListener(IN_APP_DOWNLOAD_GUIDE_EVENT, onShow);
    return () =>
      window.removeEventListener(IN_APP_DOWNLOAD_GUIDE_EVENT, onShow);
  }, []);

  useEffect(() => {
    if (!detail) return;
    const onKey = (event: KeyboardEvent) => {
      if (event.key === "Escape") setDetail(null);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [detail]);

  const close = () => setDetail(null);

  const handleCopy = async () => {
    if (!detail) return;
    const ok = await copyTextToClipboard(detail.url);
    if (ok) {
      showToast(t("inAppDownloadCopied"));
    } else {
      showToast(t("inAppDownloadCopyFail"), "error");
    }
  };

  const browser = inAppBrowserName();
  const intro = browser
    ? t("inAppDownloadIntroNamed").replace("{browser}", browser)
    : t("inAppDownloadIntro");

  return (
    <>
      {children}
      {detail
        ? createPortal(
            <div
              role="dialog"
              aria-modal="true"
              aria-labelledby="in-app-download-guide-title"
              className="fixed inset-0 z-[140] flex items-center justify-center bg-black/70 px-4 backdrop-blur-sm"
              onClick={close}
            >
              <div
                className="w-full max-w-md overflow-hidden rounded-3xl border border-white/10 bg-[#1c1c21] text-neutral-100 shadow-2xl shadow-black/70"
                onClick={(event) => event.stopPropagation()}
              >
                <div className="flex items-start justify-between gap-4 border-b border-white/10 px-5 py-4">
                  <div className="min-w-0">
                    <p className="text-xs font-semibold uppercase tracking-[0.2em] text-ark-gold/80">
                      {t("download")}
                    </p>
                    <h2
                      id="in-app-download-guide-title"
                      className="mt-1 text-lg font-semibold text-white"
                    >
                      {t("inAppDownloadTitle")}
                    </h2>
                  </div>
                  <button
                    type="button"
                    onClick={close}
                    className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80"
                    aria-label={t("cancel")}
                  >
                    <X className="h-5 w-5" />
                  </button>
                </div>

                <div className="space-y-4 px-5 py-5">
                  <p className="text-sm leading-6 text-neutral-300">{intro}</p>

                  <ol className="space-y-3 text-sm leading-6 text-neutral-100">
                    <li className="flex gap-3">
                      <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-ark-gold text-sm font-bold text-black">
                        1
                      </span>
                      <span className="pt-0.5">
                        {t("inAppDownloadStepCopy")}
                      </span>
                    </li>
                    <li className="flex gap-3">
                      <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-ark-gold text-sm font-bold text-black">
                        2
                      </span>
                      <span className="pt-0.5">
                        {t("inAppDownloadStepOpen")}
                      </span>
                    </li>
                    <li className="flex gap-3">
                      <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-ark-gold text-sm font-bold text-black">
                        3
                      </span>
                      <span className="pt-0.5">
                        {t("inAppDownloadStepDownload")}
                      </span>
                    </li>
                  </ol>

                  <button
                    type="button"
                    onClick={handleCopy}
                    className="flex h-11 w-full items-center justify-center gap-2 rounded-full bg-ark-gold px-4 text-sm font-semibold text-black transition hover:bg-ark-gold2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1c1c21]"
                  >
                    <Copy className="h-4 w-4" />
                    {t("copyLink")}
                  </button>
                </div>
              </div>
            </div>,
            document.body,
          )
        : null}
    </>
  );
}
