import type { Express } from "express";
import { createServer, type Server } from "http";
import { storage } from "./storage";
import { insertArticleSchema } from "@shared/schema";
import { seedDatabase } from "./seed";
import multer from "multer";
import path from "path";
import fs from "fs";

const uploadDir = path.join(process.cwd(), "client/public/uploads");
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

const upload = multer({
  storage: multer.diskStorage({
    destination: (_req, _file, cb) => cb(null, uploadDir),
    filename: (_req, file, cb) => {
      const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
      const ext = path.extname(file.originalname);
      cb(null, uniqueSuffix + ext);
    },
  }),
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    const allowed = /jpeg|jpg|png|gif|webp/;
    const ext = allowed.test(path.extname(file.originalname).toLowerCase());
    const mime = allowed.test(file.mimetype);
    cb(null, ext && mime);
  },
});

export async function registerRoutes(
  httpServer: Server,
  app: Express
): Promise<Server> {
  await seedDatabase();

  app.get("/api/articles", async (_req, res) => {
    const articles = await storage.getArticles();
    res.json(articles);
  });

  app.get("/api/articles/featured", async (_req, res) => {
    const articles = await storage.getFeaturedArticles();
    res.json(articles);
  });

  app.get("/api/articles/popular", async (req, res) => {
    const limit = parseInt(req.query.limit as string) || 5;
    const articles = await storage.getPopularArticles(limit);
    res.json(articles);
  });

  app.get("/api/articles/category/:category", async (req, res) => {
    const articles = await storage.getArticlesByCategory(req.params.category);
    res.json(articles);
  });

  app.get("/api/articles/:slug", async (req, res) => {
    const article = await storage.getArticleBySlug(req.params.slug);
    if (!article) {
      return res.status(404).json({ message: "Article not found" });
    }
    await storage.incrementViews(article.id);
    res.json({ ...article, views: article.views + 1 });
  });

  app.post("/api/articles", async (req, res) => {
    const parsed = insertArticleSchema.safeParse(req.body);
    if (!parsed.success) {
      return res.status(400).json({ message: "Invalid article data", errors: parsed.error.flatten() });
    }
    const article = await storage.createArticle(parsed.data);
    res.status(201).json(article);
  });

  app.patch("/api/articles/:id", async (req, res) => {
    const id = parseInt(req.params.id);
    const partial = insertArticleSchema.partial().safeParse(req.body);
    if (!partial.success) {
      return res.status(400).json({ message: "Invalid article data", errors: partial.error.flatten() });
    }
    const article = await storage.updateArticle(id, partial.data);
    if (!article) {
      return res.status(404).json({ message: "Article not found" });
    }
    res.json(article);
  });

  app.delete("/api/articles/:id", async (req, res) => {
    const id = parseInt(req.params.id);
    await storage.deleteArticle(id);
    res.status(204).send();
  });

  app.post("/api/upload", upload.single("image"), (req, res) => {
    if (!req.file) {
      return res.status(400).json({ message: "No file uploaded" });
    }
    const url = `/uploads/${req.file.filename}`;
    res.json({ url });
  });

  return httpServer;
}
