import prisma from "../config/prisma.js";
import { Prisma } from "../generated/prisma/client.js";

export class SupplierPaymentRepository {
  async create(data: Prisma.SupplierPaymentUncheckedCreateInput) {
    return prisma.supplierPayment.create({ data });
  }

  async findAll(
    skip?: number,
    take?: number,
    supplierId?: bigint,
    dateFrom?: Date,
    dateTo?: Date,
    search?: string
  ) {
    const where: Prisma.SupplierPaymentWhereInput = { deletedAt: null };

    if (supplierId) {
      where.supplierId = supplierId;
    }

    if (dateFrom || dateTo) {
      where.paymentDate = {};
      if (dateFrom) where.paymentDate.gte = dateFrom;
      if (dateTo) where.paymentDate.lte = dateTo;
    }

    const trimmedSearch = search?.trim();
    if (trimmedSearch) {
      const orFilters: Prisma.SupplierPaymentWhereInput[] = [
        { supplier: { name: { contains: trimmedSearch } } },
        { referenceNo: { contains: trimmedSearch } },
        { remarks: { contains: trimmedSearch } },
      ];

      const normalizedMode = trimmedSearch.toUpperCase();
      if (["CASH", "BANK", "UPI"].includes(normalizedMode)) {
        orFilters.push({ paymentMode: normalizedMode as any });
      }

      where.OR = orFilters;
    }

    const findOptions: any = {
      where,
      include: {
        supplier: {
          select: { name: true }
        }
      },
      orderBy: { id: 'desc' },
    };
    
    if (skip !== undefined) findOptions.skip = skip;
    if (take !== undefined) findOptions.take = take;

    const [items, total] = await Promise.all([
      prisma.supplierPayment.findMany(findOptions),
      prisma.supplierPayment.count({ where }),
    ]);

    return { items, total };
  }

  async findAllForExport(
    supplierId?: bigint,
    dateFrom?: Date,
    dateTo?: Date,
    search?: string
  ) {
    const { items } = await this.findAll(
      undefined,
      undefined,
      supplierId,
      dateFrom,
      dateTo,
      search
    );

    return items;
  }

  async findById(id: bigint) {
    return prisma.supplierPayment.findFirst({
      where: { id, deletedAt: null },
      include: {
        supplier: {
          select: { name: true, outstandingBalance: true }
        }
      },
    });
  }
}
