import { X } from "lucide-react";
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import { createPortal } from "react-dom";
import { useI18n } from "../i18n";
import type { Attachment } from "../types/post";

export type SaveToAlbumMediaKind = "image" | "video";

type SaveToAlbumGuideContextValue = {
  showSaveToAlbumGuide: (kind: SaveToAlbumMediaKind) => void;
};

const SaveToAlbumGuideContext =
  createContext<SaveToAlbumGuideContextValue | null>(null);

export function useSaveToAlbumGuide(): SaveToAlbumGuideContextValue {
  const ctx = useContext(SaveToAlbumGuideContext);
  if (!ctx) {
    throw new Error(
      "useSaveToAlbumGuide must be used within SaveToAlbumGuideProvider",
    );
  }
  return ctx;
}

export function mediaSaveKindFromAttachment(
  attachment: Attachment,
): SaveToAlbumMediaKind | null {
  if (attachment.kind === "image" || attachment.mime.startsWith("image/")) {
    return "image";
  }
  if (attachment.kind === "video" || attachment.mime.startsWith("video/")) {
    return "video";
  }
  return null;
}

export function mediaSaveKindFromType(
  type: string | undefined,
): SaveToAlbumMediaKind | null {
  if (type === "image") return "image";
  if (type === "video") return "video";
  return null;
}

type SavePlatform = "ios" | "android" | "desktop";

const saveAlbumGuideMobileMediaQuery = "(max-width: 760px)";

function shouldShowSaveAlbumGuide(): boolean {
  if (typeof window === "undefined" || !window.matchMedia) return false;
  return window.matchMedia(saveAlbumGuideMobileMediaQuery).matches;
}

function detectSavePlatform(): SavePlatform {
  if (typeof navigator === "undefined") return "desktop";
  const ua = navigator.userAgent || "";
  if (/android/i.test(ua)) return "android";
  if (/iPad|iPhone|iPod/i.test(ua)) return "ios";
  if (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
    return "ios";
  }
  return "desktop";
}

function platformStepKeys(platform: SavePlatform): string[] {
  if (platform === "ios") {
    return [
      "saveAlbumGuideIosStep1",
      "saveAlbumGuideIosStep2",
      "saveAlbumGuideIosStep3",
    ];
  }
  if (platform === "android") {
    return [
      "saveAlbumGuideAndroidStep1",
      "saveAlbumGuideAndroidStep2",
      "saveAlbumGuideAndroidStep3",
    ];
  }
  return ["saveAlbumGuideDesktopStep1", "saveAlbumGuideDesktopStep2"];
}

export function SaveToAlbumGuideProvider({
  children,
}: {
  children: ReactNode;
}) {
  const { t } = useI18n();
  const [mediaKind, setMediaKind] = useState<SaveToAlbumMediaKind | null>(null);
  const platform = useMemo(() => detectSavePlatform(), []);

  const showSaveToAlbumGuide = useCallback((kind: SaveToAlbumMediaKind) => {
    if (!shouldShowSaveAlbumGuide()) return;
    setMediaKind(kind);
  }, []);

  const close = useCallback(() => setMediaKind(null), []);

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

  const value = useMemo(
    () => ({ showSaveToAlbumGuide }),
    [showSaveToAlbumGuide],
  );

  return (
    <SaveToAlbumGuideContext.Provider value={value}>
      {children}
      {mediaKind
        ? createPortal(
            <div
              className="fixed inset-0 z-[130] flex items-center justify-center bg-black/70 px-4 backdrop-blur-sm"
              role="dialog"
              aria-modal="true"
              aria-labelledby="save-album-guide-title"
              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>
                    <p className="text-xs font-semibold uppercase tracking-[0.2em] text-ark-gold/80">
                      {mediaKind === "video"
                        ? t("saveAlbumGuideVideoLabel")
                        : t("saveAlbumGuideImageLabel")}
                    </p>
                    <h2
                      id="save-album-guide-title"
                      className="mt-1 text-lg font-semibold text-white"
                    >
                      {t("saveAlbumGuideTitle")}
                    </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="px-5 py-5">
                  <p className="text-sm leading-6 text-neutral-300">
                    {t("saveAlbumGuideIntro")}
                  </p>
                  <ol className="mt-4 space-y-3">
                    {platformStepKeys(platform).map((key, index) => (
                      <li key={key} 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">
                          {index + 1}
                        </span>
                        <span className="pt-0.5 text-sm leading-6 text-neutral-100">
                          {t(key)}
                        </span>
                      </li>
                    ))}
                  </ol>
                  <button
                    type="button"
                    onClick={close}
                    className="mt-5 flex h-11 w-full items-center justify-center 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]"
                  >
                    {t("confirm")}
                  </button>
                </div>
              </div>
            </div>,
            document.body,
          )
        : null}
    </SaveToAlbumGuideContext.Provider>
  );
}
