import "server-only";

import { MediaProcessingError } from "@/lib/server/media-errors";

function normalizeHostName(hostName: string) {
  return hostName.trim().toLowerCase();
}

function normalizeInstagramPathName(pathName: string) {
  const segments = pathName.split("/").filter(Boolean);
  if (segments.length === 0) {
    return pathName;
  }

  // Instagram sometimes shares reel links as /reels/<id>, while extractors expect /reel/<id>.
  if (segments[0].toLowerCase() === "reels" && segments.length >= 2) {
    segments[0] = "reel";
    return `/${segments.join("/")}${pathName.endsWith("/") ? "/" : ""}`;
  }

  return pathName;
}

function isInstagramHost(hostName: string) {
  const normalizedHost = normalizeHostName(hostName);
  return (
    normalizedHost === "instagram.com" ||
    normalizedHost.endsWith(".instagram.com") ||
    normalizedHost === "instagr.am" ||
    normalizedHost.endsWith(".instagr.am")
  );
}

function isTwitterHost(hostName: string) {
  const normalizedHost = normalizeHostName(hostName);
  return (
    normalizedHost === "twitter.com" ||
    normalizedHost.endsWith(".twitter.com") ||
    normalizedHost === "x.com" ||
    normalizedHost.endsWith(".x.com")
  );
}

function isYoutubeHost(hostName: string) {
  const normalizedHost = normalizeHostName(hostName);
  return (
    normalizedHost === "youtube.com" ||
    normalizedHost.endsWith(".youtube.com") ||
    normalizedHost === "youtu.be" ||
    normalizedHost.endsWith(".youtu.be")
  );
}

function isTikTokHost(hostName: string) {
  const normalizedHost = normalizeHostName(hostName);
  return normalizedHost === "tiktok.com" || normalizedHost.endsWith(".tiktok.com");
}

function extractYoutubeVideoId(parsedUrl: URL) {
  const normalizedHost = normalizeHostName(parsedUrl.hostname);
  const pathSegments = parsedUrl.pathname.split("/").filter(Boolean);

  if (normalizedHost === "youtu.be" || normalizedHost.endsWith(".youtu.be")) {
    const shortId = pathSegments[0] || "";
    return shortId.trim() || null;
  }

  const firstSegment = pathSegments[0]?.toLowerCase() || "";
  if (firstSegment === "watch") {
    const watchId = parsedUrl.searchParams.get("v");
    return watchId?.trim() || null;
  }

  if (["shorts", "live", "embed", "v"].includes(firstSegment)) {
    const pathId = pathSegments[1] || "";
    return pathId.trim() || null;
  }

  return null;
}

export function validateInstagramVideoUrl(rawValue: unknown) {
  if (typeof rawValue !== "string" || !rawValue.trim()) {
    throw new MediaProcessingError({
      message: "Instagram URL is required.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  let parsedUrl: URL;

  try {
    parsedUrl = new URL(rawValue.trim());
  } catch {
    throw new MediaProcessingError({
      message: "Invalid URL format.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!["https:", "http:"].includes(parsedUrl.protocol)) {
    throw new MediaProcessingError({
      message: "Only http/https URLs are supported.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!isInstagramHost(parsedUrl.hostname)) {
    throw new MediaProcessingError({
      message: "Only Instagram links are supported by this tool.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!parsedUrl.pathname || parsedUrl.pathname === "/") {
    throw new MediaProcessingError({
      message: "Please provide a direct Instagram post, reel, or video URL.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  parsedUrl.pathname = normalizeInstagramPathName(parsedUrl.pathname);

  return parsedUrl.toString();
}

export function validateTwitterVideoUrl(rawValue: unknown) {
  if (typeof rawValue !== "string" || !rawValue.trim()) {
    throw new MediaProcessingError({
      message: "Twitter/X URL is required.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  let parsedUrl: URL;

  try {
    parsedUrl = new URL(rawValue.trim());
  } catch {
    throw new MediaProcessingError({
      message: "Invalid URL format.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!["https:", "http:"].includes(parsedUrl.protocol)) {
    throw new MediaProcessingError({
      message: "Only http/https URLs are supported.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!isTwitterHost(parsedUrl.hostname)) {
    throw new MediaProcessingError({
      message: "Only X/Twitter links are supported by this tool.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!parsedUrl.pathname || !parsedUrl.pathname.toLowerCase().includes("/status/")) {
    throw new MediaProcessingError({
      message: "Please provide a direct tweet/status URL that contains a video.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  return parsedUrl.toString();
}

export function validateYoutubeVideoUrl(rawValue: unknown) {
  if (typeof rawValue !== "string" || !rawValue.trim()) {
    throw new MediaProcessingError({
      message: "YouTube URL is required.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  let parsedUrl: URL;

  try {
    parsedUrl = new URL(rawValue.trim());
  } catch {
    throw new MediaProcessingError({
      message: "Invalid URL format.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!["https:", "http:"].includes(parsedUrl.protocol)) {
    throw new MediaProcessingError({
      message: "Only http/https URLs are supported.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!isYoutubeHost(parsedUrl.hostname)) {
    throw new MediaProcessingError({
      message: "Only YouTube links are supported by this tool.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!extractYoutubeVideoId(parsedUrl)) {
    throw new MediaProcessingError({
      message: "Please provide a direct YouTube video URL.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  return parsedUrl.toString();
}

export function validateTikTokVideoUrl(rawValue: unknown) {
  if (typeof rawValue !== "string" || !rawValue.trim()) {
    throw new MediaProcessingError({
      message: "TikTok URL is required.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  let parsedUrl: URL;

  try {
    parsedUrl = new URL(rawValue.trim());
  } catch {
    throw new MediaProcessingError({
      message: "Invalid URL format.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!["https:", "http:"].includes(parsedUrl.protocol)) {
    throw new MediaProcessingError({
      message: "Only http/https URLs are supported.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!isTikTokHost(parsedUrl.hostname)) {
    throw new MediaProcessingError({
      message: "Only TikTok links are supported by this tool.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  if (!parsedUrl.pathname || parsedUrl.pathname === "/") {
    throw new MediaProcessingError({
      message: "Please provide a direct TikTok video URL.",
      code: "invalid_input",
      statusCode: 400
    });
  }

  return parsedUrl.toString();
}
