import { Request, Response, NextFunction } from "express";
import { productCategoryService } from "./product.category.service";
import { catchAsyncError } from "../../middlewares/catchAsyncError";
import ErrorHandler from "../../middlewares/error";

export const productCategoryController = {
  // Create new category
  createCategory: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const data = req.body;

      // Validation
      if (!data.name || data.name.trim().length < 2) {
        return next(
          new ErrorHandler(
            "Category name is required and must be at least 2 characters",
            400,
          ),
        );
      }

      const category = await productCategoryService.createCategory(data);

      res.status(201).json({
        success: true,
        message: "Category created successfully",
        data: category,
      });
    },
  ),

  // Get category by ID
  getCategoryById: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const { id } = req.params;

      const category = await productCategoryService.getCategoryById(id);

      if (!category) {
        return next(new ErrorHandler("Category not found", 404));
      }

      // Increment view count
      await productCategoryService.incrementViewCount(id);

      res.status(200).json({
        success: true,
        data: category,
      });
    },
  ),

  // Get category by slug
  getCategoryBySlug: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const { slug } = req.params;

      const category = await productCategoryService.getCategoryBySlug(slug);

      if (!category) {
        return next(new ErrorHandler("Category not found", 404));
      }

      // Increment view count
      if (category.id) {
        await productCategoryService.incrementViewCount(category.id);
      }

      res.status(200).json({
        success: true,
        data: category,
      });
    },
  ),

  // Get all categories
  getAllCategories: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const {
        page = 1,
        limit = 20,
        is_active,
        is_featured,
        parent_id,
        search,
        sort_by,
        order = "asc",
      } = req.query;

      const filters = {
        page: parseInt(page as string),
        limit: parseInt(limit as string),
        is_active: is_active ? is_active === "true" : undefined,
        is_featured: is_featured ? is_featured === "true" : undefined,
        parent_id: parent_id as string,
        search: search as string,
        sort_by: sort_by as string,
        order: order as "asc" | "desc",
      };

      const result = await productCategoryService.getAllCategories(filters);

      res.status(200).json({
        success: true,
        ...result,
      });
    },
  ),

  // Update category
  updateCategory: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const { id } = req.params;
      const data = req.body;

      // Check if category exists
      const existingCategory = await productCategoryService.getCategoryById(id);
      if (!existingCategory) {
        return next(new ErrorHandler("Category not found", 404));
      }

      const updatedCategory = await productCategoryService.updateCategory(
        id,
        data,
      );

      res.status(200).json({
        success: true,
        message: "Category updated successfully",
        data: updatedCategory,
      });
    },
  ),

  // Delete category
  deleteCategory: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const { id } = req.params;

      // Check if category exists
      const existingCategory = await productCategoryService.getCategoryById(id);
      if (!existingCategory) {
        return next(new ErrorHandler("Category not found", 404));
      }

      const deletedCategory = await productCategoryService.deleteCategory(id);

      res.status(200).json({
        success: true,
        message: "Category deleted successfully",
        data: deletedCategory,
      });
    },
  ),

  // Get category tree
  getCategoryTree: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const categoryTree = await productCategoryService.getCategoryTree();

      res.status(200).json({
        success: true,
        data: categoryTree,
      });
    },
  ),

  // Get featured categories
  getFeaturedCategories: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const limit = parseInt(req.query.limit as string) || 8;

      const featuredCategories =
        await productCategoryService.getFeaturedCategories(limit);

      res.status(200).json({
        success: true,
        data: featuredCategories,
      });
    },
  ),

  // Bulk update categories (reorder, etc.)
  bulkUpdateCategories: catchAsyncError(
    async (req: Request, res: Response, next: NextFunction) => {
      const { updates } = req.body;

      if (!Array.isArray(updates) || updates.length === 0) {
        return next(new ErrorHandler("Updates array is required", 400));
      }

      const results = [];
      for (const update of updates) {
        const { id, sort_order, parent_id, is_active } = update;

        if (!id) {
          continue;
        }

        const updateData: any = {};
        if (sort_order !== undefined) updateData.sort_order = sort_order;
        if (parent_id !== undefined) updateData.parent_id = parent_id;
        if (is_active !== undefined) updateData.is_active = is_active;

        if (Object.keys(updateData).length > 0) {
          const updated = await productCategoryService.updateCategory(
            id,
            updateData,
          );
          results.push(updated);
        }
      }

      res.status(200).json({
        success: true,
        message: "Categories updated successfully",
        data: results,
      });
    },
  ),
};
