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

export async function findPublicOffers() {
  return prisma.offer.findMany({
    where: { isPublic: true, isActive: true, validFrom: { lte: new Date() }, validUntil: { gte: new Date() } },
    include: { company: { include: { brand: { select: { displayName: true, logoUrl: true, subdomain: true, primaryColor: true } } } } },
    orderBy: [{ isFeatured: 'desc' }, { createdAt: 'desc' }],
    take: 50,
  })
}

export async function findCitiesFromCompanies() {
  return prisma.company.findMany({
    where: {
      status: { in: ['ACTIVE', 'TRIALING'] },
      brand: { isListedOnCarplace: true, publicCity: { not: null } },
    },
    select: { brand: { select: { publicCity: true } } },
  })
}

export async function findListedCompanies(where: any, skip: number, take: number) {
  return prisma.company.findMany({
    where,
    include: {
      brand: { select: { displayName: true, logoUrl: true, subdomain: true, publicCity: true, publicCountry: true, carplaceRating: true, primaryColor: true } },
      _count: { select: { vehicles: { where: { isPublished: true, status: 'AVAILABLE' } } } },
    },
    skip,
    take,
  })
}

export async function findPublishedVehicles(where: any) {
  return prisma.vehicle.findMany({
    where,
    include: {
      company: { include: { brand: { select: { displayName: true, logoUrl: true, subdomain: true, carplaceRating: true, primaryColor: true } } } },
    },
    orderBy: { dailyRate: 'asc' },
  })
}

export async function findVehicleForCarplace(vehicleId: string, companySlug: string) {
  return prisma.vehicle.findFirst({
    where: { id: vehicleId, isPublished: true, company: { status: { in: ['ACTIVE', 'TRIALING'] }, OR: [{ slug: companySlug }, { brand: { subdomain: companySlug } }] } },
    include: { company: { include: { brand: true } } },
  })
}

export async function findVehicleForCarplaceById(vehicleId: string) {
  return prisma.vehicle.findFirst({
    where: {
      id: vehicleId,
      isPublished: true,
      company: { status: { in: ['ACTIVE', 'TRIALING'] }, brand: { isListedOnCarplace: true } },
    },
    include: { company: { include: { brand: true } } },
  })
}

export async function upsertCarplaceCustomer(companyId: string, data: {
  email: string
  firstName: string
  lastName: string
  phone?: string
  dateOfBirth?: string
  nationality?: string
  identityDocumentNumber?: string
  fullAddress?: string
  driverLicense?: string
  licenseExpiry?: string
  licenseIssuedAt?: string
  licenseCountry?: string
  licenseCategory?: string
  internationalLicenseNumber?: string
}) {
  const existing = await prisma.customer.findUnique({
    where: { companyId_email: { companyId, email: data.email } },
    select: { id: true, address: true },
  })

  // Only patch the address JSON with fields that were actually provided
  const prevAddress = (existing?.address && typeof existing.address === 'object' && !Array.isArray(existing.address))
    ? existing.address as Record<string, unknown>
    : {}
  const hasAddressPatch = data.fullAddress || data.identityDocumentNumber || data.internationalLicenseNumber !== undefined
  const address = hasAddressPatch
    ? {
        ...prevAddress,
        ...(data.fullAddress               ? { fullAddress: data.fullAddress }                                 : {}),
        ...(data.identityDocumentNumber    ? { identityDocumentNumber: data.identityDocumentNumber }           : {}),
        ...(data.internationalLicenseNumber !== undefined ? { internationalLicenseNumber: data.internationalLicenseNumber ?? null } : {}),
      }
    : undefined

  const payload = {
    firstName: data.firstName,
    lastName:  data.lastName,
    email:     data.email,
    ...(data.phone            ? { phone: data.phone }                                          : {}),
    ...(data.driverLicense    ? { driverLicense: data.driverLicense, licenseNumber: data.driverLicense } : {}),
    ...(data.dateOfBirth      ? { dateOfBirth: new Date(data.dateOfBirth) }                    : {}),
    ...(data.nationality      ? { nationality: data.nationality }                              : {}),
    ...(address !== undefined ? { address }                                                    : {}),
    ...(data.licenseExpiry    ? { licenseExpiry: new Date(data.licenseExpiry) }                : {}),
    ...(data.licenseIssuedAt  ? { licenseIssuedAt: new Date(data.licenseIssuedAt) }            : {}),
    ...(data.licenseCountry   ? { licenseCountry: data.licenseCountry }                        : {}),
    ...(data.licenseCategory  ? { licenseCategory: data.licenseCategory }                      : {}),
  }

  if (!existing) {
    return prisma.customer.create({ data: { companyId, ...payload } })
  }
  return prisma.customer.update({ where: { id: existing.id }, data: payload })
}

