import { Router } from "express";
import multer from "multer";
import path from "node:path";
import fs from "node:fs/promises";
import { getQbitClient } from "../qbit/qbit.context";
import { getArchiveStatus, setArchiveStatus } from "./torrent.archive";
import { nowIso } from "../utils/time";
import { appendAuditLog, logger } from "../utils/logger";
import { config } from "../config";

const router = Router();
const upload = multer({ dest: "/tmp" });

router.post("/select", async (req, res) => {
  const { hash } = req.body ?? {};
  if (!hash) {
    return res.status(400).json({ error: "Missing hash" });
  }
  const existing = await getArchiveStatus(hash);
  if (existing?.status === "READY") {
    return res.json({ ok: true, hash, archive: existing });
  }
  const qbit = getQbitClient();
  const torrents = await qbit.getTorrentsInfo();
  const torrent = torrents.find((t) => t.hash === hash);
  if (!torrent) {
    return res.status(404).json({ error: "Torrent not found" });
  }

  await setArchiveStatus({
    hash,
    status: "MISSING",
    updatedAt: nowIso(),
  });

  res.json({ ok: true, hash, archive: { status: "MISSING" } });
});

router.post("/archive/from-selected", async (req, res) => {
  const { hash } = req.body ?? {};
  if (!hash) {
    return res.status(400).json({ error: "Missing hash" });
  }
  const existing = await getArchiveStatus(hash);
  if (existing?.status === "READY") {
    return res.json({ ok: true, torrentFilePath: existing.torrentFilePath, source: existing.source });
  }
  await setArchiveStatus({
    hash,
    status: "MISSING",
    lastError: "Magnet export disabled; upload .torrent manually.",
    updatedAt: nowIso(),
  });
  await appendAuditLog({
    level: "WARN",
    event: "ARCHIVE_FAIL",
    message: `Archive generation disabled for ${hash}; manual upload required`,
  });
  return res.status(400).json({ error: "Magnet export disabled; upload .torrent manually." });
});

router.post("/archive/upload", upload.single("file"), async (req, res) => {
  const { hash } = req.body ?? {};
  if (!hash || !req.file) {
    return res.status(400).json({ error: "Missing hash or file" });
  }
  const inputHash = String(hash).toLowerCase();
  const buffer = await fs.readFile(req.file.path);
  let warning: string | undefined;
  try {
    const { default: parseTorrent } = await import("parse-torrent");
    const parsed = parseTorrent(buffer);
    const infoHash = String(parsed.infoHash ?? "").toLowerCase();
    if (infoHash && infoHash !== inputHash) {
      await fs.unlink(req.file.path);
      return res.status(400).json({
        error: "Torrent hash uyuşmuyor. Doğru .torrent dosyasını seçin.",
        expected: inputHash,
        actual: infoHash,
      });
    }
  } catch (error) {
    warning = "Torrent dosyası okunamadı; yine de arşive kaydedildi.";
    logger.warn({ error, hash: inputHash }, "Torrent parse failed; storing archive anyway");
  }
  const targetPath = path.join(config.torrentArchiveDir, `${hash}.torrent`);
  await fs.writeFile(targetPath, buffer);
  await fs.unlink(req.file.path);
  await setArchiveStatus({
    hash,
    status: "READY",
    torrentFilePath: targetPath,
    source: "manual",
    updatedAt: nowIso(),
  });
  try {
    const qbit = getQbitClient();
    await qbit.addTorrentByFile(targetPath);
    return res.json({
      ok: true,
      torrentFilePath: targetPath,
      added: true,
    });
  } catch (error) {
    return res.json({
      ok: true,
      torrentFilePath: targetPath,
      added: false,
    });
  }
});

router.get("/archive/status/:hash", async (req, res) => {
  const status = await getArchiveStatus(req.params.hash);
  if (!status) {
    return res.json({ hash: req.params.hash, status: "MISSING" });
  }
  return res.json(status);
});

export default router;
