"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/components/VideoPlayer/VideoPlayer.tsx
var VideoPlayer_exports = {};
__export(VideoPlayer_exports, {
  default: () => VideoPlayer_default
});
module.exports = __toCommonJS(VideoPlayer_exports);
var import_react4 = require("react");
var import_react_dom = require("react-dom");
var import_phosphor_react2 = require("phosphor-react");

// src/utils/utils.ts
var import_clsx = require("clsx");
var import_tailwind_merge = require("tailwind-merge");
function cn(...inputs) {
  return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
}

// src/components/IconButton/IconButton.tsx
var import_react = require("react");
var import_jsx_runtime = require("react/jsx-runtime");
var IconButton = (0, import_react.forwardRef)(
  ({ icon, size = "md", active = false, className = "", disabled, ...props }, ref) => {
    const baseClasses = [
      "inline-flex",
      "items-center",
      "justify-center",
      "rounded-lg",
      "font-medium",
      "bg-transparent",
      "text-text-950",
      "cursor-pointer",
      "hover:bg-primary-600",
      "hover:text-text",
      "focus-visible:outline-none",
      "focus-visible:ring-2",
      "focus-visible:ring-offset-0",
      "focus-visible:ring-indicator-info",
      "disabled:opacity-50",
      "disabled:cursor-not-allowed",
      "disabled:pointer-events-none"
    ];
    const sizeClasses = {
      sm: ["w-6", "h-6", "text-sm"],
      md: ["w-10", "h-10", "text-base"]
    };
    const activeClasses = active ? ["!bg-primary-50", "!text-primary-950", "hover:!bg-primary-100"] : [];
    const allClasses = [
      ...baseClasses,
      ...sizeClasses[size],
      ...activeClasses
    ].join(" ");
    const ariaLabel = props["aria-label"] ?? "Bot\xE3o de a\xE7\xE3o";
    return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      "button",
      {
        ref,
        type: "button",
        className: cn(allClasses, className),
        disabled,
        "aria-pressed": active,
        "aria-label": ariaLabel,
        ...props,
        children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex items-center justify-center", children: icon })
      }
    );
  }
);
IconButton.displayName = "IconButton";
var IconButton_default = IconButton;

// src/components/Text/Text.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var Text = ({
  children,
  size = "md",
  weight = "normal",
  color = "text-text-950",
  as,
  className = "",
  ...props
}) => {
  let sizeClasses;
  let weightClasses;
  const sizeClassMap = {
    "2xs": "text-2xs",
    xs: "text-xs",
    sm: "text-sm",
    md: "text-md",
    lg: "text-lg",
    xl: "text-xl",
    "2xl": "text-2xl",
    "3xl": "text-3xl",
    "4xl": "text-4xl",
    "5xl": "text-5xl",
    "6xl": "text-6xl"
  };
  sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;
  const weightClassMap = {
    hairline: "font-hairline",
    light: "font-light",
    normal: "font-normal",
    medium: "font-medium",
    semibold: "font-semibold",
    bold: "font-bold",
    extrabold: "font-extrabold",
    black: "font-black"
  };
  weightClasses = weightClassMap[weight] ?? weightClassMap.normal;
  const baseClasses = "font-primary";
  const Component = as ?? "p";
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
    Component,
    {
      className: cn(baseClasses, sizeClasses, weightClasses, color, className),
      ...props,
      children
    }
  );
};
var Text_default = Text;

// src/hooks/useMobile.ts
var import_react2 = require("react");
var MOBILE_WIDTH = 500;
var TABLET_WIDTH = 931;
var SMALL_MOBILE_WIDTH = 425;
var EXTRA_SMALL_MOBILE_WIDTH = 375;
var ULTRA_SMALL_MOBILE_WIDTH = 375;
var TINY_MOBILE_WIDTH = 320;
var DEFAULT_WIDTH = 1200;
var getWindowWidth = () => {
  if (typeof window === "undefined") {
    return DEFAULT_WIDTH;
  }
  return window.innerWidth;
};
var getDeviceType = () => {
  const width = getWindowWidth();
  return width < TABLET_WIDTH ? "responsive" : "desktop";
};
var useMobile = () => {
  const [isMobile, setIsMobile] = (0, import_react2.useState)(false);
  const [isTablet, setIsTablet] = (0, import_react2.useState)(false);
  const [isSmallMobile, setIsSmallMobile] = (0, import_react2.useState)(false);
  const [isExtraSmallMobile, setIsExtraSmallMobile] = (0, import_react2.useState)(false);
  const [isUltraSmallMobile, setIsUltraSmallMobile] = (0, import_react2.useState)(false);
  const [isTinyMobile, setIsTinyMobile] = (0, import_react2.useState)(false);
  (0, import_react2.useEffect)(() => {
    const checkScreenSize = () => {
      const width = getWindowWidth();
      setIsMobile(width < MOBILE_WIDTH);
      setIsTablet(width < TABLET_WIDTH);
      setIsSmallMobile(width < SMALL_MOBILE_WIDTH);
      setIsExtraSmallMobile(width < EXTRA_SMALL_MOBILE_WIDTH);
      setIsUltraSmallMobile(width < ULTRA_SMALL_MOBILE_WIDTH);
      setIsTinyMobile(width < TINY_MOBILE_WIDTH);
    };
    checkScreenSize();
    window.addEventListener("resize", checkScreenSize);
    return () => window.removeEventListener("resize", checkScreenSize);
  }, []);
  const getFormContainerClasses = () => {
    if (isMobile) {
      return "w-full px-4";
    }
    if (isTablet) {
      return "w-full px-6";
    }
    return "w-full max-w-[992px] mx-auto px-0";
  };
  const getMobileHeaderClasses = () => {
    return "flex flex-col items-start gap-4 mb-6";
  };
  const getDesktopHeaderClasses = () => {
    return "flex flex-row justify-between items-center gap-6 mb-8";
  };
  const getHeaderClasses = () => {
    return isMobile ? getMobileHeaderClasses() : getDesktopHeaderClasses();
  };
  const getVideoContainerClasses = () => {
    if (isTinyMobile) return "aspect-square";
    if (isExtraSmallMobile) return "aspect-[4/3]";
    if (isSmallMobile) return "aspect-[16/12]";
    return "aspect-video";
  };
  return {
    isMobile,
    isTablet,
    isSmallMobile,
    isExtraSmallMobile,
    isUltraSmallMobile,
    isTinyMobile,
    getFormContainerClasses,
    getHeaderClasses,
    getMobileHeaderClasses,
    getDesktopHeaderClasses,
    getVideoContainerClasses,
    getDeviceType
  };
};

