import db from "@/db";
import { glob } from "glob";
import path from "path";
import fs from "fs";
import ffmpeg from "fluent-ffmpeg";

const VIDEO_EXTENSIONS = ["mp4", "mkv", "avi", "mov", "wmv", "flv", "webm", "m4v"];
const PHOTO_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "tiff", "svg"];

const generateVideoThumbnail = (videoPath: string, thumbnailPath: string) => {
  return new Promise((resolve, reject) => {
    ffmpeg(videoPath)
      .on("end", () => resolve(thumbnailPath))
      .on("error", (err) => reject(err))
      .screenshots({
        count: 1,
        folder: path.dirname(thumbnailPath),
        filename: path.basename(thumbnailPath),
        size: "320x240",
        timemarks: ["10%"]
      });
  });
};

const generatePhotoThumbnail = (photoPath: string, thumbnailPath: string) => {
  return new Promise((resolve, reject) => {
    ffmpeg(photoPath)
      .on("end", () => resolve(thumbnailPath))
      .on("error", (err) => reject(err))
      .outputOptions(["-vf", "scale=320:240:force_original_aspect_ratio=decrease", "-quality", "85"])
      .output(thumbnailPath)
      .run();
  });
};

const scanLibrary = async (library: { id: number; path: string }) => {
  // Scan videos
  const videoFiles = await glob(`${library.path}/**/*.{${VIDEO_EXTENSIONS.join(",")}}`, {
    nodir: true,
  });

  // Scan photos
  const photoFiles = await glob(`${library.path}/**/*.{${PHOTO_EXTENSIONS.join(",")}}`, {
    nodir: true,
  });

  const allFiles = [...videoFiles, ...photoFiles];

  for (const file of allFiles) {
    const stats = fs.statSync(file);
    const title = path.basename(file);
    const ext = path.extname(file).toLowerCase();
    const isVideo = VIDEO_EXTENSIONS.some(v => ext.includes(v));
    const isPhoto = PHOTO_EXTENSIONS.some(p => ext.includes(p));
    
    const mediaType = isVideo ? "video" : "photo";
    const thumbnailFileName = `${path.parse(title).name}_${Date.now()}.png`;
    const thumbnailPath = path.join(process.cwd(), "public", "thumbnails", thumbnailFileName);
    const thumbnailUrl = `/thumbnails/${thumbnailFileName}`;

    try {
      const existingMedia = db.prepare("SELECT * FROM media WHERE path = ?").get(file);
      if (existingMedia) {
        continue;
      }

      // Ensure thumbnails directory exists
      const thumbnailsDir = path.join(process.cwd(), "public", "thumbnails");
      if (!fs.existsSync(thumbnailsDir)) {
        fs.mkdirSync(thumbnailsDir, { recursive: true });
      }

      let finalThumbnailUrl = thumbnailUrl;
      let thumbnailGenerated = false;

      try {
        if (isVideo) {
          await generateVideoThumbnail(file, thumbnailPath);
          thumbnailGenerated = true;
        } else if (isPhoto) {
          await generatePhotoThumbnail(file, thumbnailPath);
          thumbnailGenerated = true;
        }
      } catch (thumbnailError) {
        console.warn(`Thumbnail generation failed for ${file}:`, thumbnailError);
        // Use fallback thumbnail based on media type
        finalThumbnailUrl = isVideo ? "/placeholder-video.svg" : "/placeholder-photo.svg";
      }

      const media = {
        library_id: library.id,
        path: file,
        type: mediaType,
        title: title,
        size: stats.size,
        thumbnail: finalThumbnailUrl,
      };

      db.prepare(
        "INSERT INTO media (library_id, path, type, title, size, thumbnail) VALUES (?, ?, ?, ?, ?, ?)"
      ).run(media.library_id, media.path, media.type, media.title, media.size, media.thumbnail);

      console.log(`Successfully inserted ${mediaType}: ${title}${thumbnailGenerated ? ' with thumbnail' : ' with fallback thumbnail'}`);
    } catch (error: any) {
      if (error.code !== "SQLITE_CONSTRAINT_UNIQUE") {
        console.error(`Error inserting media: ${file}`, error);
      }
    }
  }
};

export const scanAllLibraries = async () => {
  const libraries = db.prepare("SELECT * FROM libraries").all() as { id: number; path: string }[];
  for (const library of libraries) {
    await scanLibrary(library);
  }
};