import type { AuthenticatedRequest } from "../../../types/index.js";
import express, { type Request, type Response } from "express";
import { homepageLogger } from "../../utils/logger.js";
import {
  createCurrentHomepageItemRepository,
  createCurrentSyncTombstoneRepository,
} from "../repositories/factory.js";

export const homepageItemsRouter = express.Router();

/**
 * @openapi
 * /homepage/items:
 *   get:
 *     summary: Get homepage items
 *     description: Returns all homepage widget items for the authenticated user.
 *     tags:
 *       - Homepage
 *     responses:
 *       200:
 *         description: List of homepage items.
 *       500:
 *         description: Failed to fetch homepage items.
 */
homepageItemsRouter.get("/", async (req: Request, res: Response) => {
  const userId = (req as AuthenticatedRequest).userId;
  try {
    const items =
      await createCurrentHomepageItemRepository().listByUserId(userId);
    res.json(items);
  } catch (err) {
    homepageLogger.error("Failed to fetch homepage items", err);
    res.status(500).json({ error: "Failed to fetch homepage items" });
  }
});

/**
 * @openapi
 * /homepage/items:
 *   post:
 *     summary: Create homepage item
 *     description: Creates a new homepage widget item for the authenticated user.
 *     tags:
 *       - Homepage
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - typeId
 *             properties:
 *               typeId:
 *                 type: string
 *               title:
 *                 type: string
 *               config:
 *                 type: object
 *     responses:
 *       201:
 *         description: Homepage item created.
 *       400:
 *         description: Invalid data.
 *       500:
 *         description: Failed to create homepage item.
 */
homepageItemsRouter.post("/", async (req: Request, res: Response) => {
  const userId = (req as AuthenticatedRequest).userId;
  const { typeId, title, config } = req.body;

  if (!typeId || typeof typeId !== "string") {
    return res.status(400).json({ error: "typeId is required" });
  }

  try {
    const created = await createCurrentHomepageItemRepository().createForUser(
      userId,
      {
        typeId,
        title: title ?? null,
        config: config ? JSON.stringify(config) : "{}",
      },
    );
    res.status(201).json(created);
  } catch (err) {
    homepageLogger.error("Failed to create homepage item", err);
    res.status(500).json({ error: "Failed to create homepage item" });
  }
});

/**
 * @openapi
 * /homepage/items/{id}:
 *   put:
 *     summary: Update homepage item
 *     description: Updates a homepage widget item.
 *     tags:
 *       - Homepage
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: integer
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               title:
 *                 type: string
 *               config:
 *                 type: object
 *     responses:
 *       200:
 *         description: Homepage item updated.
 *       400:
 *         description: Invalid data.
 *       404:
 *         description: Not found.
 *       500:
 *         description: Failed to update homepage item.
 */
homepageItemsRouter.put("/:id", async (req: Request, res: Response) => {
  const userId = (req as AuthenticatedRequest).userId;
  const id = parseInt(req.params.id as string);
  if (isNaN(id)) return res.status(400).json({ error: "Invalid id" });

  const { title, config } = req.body;

  try {
    const itemRepository = createCurrentHomepageItemRepository();
    const existing = await itemRepository.findByIdForUser(userId, id);
    if (!existing) {
      return res.status(404).json({ error: "Not found" });
    }

    const updates: Parameters<typeof itemRepository.updateForUser>[2] = {};
    if (title !== undefined) updates.title = title;
    if (config !== undefined) updates.config = JSON.stringify(config);

    const updated = await itemRepository.updateForUser(userId, id, updates);
    res.json(updated ?? existing);
  } catch (err) {
    homepageLogger.error("Failed to update homepage item", err);
    res.status(500).json({ error: "Failed to update homepage item" });
  }
});

/**
 * @openapi
 * /homepage/items/{id}:
 *   delete:
 *     summary: Delete homepage item
 *     description: Deletes a homepage widget item and cascades deletion to children if a folder.
 *     tags:
 *       - Homepage
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: integer
 *     responses:
 *       200:
 *         description: Homepage item deleted.
 *       400:
 *         description: Invalid id.
 *       404:
 *         description: Not found.
 *       500:
 *         description: Failed to delete homepage item.
 */
homepageItemsRouter.delete("/:id", async (req: Request, res: Response) => {
  const userId = (req as AuthenticatedRequest).userId;
  const id = parseInt(req.params.id as string);
  if (isNaN(id)) return res.status(400).json({ error: "Invalid id" });

  try {
    const itemRepository = createCurrentHomepageItemRepository();
    const existing = await itemRepository.findByIdForUser(userId, id);
    if (!existing) {
      return res.status(404).json({ error: "Not found" });
    }

    const deleted = await itemRepository.deleteForUser(userId, id);
    if (deleted?.syncId) {
      await createCurrentSyncTombstoneRepository().record(
        userId,
        "homepageItems",
        deleted.syncId,
      );
    }
    res.json({ message: "Homepage item deleted" });
  } catch (err) {
    homepageLogger.error("Failed to delete homepage item", err);
    res.status(500).json({ error: "Failed to delete homepage item" });
  }
});
