import { Request, Response } from "express";
import { z } from "zod";
import { asyncHandler } from "../../core/asyncHandler";
import { AppError } from "../../core/AppError";
import { categoryService } from "./category.service";
import {io} from "../../server";

const paramsSchema = z.object({
    id: z.string().uuid()
});

const createSchema = z.object({
    name: z.string().min(1),
    color: z.string().optional(),
    imageUrl: z.string().optional().nullable(),
    displayOrder: z.number().optional()
});

const updateSchema = createSchema.partial().extend({
    active: z.boolean().optional()
});

const reorderSchema = z.object({
    orderedIds: z.array(z.string().uuid()).min(1)
});

export const getCategories = asyncHandler(
    async (req: Request, res: Response) => {
        const categories = await categoryService.findAll(req.shop!.id);
        res.json(categories);
    }
);

export const createCategory = asyncHandler(
    async (req: Request, res: Response) => {
        const data = createSchema.parse(req.body);

        const category = await categoryService.create(
            req.shop!.id,
            data
        );

        console.log(`category created send to shop ${req.shop!.id}`, category);
        io.to(`shop:${req.shop!.id}`).emit(
            "category:created",
            {
                category
            }
        );

        res.status(201).json(category);
    }
);

export const updateCategory = asyncHandler(
    async (req: Request, res: Response) => {
        const { id } = paramsSchema.parse(req.params);
        const data = updateSchema.parse(req.body);

        const existing = await categoryService.findById(
            req.shop!.id,
            id
        );

        if (!existing) {
            throw new AppError("Category not found", 404);
        }

        await categoryService.update(req.shop!.id, id, data);

        const updated = await categoryService.findById(
            req.shop!.id,
            id
        );

        io.to(`shop:${req.shop!.id}`).emit(
            "category:updated",
            {
                category: updated
            }
        );

        res.json(updated);
    }
);

export const reorderCategories = asyncHandler(
    async (req: Request, res: Response) => {
        const { orderedIds } = reorderSchema.parse(req.body);

        await categoryService.reorder(req.shop!.id, orderedIds);

        // Fetch fresh list to broadcast
        const categories = await categoryService.findAll(req.shop!.id);

        io.to(`shop:${req.shop!.id}`).emit("categories:reordered", { categories });

        res.json(categories);
    }
);

export const deleteCategory = asyncHandler(
    async (req: Request, res: Response) => {
        const { id } = paramsSchema.parse(req.params);

        const existing = await categoryService.findById(
            req.shop!.id,
            id
        );

        if (!existing) {
            throw new AppError("Category not found", 404);
        }

        await categoryService.softDelete(req.shop!.id, id);

        console.log(`category deleted send to shop ${req.shop!.id}`, id);
        io.to(`shop:${req.shop!.id}`).emit(
            "category:deleted",
            {
                id
            }
        );

        res.status(204).send();
    }
);