import { prisma } from '../../lib/prisma'

const FULL_INCLUDE = {
  vehicle: true,
  customer: true,
  insurances: true,
  additionalDrivers: true,
  rentalPayments: true,
  damageReports: true,
}

export async function findMany(where: any, skip: number, take: number) {
  return Promise.all([
    prisma.reservation.findMany({
      where,
      include: { vehicle: true, customer: true },
      skip,
      take,
      orderBy: { createdAt: 'desc' },
    }),
    prisma.reservation.count({ where }),
  ])
}

export async function findById(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({ where: { id, companyId }, include: FULL_INCLUDE })
}

export async function findByIdSimple(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({ where: { id, companyId } })
}

export async function findByIdWithRelations(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: { insurances: true, additionalDrivers: true },
  })
}

export async function findByIdForCheckout(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: { vehicle: true },
  })
}

export async function findForLicenseCheck(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: { customer: true, additionalDrivers: true },
  })
}

export async function findForContract(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: {
      vehicle: true,
      customer: true,
      insurances: true,
      additionalDrivers: true,
      rentalPayments: { orderBy: { createdAt: 'asc' } },
      inspections: { include: { damagePoints: true }, orderBy: { inspectedAt: 'asc' } },
      company: { include: { brand: true, contractSettings: true, accountingSettings: true } },
    },
  })
}

export async function findForBilling(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: { vehicle: true, insurances: true, additionalDrivers: true },
  })
}

export async function findForClose(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({ where: { id, companyId }, include: { customer: true } })
}

export async function findForInspection(id: string, companyId: string) {
  return prisma.reservation.findFirstOrThrow({
    where: { id, companyId },
    include: { vehicle: true, customer: true },
  })
}

export async function findConflict(vehicleId: string, start: Date, end: Date, excludeId?: string) {
  return prisma.reservation.findFirst({
    where: {
      vehicleId,
      status: { in: ['CONFIRMED', 'ACTIVE'] },
      startDate: { lt: end },
      endDate:   { gt: start },
      ...(excludeId ? { id: { not: excludeId } } : {}),
    },
  })
}

export async function create(data: any) {
  return prisma.reservation.create({ data, include: { vehicle: true, customer: true } })
}

export async function updateById(id: string, data: any) {
  return prisma.reservation.update({ where: { id }, data })
}

export async function findActiveOffer(companyId: string, promoCode: string) {
  return prisma.offer.findFirst({
    where: { companyId, promoCode, isActive: true, validFrom: { lte: new Date() }, validUntil: { gte: new Date() } },
  })
}

export async function incrementOfferRedemption(offerId: string) {
  return prisma.offer.update({ where: { id: offerId }, data: { redemptionCount: { increment: 1 } } })
}

export async function findVehicle(vehicleId: string, companyId: string) {
  return prisma.vehicle.findFirstOrThrow({ where: { id: vehicleId, companyId } })
}

export async function findCustomer(customerId: string, companyId: string) {
  return prisma.customer.findFirstOrThrow({ where: { id: customerId, companyId } })
}

export async function findCustomerById(customerId: string) {
  return prisma.customer.findUniqueOrThrow({ where: { id: customerId } })
}

export async function updateVehicleStatus(vehicleId: string, status: string, mileage?: number) {
  return prisma.vehicle.update({
    where: { id: vehicleId },
    data: { status: status as any, ...(mileage !== undefined ? { mileage } : {}) },
  })
}

export async function findCompanyWithBrand(companyId: string) {
  return prisma.company.findUnique({
    where: { id: companyId },
    include: { brand: { select: { displayName: true, defaultLocale: true } } },
  })
}

export async function findBrandLocale(companyId: string) {
  return prisma.brandSettings.findUnique({ where: { companyId }, select: { defaultLocale: true } })
}

export async function findInspections(reservationId: string, companyId: string) {
  return prisma.damageInspection.findMany({
    where: { reservationId, companyId },
    include: { damagePoints: true },
    orderBy: { inspectedAt: 'asc' },
  })
}

export async function findAdditionalDriver(driverId: string, reservationId: string, companyId: string) {
  return prisma.additionalDriver.findFirstOrThrow({ where: { id: driverId, reservationId, companyId } })
}

export async function updateAdditionalDriver(id: string, data: any) {
  return prisma.additionalDriver.update({ where: { id }, data })
}