export async function createCarplaceReservation(data: {
  companyId: string; vehicleId: string; customerId: string
  startDate: Date; endDate: Date; pickupLocation?: string | null; returnLocation?: string | null
  dailyRate: number; totalDays: number; totalAmount: number; notes?: string; bookingReference?: string
}) {
  return prisma.reservation.create({
    data: { ...data, source: 'CARPLACE', status: 'DRAFT' },
  })
}

export async function createCarplaceFunnelEvent(data: {
  eventName: string
  companySlug: string
  vehicleId: string
  renterId?: string | null
  sessionId?: string
  path?: string
  metadata?: Record<string, string | number | boolean | null>
}) {
  const vehicle = await prisma.vehicle.findFirst({
    where: {
      id: data.vehicleId,
      isPublished: true,
      company: { status: { in: ['ACTIVE', 'TRIALING'] }, OR: [{ slug: data.companySlug }, { brand: { subdomain: data.companySlug } }] },
    },
    select: { companyId: true },
  })

  return prisma.carplaceFunnelEvent.create({
    data: {
      eventName: data.eventName,
      companyId: vehicle?.companyId ?? null,
      companySlug: data.companySlug,
      vehicleId: data.vehicleId,
      renterId: data.renterId ?? null,
      sessionId: data.sessionId,
      path: data.path,
      metadata: (data.metadata ?? {}) as any,
    },
  })
}

export async function findCompanyPage(slug: string) {
  return prisma.company.findFirst({
    where: { status: { in: ['ACTIVE', 'TRIALING'] }, OR: [{ slug }, { brand: { subdomain: slug } }] },
    include: {
      brand: true,
      vehicles: { where: { isPublished: true, status: 'AVAILABLE' }, orderBy: { createdAt: 'desc' } },
      offers:   { where: { isPublic: true, isActive: true, validUntil: { gte: new Date() } }, orderBy: { isFeatured: 'desc' } },
    },
  })
}

export async function findCompanyBySlug(slug: string) {
  return prisma.company.findFirstOrThrow({ where: { status: { in: ['ACTIVE', 'TRIALING'] }, OR: [{ slug }, { brand: { subdomain: slug } }] } })
}

export async function findCompanyReviews(companyId: string) {
  return prisma.review.findMany({
    where: { companyId, isPublished: true },
    include: { renter: { select: { firstName: true, lastName: true } } },
    orderBy: { createdAt: 'desc' },
    take: 50,
  })
}

export async function findCompanyVehicles(companyId: string) {
  return prisma.vehicle.findMany({
    where: { companyId, isPublished: true, status: 'AVAILABLE' },
    orderBy: { createdAt: 'desc' },
  })
}

export async function findVehicleById(slug: string, vehicleId: string) {
  const company = await prisma.company.findFirstOrThrow({ where: { status: { in: ['ACTIVE', 'TRIALING'] }, OR: [{ slug }, { brand: { subdomain: slug } }] } })
  return prisma.vehicle.findFirstOrThrow({
    where: { id: vehicleId, companyId: company.id, isPublished: true, status: 'AVAILABLE' },
    include: { company: { include: { brand: true } } },
  })
}

export async function findCompanyOffers(companyId: string) {
  return prisma.offer.findMany({
    where: { companyId, isPublic: true, isActive: true, validFrom: { lte: new Date() }, validUntil: { gte: new Date() } },
    orderBy: [{ isFeatured: 'desc' }, { createdAt: 'desc' }],
  })
}

export async function findReservationByReviewToken(token: string) {
  return prisma.reservation.findUnique({
    where: { reviewToken: token },
    include: {
      vehicle: { select: { make: true, model: true, year: true, photos: true } },
      company: { include: { brand: { select: { displayName: true, logoUrl: true } } } },
      review:  { select: { id: true } },
    },
  })
}

export async function findReservationForReviewSubmit(token: string) {
  return prisma.reservation.findUnique({
    where: { reviewToken: token },
    include: { review: { select: { id: true } } },
  })
}

export async function createReview(data: {
  reservationId: string; companyId: string; renterId?: string | null
  overallRating: number; vehicleRating?: number; serviceRating?: number; comment?: string
}) {
  return prisma.review.create({
    data: { ...data, renterId: data.renterId ?? undefined, isPublished: true },
  })
}

export async function invalidateReviewToken(reservationId: string) {
  return prisma.reservation.update({ where: { id: reservationId }, data: { reviewToken: null } })
}

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