import { Request, Response } from 'express';
import prisma from '../config/database';
import { sendSuccess, sendError } from '../utils/response.utils';
import { AuthenticatedRequest } from '../middleware/auth.middleware';

// 1. List all coupons
export const getCoupons = async (req: Request, res: Response) => {
  try {
    const coupons = await prisma.coupon.findMany({
      orderBy: { createdAt: 'desc' },
    });
    return sendSuccess(res, 'Coupons retrieved successfully', { coupons });
  } catch (error: any) {
    return sendError(res, 'Failed to fetch coupons', error.message, 500);
  }
};

// 2. Create a new coupon
export const createCoupon = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { code, discountType, discountValue, minOrderValue, maxDiscount, usageLimit, expiresAt, isActive } = req.body;

    const existing = await prisma.coupon.findUnique({ where: { code: code.toUpperCase() } });
    if (existing) return sendError(res, 'Coupon code already exists', null, 400);

    const coupon = await prisma.coupon.create({
      data: {
        code: code.toUpperCase(),
        discountType, // e.g. PERCENTAGE, FIXED_AMOUNT
        discountValue: Number(discountValue),
        minOrderValue: minOrderValue ? Number(minOrderValue) : null,
        maxDiscount: maxDiscount ? Number(maxDiscount) : null,
        usageLimit: usageLimit ? parseInt(usageLimit) : null,
        expiresAt: new Date(expiresAt),
        isActive: isActive ?? true,
      },
    });

    return sendSuccess(res, 'Coupon created successfully', { coupon });
  } catch (error: any) {
    return sendError(res, 'Failed to create coupon', error.message, 500);
  }
};

// 3. Edit coupon settings
export const updateCoupon = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    const { code, discountType, discountValue, minOrderValue, maxDiscount, usageLimit, expiresAt, isActive } = req.body;

    const coupon = await prisma.coupon.findUnique({ where: { id } });
    if (!coupon) return sendError(res, 'Coupon not found', null, 404);

    const updated = await prisma.coupon.update({
      where: { id },
      data: {
        code: code ? code.toUpperCase() : undefined,
        discountType,
        discountValue: discountValue ? Number(discountValue) : undefined,
        minOrderValue: minOrderValue !== undefined ? (minOrderValue ? Number(minOrderValue) : null) : undefined,
        maxDiscount: maxDiscount !== undefined ? (maxDiscount ? Number(maxDiscount) : null) : undefined,
        usageLimit: usageLimit !== undefined ? (usageLimit ? parseInt(usageLimit) : null) : undefined,
        expiresAt: expiresAt ? new Date(expiresAt) : undefined,
        isActive: isActive !== undefined ? isActive : undefined,
      },
    });

    return sendSuccess(res, 'Coupon updated successfully', { coupon: updated });
  } catch (error: any) {
    return sendError(res, 'Failed to update coupon', error.message, 500);
  }
};

// 4. Delete coupon
export const deleteCoupon = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    await prisma.coupon.delete({ where: { id } });
    return sendSuccess(res, 'Coupon deleted successfully');
  } catch (error: any) {
    return sendError(res, 'Failed to delete coupon', error.message, 500);
  }
};

// 5. Apply coupon logic (checking limits, expiries, usage limits)
export const applyCouponCode = async (req: Request, res: Response) => {
  try {
    const { code, orderAmount } = req.body;

    const coupon = await prisma.coupon.findUnique({
      where: { code: code.toUpperCase() },
    });

    if (!coupon || !coupon.isActive) {
      return sendError(res, 'Invalid or inactive coupon code', null, 400);
    }

    const now = new Date();
    if (coupon.expiresAt && now > coupon.expiresAt) {
      return sendError(res, 'Coupon has expired', null, 400);
    }

    if (coupon.minOrderValue && Number(orderAmount) < Number(coupon.minOrderValue)) {
      return sendError(res, `Minimum order amount of ₹${coupon.minOrderValue} required`, null, 400);
    }

    if (coupon.usageLimit && coupon.usageCount >= coupon.usageLimit) {
      return sendError(res, 'Coupon usage limit has been reached', null, 400);
    }

    // Calculate discount value
    let discount = 0;
    if (coupon.discountType === 'PERCENTAGE') {
      discount = (Number(orderAmount) * Number(coupon.discountValue)) / 100;
      if (coupon.maxDiscount && discount > Number(coupon.maxDiscount)) {
        discount = Number(coupon.maxDiscount);
      }
    } else {
      discount = Number(coupon.discountValue);
    }

    return sendSuccess(res, 'Coupon applied successfully', {
      code: coupon.code,
      discount,
      discountType: coupon.discountType,
      discountValue: coupon.discountValue,
    });
  } catch (error: any) {
    return sendError(res, 'Failed to apply coupon code', error.message, 500);
  }
};