// src/components/DownloadButton/DownloadButton.tsx
var import_react3 = require("react");
var import_phosphor_react = require("phosphor-react");
var import_jsx_runtime3 = require("react/jsx-runtime");
var getMimeType = (url) => {
  const extension = getFileExtension(url);
  const mimeTypes = {
    pdf: "application/pdf",
    png: "image/png",
    jpg: "image/jpeg",
    jpeg: "image/jpeg",
    mp3: "audio/mpeg",
    mp4: "video/mp4",
    vtt: "text/vtt"
  };
  return mimeTypes[extension] || "application/octet-stream";
};
var triggerDownload = async (url, filename) => {
  try {
    const response = await fetch(url, {
      mode: "cors",
      credentials: "same-origin"
    });
    if (!response.ok) {
      throw new Error(
        `Failed to fetch file: ${response.status} ${response.statusText}`
      );
    }
    const blob = await response.blob();
    const mimeType = getMimeType(url);
    const typedBlob = new Blob([blob], { type: mimeType });
    const blobUrl = URL.createObjectURL(typedBlob);
    const link = document.createElement("a");
    link.href = blobUrl;
    link.download = filename;
    link.rel = "noopener noreferrer";
    document.body.appendChild(link);
    link.click();
    link.remove();
    setTimeout(() => {
      URL.revokeObjectURL(blobUrl);
    }, 1e3);
  } catch (error) {
    console.warn("Fetch download failed, falling back to direct link:", error);
    const link = document.createElement("a");
    link.href = url;
    link.download = filename;
    link.rel = "noopener noreferrer";
    link.target = "_blank";
    document.body.appendChild(link);
    link.click();
    link.remove();
  }
};
var getFileExtension = (url) => {
  try {
    const u = new URL(url, globalThis.location?.origin || "http://localhost");
    url = u.pathname;
  } catch {
  }
  const path = url.split(/[?#]/)[0];
  const dot = path.lastIndexOf(".");
  return dot > -1 ? path.slice(dot + 1).toLowerCase() : "file";
};
var generateFilename = (contentType, url, lessonTitle = "aula") => {
  const sanitizedTitle = lessonTitle.toLowerCase().replaceAll(/[^a-z0-9\s]/g, "").replaceAll(/\s+/g, "-").substring(0, 50);
  const extension = getFileExtension(url);
  return `${sanitizedTitle}-${contentType}.${extension}`;
};
var DownloadButton = ({
  content,
  className,
  onDownloadStart,
  onDownloadComplete,
  onDownloadError,
  lessonTitle = "aula",
  disabled = false
}) => {
  const [isDownloading, setIsDownloading] = (0, import_react3.useState)(false);
  const isValidUrl = (0, import_react3.useCallback)((url) => {
    return Boolean(
      url && url.trim() !== "" && url !== "undefined" && url !== "null"
    );
  }, []);
  const getAvailableContent = (0, import_react3.useCallback)(() => {
    const downloads = [];
    if (isValidUrl(content.urlDoc)) {
      downloads.push({
        type: "documento",
        url: content.urlDoc,
        label: "Documento"
      });
    }
    if (isValidUrl(content.urlInitialFrame)) {
      downloads.push({
        type: "quadro-inicial",
        url: content.urlInitialFrame,
        label: "Quadro Inicial"
      });
    }
    if (isValidUrl(content.urlFinalFrame)) {
      downloads.push({
        type: "quadro-final",
        url: content.urlFinalFrame,
        label: "Quadro Final"
      });
    }
    if (isValidUrl(content.urlPodcast)) {
      downloads.push({
        type: "podcast",
        url: content.urlPodcast,
        label: "Podcast"
      });
    }
    if (isValidUrl(content.urlVideo)) {
      downloads.push({ type: "video", url: content.urlVideo, label: "V\xEDdeo" });
    }
    return downloads;
  }, [content, isValidUrl]);
  const handleDownload = (0, import_react3.useCallback)(async () => {
    if (disabled || isDownloading) return;
    const availableContent = getAvailableContent();
    if (availableContent.length === 0) {
      return;
    }
    setIsDownloading(true);
    try {
      for (let i = 0; i < availableContent.length; i++) {
        const item = availableContent[i];
        try {
          onDownloadStart?.(item.type);
          const filename = generateFilename(item.type, item.url, lessonTitle);
          await triggerDownload(item.url, filename);
          onDownloadComplete?.(item.type);
          if (i < availableContent.length - 1) {
            await new Promise((resolve) => setTimeout(resolve, 200));
          }
        } catch (error) {
          onDownloadError?.(
            item.type,
            error instanceof Error ? error : new Error(`Falha ao baixar ${item.label}`)
          );
        }
      }
    } finally {
      setIsDownloading(false);
    }
  }, [
    disabled,
    isDownloading,
    getAvailableContent,
    lessonTitle,
    onDownloadStart,
    onDownloadComplete,
    onDownloadError
  ]);
  const hasContent = getAvailableContent().length > 0;
  if (!hasContent) {
    return null;
  }
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("flex items-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
    IconButton_default,
    {
      icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.DownloadSimple, { size: 24 }),
      onClick: handleDownload,
      disabled: disabled || isDownloading,
      "aria-label": (() => {
        if (isDownloading) {
          return "Baixando conte\xFAdo...";
        }
        const contentCount = getAvailableContent().length;
        const suffix = contentCount > 1 ? "s" : "";
        return `Baixar conte\xFAdo da aula (${contentCount} arquivo${suffix})`;
      })(),
      className: cn(
        "!bg-transparent hover:!bg-black/10 transition-colors",
        isDownloading && "opacity-60 cursor-not-allowed"
      )
    }
  ) });
};
var DownloadButton_default = DownloadButton;

