import type { Request, Response } from "express";
import { QuotationService } from "../services/QuotationService.js";
import { z } from "zod";

const quotationService = new QuotationService();

const QuotationItemSchema = z.object({
  vegetableId: z.coerce.number().int().positive().optional().nullable(),
  vegName: z.string().min(1, { message: "Vegetable name is required" }),
  hsnCode: z.string().optional().nullable(),
  quantity: z.coerce.number().positive({ message: "Quantity must be greater than 0" }),
  unit: z.string().optional().default("Kg"),
  price: z.coerce.number().nonnegative({ message: "Price cannot be negative" }),
});

const QuotationSchema = z.object({
  customerId: z.coerce.number().int().positive().optional().nullable(),
  customerName: z.string().min(1, { message: "Customer name is required" }),
  quotationDate: z.string().min(1, { message: "Quotation date is required" }),
  extraCharge: z.coerce.number().nonnegative().optional().default(0),
  discount: z.coerce.number().nonnegative().optional().default(0),
  items: z.array(QuotationItemSchema).min(1, { message: "At least one item is required" }),
});

export const createQuotation = async (req: Request, res: Response): Promise<void> => {
  const parsed = QuotationSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({
      message: "Validation failed",
      errors: parsed.error.flatten().fieldErrors,
    });
    return;
  }

  try {
    const quotation = await quotationService.createQuotation({
      ...parsed.data,
      createdBy: req.user?.id ? BigInt(req.user.id) : null,
    });
    res.status(201).json({ message: "Quotation created successfully", result: quotation });
  } catch (err: any) {
    res.status(400).json({ message: err.message });
  }
};

export const updateQuotation = async (req: Request, res: Response): Promise<void> => {
  const parsed = QuotationSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({
      message: "Validation failed",
      errors: parsed.error.flatten().fieldErrors,
    });
    return;
  }

  try {
    const id = BigInt(req.params.id as string);
    const quotation = await quotationService.updateQuotation(id, parsed.data);
    res.json({ message: "Quotation updated successfully", result: quotation });
  } catch (err: any) {
    res.status(400).json({ message: err.message });
  }
};

export const getQuotations = async (req: Request, res: Response): Promise<void> => {
  try {
    const page = Number(req.query.page) || 1;
    const limit = Number(req.query.limit) || 10;
    const search = req.query.search ? String(req.query.search) : undefined;
    const dateFrom = req.query.dateFrom ? String(req.query.dateFrom) : undefined;
    const dateTo = req.query.dateTo ? String(req.query.dateTo) : undefined;

    const result = await quotationService.getQuotations(page, limit, search, dateFrom, dateTo);
    res.json({ message: "Quotations fetched successfully", result });
  } catch (err: any) {
    res.status(500).json({ message: err.message });
  }
};

export const getQuotationById = async (req: Request, res: Response): Promise<void> => {
  try {
    const quotation = await quotationService.getQuotationById(BigInt(req.params.id as string));
    res.json({ message: "Quotation fetched successfully", result: quotation });
  } catch (err: any) {
    res.status(404).json({ message: err.message });
  }
};

export const deleteQuotation = async (req: Request, res: Response): Promise<void> => {
  try {
    await quotationService.deleteQuotation(BigInt(req.params.id as string));
    res.json({ message: "Quotation deleted successfully" });
  } catch (err: any) {
    res.status(400).json({ message: err.message });
  }
};

export const printQuotationPdf = async (req: Request, res: Response): Promise<void> => {
  try {
    const id = BigInt(req.params.id as string);
    await quotationService.generatePdf(id, res);
  } catch (error: any) {
    res.status(500).json({ message: error.message });
  }
};
