const express = require("express");
const Report = require("../models/Report");
const User = require("../models/User");
const Street = require("../models/Street");
const auth = require("../middleware/auth");
const { asyncHandler } = require("../middleware/errorHandler");
const {
  createReportValidation,
  reportIdValidation,
} = require("../middleware/validators/reportValidator");
const { upload, handleUploadError } = require("../middleware/upload");
const { uploadImage, deleteImage } = require("../config/cloudinary");

const router = express.Router();

// Get all reports (with pagination)
router.get(
  "/",
  asyncHandler(async (req, res) => {
    const page = parseInt(req.query.page) || 1;
    const limit = Math.min(parseInt(req.query.limit) || 10, 100);

    const result = await Report.findWithPagination({
      page,
      limit,
      sort: { createdAt: -1 },
    });

    res.json({
      reports: result.docs,
      totalCount: result.totalDocs,
      currentPage: result.page,
      totalPages: result.totalPages,
      hasNext: result.hasNextPage,
      hasPrev: result.hasPrevPage,
    });
  }),
);

// Create a report with optional image
router.post(
  "/",
  auth,
  upload.single("image"),
  handleUploadError,
  createReportValidation,
  asyncHandler(async (req, res) => {
    const { street: streetId, issue } = req.body;

    // Get street and user data for embedding
    const street = await Street.findById(streetId);
    if (!street) {
      return res.status(404).json({ msg: "Street not found" });
    }

    const user = await User.findById(req.user.id);
    if (!user) {
      return res.status(404).json({ msg: "User not found" });
    }

    const reportData = {
      street: {
        _id: street._id,
        name: street.name,
      },
      user: {
        _id: user._id,
        name: user.name,
        profilePicture: user.profilePicture,
      },
      issue,
    };

    // Upload image if provided
    if (req.file) {
      const result = await uploadImage(
        req.file.buffer,
        "adopt-a-street/reports",
      );
      reportData.imageUrl = result.url;
      reportData.cloudinaryPublicId = result.publicId;
    }

    const report = await Report.create(reportData);
    res.json(report);
  }),
);

// Add image to existing report
router.post(
  "/:id/image",
  auth,
  upload.single("image"),
  handleUploadError,
  reportIdValidation,
  asyncHandler(async (req, res) => {
    const report = await Report.findById(req.params.id);
    if (!report) {
      return res.status(404).json({ msg: "Report not found" });
    }

    // Verify user owns the report
    if (report.user._id !== req.user.id) {
      return res.status(403).json({ msg: "Not authorized" });
    }

    if (!req.file) {
      return res.status(400).json({ msg: "No image file provided" });
    }

    // Delete old image if exists
    if (report.cloudinaryPublicId) {
      await deleteImage(report.cloudinaryPublicId);
    }

    // Upload new image
    const result = await uploadImage(
      req.file.buffer,
      "adopt-a-street/reports",
    );

    const updatedReport = await Report.update(req.params.id, {
      imageUrl: result.url,
      cloudinaryPublicId: result.publicId,
    });

    res.json(updatedReport);
  }),
);

// Resolve a report
router.put(
  "/:id",
  auth,
  reportIdValidation,
  asyncHandler(async (req, res) => {
    const report = await Report.findById(req.params.id);
    if (!report) {
      return res.status(404).json({ msg: "Report not found" });
    }

    const updatedReport = await Report.update(req.params.id, {
      status: "resolved",
    });

    res.json(updatedReport);
  }),
);

module.exports = router;
