import { promises as fs } from "fs";
import { getVideoConfig } from "@/lib/generation/video-config";
import { resolveLocalMediaPath } from "@/lib/storage/media-files";

export interface YouTubePublishResult {
  success: boolean;
  postId?: string;
  permalink?: string;
  error?: string;
}

function extractHashtags(caption: string): string[] {
  return (caption.match(/#[\w]+/g) ?? []).map((t) => t.replace(/^#/, "")).slice(0, 10);
}

function titleFromCaption(caption: string, fallback: string): string {
  const first = caption
    .replace(/#[\w]+/g, "")
    .split(/(?<=[.!?])\s+/)
    .find((s) => s.trim().length > 10);
  const raw = (first ?? caption).trim().slice(0, 95);
  return raw.length >= 10 ? raw : fallback.slice(0, 95);
}

/**
 * YouTube Data API resumable upload — requires a local MP4 (post.videoUrl → data/media/).
 */
export async function publishToYouTube(input: {
  accessToken: string;
  channelId: string;
  caption: string;
  videoUrl?: string | null;
  title?: string;
}): Promise<YouTubePublishResult> {
  if (!input.videoUrl) {
    return {
      success: false,
      error:
        "YouTube requires a video. Enable VIDEO_PROVIDER=ffmpeg and regenerate the post, or publish to LinkedIn/Facebook/Instagram.",
    };
  }

  const filePath = resolveLocalMediaPath(input.videoUrl);
  if (!filePath) {
    return {
      success: false,
      error: "Video file not found on server. Regenerate the post with VIDEO_PROVIDER=ffmpeg.",
    };
  }

  let fileBuffer: Buffer;
  try {
    fileBuffer = await fs.readFile(filePath);
  } catch {
    return { success: false, error: `Cannot read video file: ${filePath}` };
  }

  if (!fileBuffer.length) {
    return { success: false, error: "Video file is empty." };
  }

  const cfg = getVideoConfig();
  const title = titleFromCaption(input.caption, input.title ?? "PostSync Pro Update");
  const description = input.caption.slice(0, 4900);
  const tags = extractHashtags(input.caption);

  const initRes = await fetch(
    "https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${input.accessToken}`,
        "Content-Type": "application/json",
        "X-Upload-Content-Type": "video/mp4",
        "X-Upload-Content-Length": String(fileBuffer.length),
      },
      body: JSON.stringify({
        snippet: {
          title,
          description,
          tags: tags.length ? tags : undefined,
          categoryId: "22",
        },
        status: {
          privacyStatus: cfg.youtubePrivacy,
          selfDeclaredMadeForKids: false,
        },
      }),
    },
  );

  if (!initRes.ok) {
    const err = (await initRes.json().catch(() => ({}))) as { error?: { message?: string } };
    return {
      success: false,
      error: err.error?.message ?? `YouTube upload init failed (${initRes.status})`,
    };
  }

  const uploadUrl = initRes.headers.get("location");
  if (!uploadUrl) {
    return { success: false, error: "YouTube did not return an upload URL." };
  }

  const uploadRes = await fetch(uploadUrl, {
    method: "PUT",
    headers: {
      "Content-Type": "video/mp4",
      "Content-Length": String(fileBuffer.length),
    },
    body: new Uint8Array(fileBuffer),
  });

  const uploadData = (await uploadRes.json().catch(() => ({}))) as {
    id?: string;
    snippet?: { title?: string };
    error?: { message?: string };
  };

  if (!uploadRes.ok || !uploadData.id) {
    return {
      success: false,
      error: uploadData.error?.message ?? `YouTube upload failed (${uploadRes.status})`,
    };
  }

  return {
    success: true,
    postId: uploadData.id,
    permalink: `https://www.youtube.com/watch?v=${uploadData.id}`,
  };
}
