import { Router, Request, Response, NextFunction } from 'express';
import { PrismaClient } from '@prisma/client';
import Joi from 'joi';

const router = Router();
const prisma = new PrismaClient();

// Validation schemas
const ingredientSchema = Joi.object({
  recipeNumber: Joi.string().required().max(20),
  ingredients: Joi.string().required(),
});

const updateIngredientSchema = ingredientSchema.fork(['recipeNumber'], (schema) => schema.optional());

// Get all ingredients with search and pagination
router.get('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { 
      search = '', 
      category = '', 
      page = '1', 
      limit = '10',
      sortBy = 'recipeNumber',
      sortOrder = 'asc'
    } = req.query;

    const pageNum = parseInt(page as string);
    const limitNum = parseInt(limit as string);
    const skip = (pageNum - 1) * limitNum;

    const where: any = {};
    
    if (search) {
      where.OR = [
        { recipeNumber: { contains: search as string } },
        { ingredients: { contains: search as string } },
      ];
    }
    
    if (category) {
      where.recipeNumber = { contains: category as string };
    }

    const [ingredients, total] = await Promise.all([
      prisma.ingredient.findMany({
        where,
        orderBy: { [sortBy as string]: sortOrder as 'asc' | 'desc' },
        skip,
        take: limitNum,
      }),
      prisma.ingredient.count({ where })
    ]);

    return res.json({
      success: true,
      data: ingredients,
      pagination: {
        page: pageNum,
        limit: limitNum,
        total,
        pages: Math.ceil(total / limitNum),
      },
    });
  } catch (error) {
    next(error);
  }
});

// Get single ingredient by ID
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params;
    
    if (!id) {
      return res.status(400).json({
        success: false,
        message: 'Ingredient ID is required',
      });
    }
    
    const ingredient = await prisma.ingredient.findUnique({
      where: { id: parseInt(id) }
    });

    if (!ingredient) {
      return res.status(404).json({
        success: false,
        message: 'Ingredient not found',
      });
    }

    return res.json({
      success: true,
      data: ingredient,
    });
  } catch (error) {
    next(error);
  }
});

// Create new ingredient
router.post('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { error, value } = ingredientSchema.validate(req.body);
    
    if (error) {
      return res.status(400).json({
        success: false,
        message: 'Validation error',
        details: error.details,
      });
    }

    const ingredient = await prisma.ingredient.create({
      data: value
    });

    return res.status(201).json({
      success: true,
      data: ingredient,
      message: 'Ingredient created successfully',
    });
  } catch (error) {
    next(error);
  }
});

// Update ingredient
router.put('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params;
    
    if (!id) {
      return res.status(400).json({
        success: false,
        message: 'Ingredient ID is required',
      });
    }
    
    const { error, value } = updateIngredientSchema.validate(req.body);
    
    if (error) {
      return res.status(400).json({
        success: false,
        message: 'Validation error',
        details: error.details,
      });
    }

    const ingredient = await prisma.ingredient.update({
      where: { id: parseInt(id) },
      data: value
    });

    return res.json({
      success: true,
      data: ingredient,
      message: 'Ingredient updated successfully',
    });
  } catch (error) {
    next(error);
  }
});

// Delete ingredient
router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params;
    
    if (!id) {
      return res.status(400).json({
        success: false,
        message: 'Ingredient ID is required',
      });
    }
    
    await prisma.ingredient.delete({
      where: { id: parseInt(id) }
    });

    return res.json({
      success: true,
      message: 'Ingredient deleted successfully',
    });
  } catch (error) {
    next(error);
  }
});

export default router;