// src/components/VideoPlayer/VideoPlayer.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
var CONTROLS_HIDE_TIMEOUT = 3e3;
var LEAVE_HIDE_TIMEOUT = 1e3;
var INIT_DELAY = 100;
var formatTime = (seconds) => {
  if (!seconds || Number.isNaN(seconds)) return "0:00";
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, "0")}`;
};
var ProgressBar = ({
  currentTime,
  duration,
  progressPercentage,
  onSeek,
  className = "px-4 pb-2"
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
  "input",
  {
    type: "range",
    min: 0,
    max: duration || 100,
    value: currentTime,
    onChange: (e) => onSeek(Number.parseFloat(e.target.value)),
    className: "w-full h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer slider:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-primary-500",
    "aria-label": "Video progress",
    style: {
      background: `linear-gradient(to right, var(--color-primary-700) ${progressPercentage}%, var(--color-secondary-300) ${progressPercentage}%)`
    }
  }
) });
var VolumeControls = ({
  volume,
  isMuted,
  onVolumeChange,
  onToggleMute,
  iconSize = 24,
  showSlider = true
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
    IconButton_default,
    {
      icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.SpeakerSlash, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.SpeakerHigh, { size: iconSize }),
      onClick: onToggleMute,
      "aria-label": isMuted ? "Unmute" : "Mute",
      className: "!bg-transparent !text-white hover:!bg-white/20"
    }
  ),
  showSlider && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
    "input",
    {
      type: "range",
      min: 0,
      max: 100,
      value: Math.round(volume * 100),
      onChange: (e) => onVolumeChange(Number.parseInt(e.target.value)),
      className: "w-20 h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500",
      "aria-label": "Volume control",
      style: {
        background: `linear-gradient(to right, var(--color-primary-700) ${volume * 100}%, var(--color-secondary-300) ${volume * 100}%)`
      }
    }
  )
] });
var SpeedMenu = ({
  showSpeedMenu,
  playbackRate,
  onToggleMenu,
  onSpeedChange,
  isFullscreen,
  iconSize = 24,
  isTinyMobile = false
}) => {
  const buttonRef = (0, import_react4.useRef)(null);
  const speedMenuContainerRef = (0, import_react4.useRef)(null);
  const speedMenuRef = (0, import_react4.useRef)(null);
  const getMenuPosition = () => {
    if (!buttonRef.current) return { top: 0, left: 0 };
    const rect = buttonRef.current.getBoundingClientRect();
    const menuHeight = isTinyMobile ? 150 : 180;
    const menuWidth = isTinyMobile ? 60 : 80;
    const padding = isTinyMobile ? 4 : 8;
    return {
      // Fixed coords are viewport-based — no scroll offsets.
      top: Math.max(padding, rect.top - menuHeight),
      left: Math.max(padding, rect.right - menuWidth)
    };
  };
  const position = getMenuPosition();
  (0, import_react4.useEffect)(() => {
    const handleClickOutside = (event) => {
      const target = event.target;
      const isOutsideContainer = speedMenuContainerRef.current && !speedMenuContainerRef.current.contains(target);
      const isOutsideMenu = speedMenuRef.current && !speedMenuRef.current.contains(target);
      if (isOutsideContainer && isOutsideMenu) {
        onToggleMenu();
      }
    };
    if (showSpeedMenu) {
      document.addEventListener("mousedown", handleClickOutside);
    }
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [showSpeedMenu, onToggleMenu]);
  const menuContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
    "div",
    {
      ref: speedMenuRef,
      role: "menu",
      "aria-label": "Playback speed",
      className: isFullscreen ? "absolute bottom-12 right-0 bg-background border border-border-100 rounded-lg shadow-lg p-2 min-w-24 z-[9999]" : "fixed bg-background border border-border-100 rounded-lg shadow-lg p-2 min-w-24 z-[9999]",
      style: isFullscreen ? void 0 : {
        top: `${position.top}px`,
        left: `${position.left}px`
      },
      children: [0.5, 0.75, 1, 1.25, 1.5, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
        "button",
        {
          role: "menuitemradio",
          "aria-checked": playbackRate === speed,
          onClick: () => onSpeedChange(speed),
          className: `block w-full text-left px-3 py-1 text-sm rounded hover:bg-border-50 transition-colors ${playbackRate === speed ? "bg-primary-950 text-secondary-100 font-medium" : "text-text-950"}`,
          children: [
            speed,
            "x"
          ]
        },
        speed
      ))
    }
  );
  const portalContent = showSpeedMenu && globalThis.window !== void 0 && globalThis.document !== void 0 && !!globalThis.document?.body ? (0, import_react_dom.createPortal)(menuContent, globalThis.document.body) : null;
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative", ref: speedMenuContainerRef, children: [
    /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
      IconButton_default,
      {
        ref: buttonRef,
        icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.DotsThreeVertical, { size: iconSize }),
        onClick: onToggleMenu,
        "aria-label": "Playback speed",
        "aria-haspopup": "menu",
        "aria-expanded": showSpeedMenu,
        className: "!bg-transparent !text-white hover:!bg-white/20"
      }
    ),
    showSpeedMenu && (isFullscreen ? menuContent : portalContent)
  ] });
};
var VideoPlayer = ({
  src,
  poster,
  subtitles,
  title,
  subtitle: subtitleText,
  initialTime = 0,
  onTimeUpdate,
  onProgress,
  onVideoComplete,
  className,
  autoSave = true,
  storageKey = "video-progress",
  userId,
  downloadContent,
  showDownloadButton = false,
  onDownloadStart,
  onDownloadComplete,
  onDownloadError
}) => {
  const videoRef = (0, import_react4.useRef)(null);
  const { isUltraSmallMobile, isTinyMobile } = useMobile();
  const [isPlaying, setIsPlaying] = (0, import_react4.useState)(false);
  const [currentTime, setCurrentTime] = (0, import_react4.useState)(0);
  const [duration, setDuration] = (0, import_react4.useState)(0);
  const [isMuted, setIsMuted] = (0, import_react4.useState)(false);
  const [volume, setVolume] = (0, import_react4.useState)(1);
  const [isFullscreen, setIsFullscreen] = (0, import_react4.useState)(false);
  const [showControls, setShowControls] = (0, import_react4.useState)(true);
  const [hasCompleted, setHasCompleted] = (0, import_react4.useState)(false);
  const [showCaptions, setShowCaptions] = (0, import_react4.useState)(false);
  const [subtitlesValidation, setSubtitlesValidation] = (0, import_react4.useState)("idle");
  (0, import_react4.useEffect)(() => {
    setHasCompleted(false);
  }, [src]);
  const [playbackRate, setPlaybackRate] = (0, import_react4.useState)(1);
  const [showSpeedMenu, setShowSpeedMenu] = (0, import_react4.useState)(false);
  const lastSaveTimeRef = (0, import_react4.useRef)(0);
  const trackRef = (0, import_react4.useRef)(null);
  const controlsTimeoutRef = (0, import_react4.useRef)(null);
  const lastMousePositionRef = (0, import_react4.useRef)({ x: 0, y: 0 });
  const isUserInteracting = (0, import_react4.useCallback)(() => {
    if (showSpeedMenu) {
      return true;
    }
    const activeElement = document.activeElement;
    const videoContainer = videoRef.current?.parentElement;
    if (activeElement && videoContainer?.contains(activeElement)) {
      if (activeElement === videoRef.current) {
        return false;
      }
      const isControl = activeElement.matches("button, input, [tabindex]");
      if (isControl) {
        return true;
      }
    }
    return false;
  }, [showSpeedMenu]);
  const clearControlsTimeout = (0, import_react4.useCallback)(() => {
    if (controlsTimeoutRef.current) {
      clearTimeout(controlsTimeoutRef.current);
      controlsTimeoutRef.current = null;
    }
  }, []);
  const showControlsWithTimer = (0, import_react4.useCallback)(() => {
    setShowControls(true);
    clearControlsTimeout();
    if (isFullscreen) {
      if (isPlaying) {
        controlsTimeoutRef.current = globalThis.setTimeout(() => {
          setShowControls(false);
        }, CONTROLS_HIDE_TIMEOUT);
      }
    } else {
      controlsTimeoutRef.current = globalThis.setTimeout(() => {
        setShowControls(false);
      }, CONTROLS_HIDE_TIMEOUT);
    }
  }, [isFullscreen, isPlaying, clearControlsTimeout]);
  const handleMouseMove = (0, import_react4.useCallback)(
    (event) => {
      const currentX = event.clientX;
      const currentY = event.clientY;
      const lastPos = lastMousePositionRef.current;
      const hasMoved = Math.abs(currentX - lastPos.x) > 5 || Math.abs(currentY - lastPos.y) > 5;
      if (hasMoved) {
        lastMousePositionRef.current = { x: currentX, y: currentY };
        showControlsWithTimer();
      }
    },
    [showControlsWithTimer]
  );
  const handleMouseEnter = (0, import_react4.useCallback)(() => {
    showControlsWithTimer();
  }, [showControlsWithTimer]);
  const handleMouseLeave = (0, import_react4.useCallback)(() => {
    const userInteracting = isUserInteracting();
    clearControlsTimeout();
    if (!isFullscreen && !userInteracting) {
      controlsTimeoutRef.current = globalThis.setTimeout(() => {
        setShowControls(false);
      }, LEAVE_HIDE_TIMEOUT);
    }
  }, [isFullscreen, clearControlsTimeout, isUserInteracting]);
  (0, import_react4.useEffect)(() => {
    if (videoRef.current) {
      videoRef.current.volume = volume;
      videoRef.current.muted = isMuted;
    }
  }, [volume, isMuted]);
  (0, import_react4.useEffect)(() => {
    const video = videoRef.current;
    if (!video) return;
    const onPlay = () => setIsPlaying(true);
    const onPause = () => setIsPlaying(false);
    const onEnded = () => setIsPlaying(false);
    video.addEventListener("play", onPlay);
    video.addEventListener("pause", onPause);
    video.addEventListener("ended", onEnded);
    return () => {
      video.removeEventListener("play", onPlay);
      video.removeEventListener("pause", onPause);
      video.removeEventListener("ended", onEnded);
    };
  }, []);
  (0, import_react4.useEffect)(() => {
    const video = videoRef.current;
    if (!video) return;
    video.setAttribute("playsinline", "");
    video.setAttribute("webkit-playsinline", "");
  }, []);
  (0, import_react4.useEffect)(() => {
    if (isPlaying) {
      showControlsWithTimer();
    } else {
      clearControlsTimeout();
      if (isFullscreen) {
        setShowControls(true);
      } else {
        showControlsWithTimer();
      }
    }
  }, [isPlaying, isFullscreen, showControlsWithTimer, clearControlsTimeout]);
  (0, import_react4.useEffect)(() => {
    const video = videoRef.current;
    if (!video) return;
    const handleFullscreenChange = () => {
      const isCurrentlyFullscreen = !!document.fullscreenElement;
      setIsFullscreen(isCurrentlyFullscreen);
      if (isCurrentlyFullscreen) {
        showControlsWithTimer();
      }
    };
    const handleWebkitBeginFullscreen = () => {
      setIsFullscreen(true);
      showControlsWithTimer();
    };
    const handleWebkitEndFullscreen = () => {
      setIsFullscreen(false);
    };
    document.addEventListener("fullscreenchange", handleFullscreenChange);
    video.addEventListener(
      "webkitbeginfullscreen",
      handleWebkitBeginFullscreen
    );
    video.addEventListener("webkitendfullscreen", handleWebkitEndFullscreen);
    return () => {
      document.removeEventListener("fullscreenchange", handleFullscreenChange);
      video.removeEventListener(
        "webkitbeginfullscreen",
        handleWebkitBeginFullscreen
      );
      video.removeEventListener(
        "webkitendfullscreen",
        handleWebkitEndFullscreen
      );
    };
  }, [showControlsWithTimer]);
  (0, import_react4.useEffect)(() => {
    const init = () => {
      if (!isFullscreen) {
        showControlsWithTimer();
      }
    };
    let raf1 = 0, raf2 = 0, tid;
    if (globalThis.requestAnimationFrame === void 0) {
      tid = globalThis.setTimeout(init, INIT_DELAY);
      return () => {
        if (tid) clearTimeout(tid);
      };
    } else {
      raf1 = requestAnimationFrame(() => {
        raf2 = requestAnimationFrame(init);
      });
      return () => {
        cancelAnimationFrame(raf1);
        cancelAnimationFrame(raf2);
      };
    }
  }, []);
  const getInitialTime = (0, import_react4.useCallback)(() => {
    if (!autoSave || !storageKey) {
      return Number.isFinite(initialTime) && initialTime >= 0 ? initialTime : void 0;
    }
    const scopedKey = userId ? `${storageKey}-${userId}` : storageKey;
    const saved = Number(
      localStorage.getItem(`${scopedKey}-${src}`) || Number.NaN
    );
    const hasValidInitial = Number.isFinite(initialTime) && initialTime >= 0;
    const hasValidSaved = Number.isFinite(saved) && saved >= 0;
    if (hasValidInitial) return initialTime;
    if (hasValidSaved) return saved;
    return void 0;
  }, [autoSave, storageKey, userId, src, initialTime]);
  (0, import_react4.useEffect)(() => {
    const start = getInitialTime();
    if (start !== void 0 && videoRef.current) {
      videoRef.current.currentTime = start;
      setCurrentTime(start);
    }
  }, [getInitialTime]);
  const saveProgress = (0, import_react4.useCallback)(
    (time) => {
      if (!autoSave || !storageKey) return;
      const now = Date.now();
      if (now - lastSaveTimeRef.current > 5e3) {
        const scopedKey = userId ? `${storageKey}-${userId}` : storageKey;
        localStorage.setItem(`${scopedKey}-${src}`, time.toString());
        lastSaveTimeRef.current = now;
      }
    },
    [autoSave, storageKey, userId, src]
  );
  const togglePlayPause = (0, import_react4.useCallback)(async () => {
    const video = videoRef.current;
    if (!video) return;
    if (!video.paused) {
      video.pause();
      return;
    }
    try {
      await video.play();
    } catch {
    }
  }, []);
  const handleVolumeChange = (0, import_react4.useCallback)(
    (newVolume) => {
      const video = videoRef.current;
      if (!video) return;
      const volumeValue = newVolume / 100;
      video.volume = volumeValue;
      setVolume(volumeValue);
      const shouldMute = volumeValue === 0;
      const shouldUnmute = volumeValue > 0 && isMuted;
      if (shouldMute) {
        video.muted = true;
        setIsMuted(true);
      } else if (shouldUnmute) {
        video.muted = false;
        setIsMuted(false);
      }
    },
    [isMuted]
  );
  const toggleMute = (0, import_react4.useCallback)(() => {
    const video = videoRef.current;
    if (!video) return;
    if (isMuted) {
      const restoreVolume = volume > 0 ? volume : 0.5;
      video.volume = restoreVolume;
      video.muted = false;
      setVolume(restoreVolume);
      setIsMuted(false);
    } else {
      video.muted = true;
      setIsMuted(true);
    }
  }, [isMuted, volume]);
  const handleSeek = (0, import_react4.useCallback)((newTime) => {
    const video = videoRef.current;
    if (video) {
      video.currentTime = newTime;
    }
  }, []);
  const isSafariIOS = (0, import_react4.useCallback)(() => {
    const ua = navigator.userAgent;
    const isIOS = /iPad|iPhone|iPod/.test(ua);
    const isWebKit = /WebKit/.test(ua);
    const isNotChrome = !/CriOS|Chrome/.test(ua);
    return isIOS && isWebKit && isNotChrome;
  }, []);
  const toggleFullscreen = (0, import_react4.useCallback)(() => {
    const video = videoRef.current;
    const container = video?.parentElement;
    if (!video || !container) return;
    if (isSafariIOS()) {
      const videoElement = video;
      if (!isFullscreen && videoElement.webkitEnterFullscreen) {
        videoElement.webkitEnterFullscreen();
      } else if (isFullscreen && videoElement.webkitExitFullscreen) {
        videoElement.webkitExitFullscreen();
      }
    } else if (!isFullscreen && container.requestFullscreen) {
      container.requestFullscreen();
    } else if (isFullscreen && document.exitFullscreen) {
      document.exitFullscreen();
    }
  }, [isFullscreen, isSafariIOS]);
  const handleSpeedChange = (0, import_react4.useCallback)((speed) => {
    if (videoRef.current) {
      videoRef.current.playbackRate = speed;
      setPlaybackRate(speed);
      setShowSpeedMenu(false);
    }
  }, []);
  const toggleSpeedMenu = (0, import_react4.useCallback)(() => {
    setShowSpeedMenu(!showSpeedMenu);
  }, [showSpeedMenu]);
  const toggleCaptions = (0, import_react4.useCallback)(() => {
    if (!trackRef.current?.track || !subtitles || subtitlesValidation !== "valid")
      return;
    const newShowCaptions = !showCaptions;
    setShowCaptions(newShowCaptions);
    trackRef.current.track.mode = newShowCaptions ? "showing" : "hidden";
  }, [showCaptions, subtitles, subtitlesValidation]);
  const checkVideoCompletion = (0, import_react4.useCallback)(
    (progressPercent) => {
      if (progressPercent >= 95 && !hasCompleted) {
        setHasCompleted(true);
        onVideoComplete?.();
      }
    },
    [hasCompleted, onVideoComplete]
  );
  const handleTimeUpdate = (0, import_react4.useCallback)(() => {
    const video = videoRef.current;
    if (!video) return;
    const current = video.currentTime;
    setCurrentTime(current);
    saveProgress(current);
    onTimeUpdate?.(current);
    if (duration > 0) {
      const progressPercent = current / duration * 100;
      onProgress?.(progressPercent);
      checkVideoCompletion(progressPercent);
    }
  }, [duration, saveProgress, onTimeUpdate, onProgress, checkVideoCompletion]);
  const handleLoadedMetadata = (0, import_react4.useCallback)(() => {
    if (videoRef.current) {
      setDuration(videoRef.current.duration);
    }
  }, []);
  (0, import_react4.useEffect)(() => {
    const controller = new AbortController();
    const validateSubtitles = async () => {
      if (!subtitles) {
        setSubtitlesValidation("idle");
        return;
      }
      setSubtitlesValidation("validating");
      try {
        if (subtitles.startsWith("data:")) {
          setSubtitlesValidation("valid");
          return;
        }
        const response = await fetch(subtitles, {
          method: "HEAD",
          signal: controller.signal
        });
        if (response.ok) {
          const contentType = response.headers.get("content-type");
          const isValidType = !contentType || contentType.includes("text/vtt") || contentType.includes("text/plain") || contentType.includes("application/octet-stream");
          if (isValidType) {
            setSubtitlesValidation("valid");
          } else {
            setSubtitlesValidation("invalid");
            console.warn(
              `Subtitles URL has invalid content type: ${contentType}`
            );
          }
        } else {
          setSubtitlesValidation("invalid");
          console.warn(
            `Subtitles URL returned status: ${response.status} ${response.statusText}`
          );
        }
      } catch (error) {
        if (error instanceof Error && error.name === "AbortError") {
          return;
        }
        console.warn("Subtitles URL validation failed:", error);
        setSubtitlesValidation("invalid");
      }
    };
    validateSubtitles();
    return () => {
      controller.abort();
    };
  }, [subtitles]);
  (0, import_react4.useEffect)(() => {
    if (trackRef.current?.track) {
      trackRef.current.track.mode = showCaptions && subtitles && subtitlesValidation === "valid" ? "showing" : "hidden";
    }
  }, [subtitles, showCaptions, subtitlesValidation]);
  (0, import_react4.useEffect)(() => {
    const handleVisibilityChange = () => {
      if (document.hidden && isPlaying && videoRef.current) {
        videoRef.current.pause();
        setIsPlaying(false);
      }
    };
    const handleBlur = () => {
      if (isPlaying && videoRef.current) {
        videoRef.current.pause();
        setIsPlaying(false);
      }
    };
    document.addEventListener("visibilitychange", handleVisibilityChange);
    globalThis.addEventListener("blur", handleBlur);
    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
      globalThis.removeEventListener("blur", handleBlur);
      clearControlsTimeout();
    };
  }, [isPlaying, clearControlsTimeout]);
  const progressPercentage = duration > 0 ? currentTime / duration * 100 : 0;
  const getIconSize = (0, import_react4.useCallback)(() => {
    if (isTinyMobile) return 18;
    if (isUltraSmallMobile) return 20;
    return 24;
  }, [isTinyMobile, isUltraSmallMobile]);
  const getControlsPadding = (0, import_react4.useCallback)(() => {
    if (isTinyMobile) return "px-2 pb-2 pt-1";
    if (isUltraSmallMobile) return "px-3 pb-3 pt-1";
    return "px-4 pb-4";
  }, [isTinyMobile, isUltraSmallMobile]);
  const getControlsGap = (0, import_react4.useCallback)(() => {
    if (isTinyMobile) return "gap-1";
    if (isUltraSmallMobile) return "gap-2";
    return "gap-4";
  }, [isTinyMobile, isUltraSmallMobile]);
  const getProgressBarPadding = (0, import_react4.useCallback)(() => {
    if (isTinyMobile) return "px-2 pb-1";
    if (isUltraSmallMobile) return "px-3 pb-1";
    return "px-4 pb-2";
  }, [isTinyMobile, isUltraSmallMobile]);
  const getCenterPlayButtonPosition = (0, import_react4.useCallback)(() => {
    if (isTinyMobile) return "items-center justify-center -translate-y-12";
    if (isUltraSmallMobile) return "items-center justify-center -translate-y-8";
    return "items-center justify-center";
  }, [isTinyMobile, isUltraSmallMobile]);
  const getTopControlsOpacity = (0, import_react4.useCallback)(() => {
    return showControls ? "opacity-100" : "opacity-0";
  }, [showControls]);
  const getBottomControlsOpacity = (0, import_react4.useCallback)(() => {
    return showControls ? "opacity-100" : "opacity-0";
  }, [showControls]);
  const seekBackward = (0, import_react4.useCallback)(() => {
    if (videoRef.current) {
      videoRef.current.currentTime -= 10;
    }
  }, []);
  const seekForward = (0, import_react4.useCallback)(() => {
    if (videoRef.current) {
      videoRef.current.currentTime += 10;
    }
  }, []);
  const increaseVolume = (0, import_react4.useCallback)(() => {
    handleVolumeChange(Math.min(100, volume * 100 + 10));
  }, [handleVolumeChange, volume]);
  const decreaseVolume = (0, import_react4.useCallback)(() => {
    handleVolumeChange(Math.max(0, volume * 100 - 10));
  }, [handleVolumeChange, volume]);
  const handleVideoKeyDown = (0, import_react4.useCallback)(
    (e) => {
      if (!e.key) return;
      e.stopPropagation();
      showControlsWithTimer();
      const keyHandlers = {
        " ": togglePlayPause,
        Enter: togglePlayPause,
        ArrowLeft: seekBackward,
        ArrowRight: seekForward,
        ArrowUp: increaseVolume,
        ArrowDown: decreaseVolume,
        m: toggleMute,
        M: toggleMute,
        f: toggleFullscreen,
        F: toggleFullscreen
      };
      const handler = keyHandlers[e.key];
      if (handler) {
        e.preventDefault();
        handler();
      }
    },
    [
      showControlsWithTimer,
      togglePlayPause,
      seekBackward,
      seekForward,
      increaseVolume,
      decreaseVolume,
      toggleMute,
      toggleFullscreen
    ]
  );
  const groupedSubTitleValid = subtitles && subtitlesValidation === "valid";
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("flex flex-col", className), children: [
    (title || subtitleText) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "bg-subject-1 px-8 py-4 flex items-end justify-between min-h-20", children: [
      /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col gap-1", children: [
        title && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
          Text_default,
          {
            as: "h2",
            size: "lg",
            weight: "bold",
            color: "text-text-900",
            className: "leading-5 tracking-wide",
            children: title
          }
        ),
        subtitleText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
          Text_default,
          {
            as: "p",
            size: "sm",
            weight: "normal",
            color: "text-text-600",
            className: "leading-5",
            children: subtitleText
          }
        )
      ] }),
      showDownloadButton && downloadContent && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
        DownloadButton_default,
        {
          content: downloadContent,
          lessonTitle: title,
          onDownloadStart,
          onDownloadComplete,
          onDownloadError,
          className: "flex-shrink-0"
        }
      )
    ] }),
    /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
      "section",
      {
        className: cn(
          "relative w-full bg-background overflow-hidden group",
          "rounded-b-xl",
          // Hide cursor when controls are hidden and video is playing
          isPlaying && !showControls ? "cursor-none group-hover:cursor-default" : "cursor-default"
        ),
        "aria-label": title ? `Video player: ${title}` : "Video player",
        onMouseMove: handleMouseMove,
        onMouseEnter: handleMouseEnter,
        onTouchStart: handleMouseEnter,
        onMouseLeave: handleMouseLeave,
        children: [
          /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
            "video",
            {
              ref: videoRef,
              src,
              poster,
              className: "w-full h-full object-contain analytica-video",
              controlsList: "nodownload",
              playsInline: true,
              onTimeUpdate: handleTimeUpdate,
              onLoadedMetadata: handleLoadedMetadata,
              onClick: togglePlayPause,
              onKeyDown: handleVideoKeyDown,
              tabIndex: 0,
              "aria-label": title ? `Video: ${title}` : "Video player",
              children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                "track",
                {
                  ref: trackRef,
                  kind: "captions",
                  src: groupedSubTitleValid ? subtitles : "data:text/vtt;charset=utf-8,WEBVTT",
                  srcLang: "pt-br",
                  label: groupedSubTitleValid ? "Legendas em Portugu\xEAs" : "Sem legendas dispon\xEDveis",
                  default: false
                }
              )
            }
          ),
          !isPlaying && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
            "div",
            {
              className: cn(
                "absolute inset-0 flex bg-black/30 transition-opacity",
                getCenterPlayButtonPosition()
              ),
              children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                IconButton_default,
                {
                  icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.Play, { size: 32, weight: "regular", className: "ml-1" }),
                  onClick: togglePlayPause,
                  "aria-label": "Play video",
                  className: "!bg-transparent !text-white !w-auto !h-auto hover:!bg-transparent hover:!text-gray-200"
                }
              )
            }
          ),
          /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
            "div",
            {
              className: cn(
                "absolute top-0 left-0 right-0 p-4 bg-gradient-to-b from-black/70 to-transparent transition-opacity",
                getTopControlsOpacity()
              ),
              children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                IconButton_default,
                {
                  icon: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.ArrowsInSimple, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.ArrowsOutSimple, { size: 24 }),
                  onClick: toggleFullscreen,
                  "aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
                  className: "!bg-transparent !text-white hover:!bg-white/20"
                }
              ) })
            }
          ),
          /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
            "div",
            {
              className: cn(
                "absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/90 to-transparent transition-opacity",
                getBottomControlsOpacity()
              ),
              children: [
                /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                  ProgressBar,
                  {
                    currentTime,
                    duration,
                    progressPercentage,
                    onSeek: handleSeek,
                    className: getProgressBarPadding()
                  }
                ),
                /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
                  "div",
                  {
                    className: cn(
                      "flex items-center justify-between",
                      getControlsPadding()
                    ),
                    children: [
                      /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("flex items-center", getControlsGap()), children: [
                        /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                          IconButton_default,
                          {
                            icon: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.Pause, { size: getIconSize() }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.Play, { size: getIconSize() }),
                            onClick: togglePlayPause,
                            "aria-label": isPlaying ? "Pause" : "Play",
                            className: "!bg-transparent !text-white hover:!bg-white/20"
                          }
                        ),
                        /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                          VolumeControls,
                          {
                            volume,
                            isMuted,
                            onVolumeChange: handleVolumeChange,
                            onToggleMute: toggleMute,
                            iconSize: getIconSize(),
                            showSlider: !isUltraSmallMobile
                          }
                        ),
                        groupedSubTitleValid && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                          IconButton_default,
                          {
                            icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.ClosedCaptioning, { size: getIconSize() }),
                            onClick: toggleCaptions,
                            "aria-label": showCaptions ? "Hide captions" : "Show captions",
                            className: cn(
                              "!bg-transparent hover:!bg-white/20",
                              showCaptions ? "!text-primary-400" : "!text-white"
                            )
                          }
                        ),
                        /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text_default, { size: "sm", weight: "medium", color: "text-white", children: [
                          formatTime(currentTime),
                          " / ",
                          formatTime(duration)
                        ] })
                      ] }),
                      /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
                        SpeedMenu,
                        {
                          showSpeedMenu,
                          playbackRate,
                          onToggleMenu: toggleSpeedMenu,
                          onSpeedChange: handleSpeedChange,
                          iconSize: getIconSize(),
                          isTinyMobile,
                          isFullscreen
                        }
                      ) })
                    ]
                  }
                )
              ]
            }
          )
        ]
      }
    )
  ] });
};
var VideoPlayer_default = VideoPlayer;
//# sourceMappingURL=index.js.map