// External media imports — currently YouTube only.
//
// The flow mirrors upload.js: create the asset row up front with a placeholder
// filename (the worker fills in the real title once yt-dlp prints metadata),
// then enqueue a BullMQ job. The worker downloads, lands the file in S3 at the
// same originals/{assetId}/... path uploads use, and hands off to the existing
// proxy queue — so an imported asset travels the same lifecycle as any upload.

import express from 'express';
import { Queue } from 'bullmq';
import { v4 as uuidv4 } from 'uuid';
import pool from '../db/pool.js';
import { assertProjectAccess } from '../auth/authz.js';

const router = express.Router();

const parseRedisUrl = (url) => {
  try {
    const parsed = new URL(url);
    return { host: parsed.hostname, port: parseInt(parsed.port, 10) || 6379 };
  } catch {
    return { host: 'localhost', port: 6379 };
  }
};

const importQueue = new Queue('import', {
  connection: parseRedisUrl(process.env.REDIS_URL || 'redis://queue:6379'),
});

// Match the same three forms the client UI validates against. Server is the
// authoritative check — never trust the client to have validated.
const YT_PATTERNS = [
  /^https?:\/\/(?:www\.|m\.)?youtube\.com\/watch\?[^ ]*v=[A-Za-z0-9_-]{11}/i,
  /^https?:\/\/youtu\.be\/[A-Za-z0-9_-]{11}/i,
  /^https?:\/\/(?:www\.)?youtube\.com\/shorts\/[A-Za-z0-9_-]{11}/i,
];

function isYouTubeUrl(url) {
  return typeof url === 'string' && YT_PATTERNS.some((re) => re.test(url));
}

// POST /api/v1/imports/youtube — body { url, projectId, binId? }
router.post('/youtube', async (req, res, next) => {
  try {
    const { url, projectId, binId } = req.body || {};

    if (!url || !projectId) {
      return res.status(400).json({ error: 'url and projectId are required' });
    }
    if (!isYouTubeUrl(url)) {
      return res.status(400).json({ error: 'Invalid YouTube URL' });
    }
    // A playlist URL has `list=…` — yt-dlp's --no-playlist would still grab
    // the single video, but the operator probably meant "import the list" and
    // we don't support that yet. Reject so the intent is explicit.
    if (/[?&]list=/i.test(url)) {
      return res.status(400).json({ error: "Playlists aren't supported yet" });
    }

    const projCheck = await pool.query('SELECT id FROM projects WHERE id = $1', [projectId]);
    if (projCheck.rows.length === 0) {
      return res.status(404).json({ error: 'Project not found' });
    }
    // Importing writes an asset into the project — require edit access.
    await assertProjectAccess(req.user, projectId, 'edit');

    const assetId = uuidv4();

    // Placeholder filename/display_name — the worker overwrites both once
    // yt-dlp resolves the video title (usually within a second or two).
    await pool.query(
      `INSERT INTO assets (
        id, project_id, bin_id, filename, display_name, status,
        media_type, original_s3_key, source_url, created_at, updated_at
      )
      VALUES ($1, $2, $3, $4, $4, 'ingesting', 'video', NULL, $5, NOW(), NOW())`,
      [assetId, projectId, binId || null, url, url]
    );

    const bullJob = await importQueue.add('youtube', {
      assetId,
      url,
      // Surface the URL in the Jobs screen until the worker fills in the title.
      assetName: url,
    });

    res.status(202).json({
      assetId,
      jobId: `import:${bullJob.id}`,
      status: 'queued',
    });
  } catch (err) {
    next(err);
  }
});

export default router;
