import { prisma } from '../../lib/prisma'
import { generateCompanyApiKey } from '../../security/apiKeys'

export async function findCompany(companyId: string) {
  return prisma.company.findUniqueOrThrow({
    where: { id: companyId },
    include: {
      brand: true,
      subscription: true,
      _count: { select: { vehicles: true, customers: true, reservations: true } },
    },
  })
}

export async function updateCompany(companyId: string, data: any) {
  return prisma.company.update({ where: { id: companyId }, data })
}

export async function findBrand(companyId: string) {
  return prisma.brandSettings.findUnique({ where: { companyId } })
}

export async function upsertBrand(companyId: string, updateData: any, createData: any) {
  return prisma.brandSettings.upsert({
    where: { companyId },
    update: updateData,
    create: { companyId, ...createData },
  })
}

export async function findContractSettings(companyId: string) {
  return prisma.contractSettings.findUnique({ where: { companyId } })
}

export async function upsertContractSettings(companyId: string, data: any) {
  return prisma.contractSettings.upsert({
    where: { companyId },
    update: data,
    create: { companyId, ...data },
  })
}

export async function findInsurancePolicies(companyId: string) {
  return prisma.insurancePolicy.findMany({
    where: { companyId },
    orderBy: [{ isRequired: 'desc' }, { sortOrder: 'asc' }, { name: 'asc' }],
  })
}

export async function createInsurancePolicy(companyId: string, data: any) {
  return prisma.insurancePolicy.create({ data: { companyId, ...data } })
}

export async function updateInsurancePolicy(id: string, companyId: string, data: any) {
  return prisma.insurancePolicy.updateMany({ where: { id, companyId }, data })
}

export async function findInsurancePolicyOrThrow(id: string) {
  return prisma.insurancePolicy.findUniqueOrThrow({ where: { id } })
}

export async function deleteInsurancePolicy(id: string, companyId: string) {
  return prisma.insurancePolicy.deleteMany({ where: { id, companyId } })
}

export async function findPricingRules(companyId: string) {
  return prisma.pricingRule.findMany({
    where: { companyId },
    orderBy: [{ isActive: 'desc' }, { createdAt: 'asc' }],
  })
}

export async function createPricingRule(companyId: string, data: any) {
  return prisma.pricingRule.create({ data: { companyId, ...data } })
}

export async function updatePricingRule(id: string, companyId: string, data: any) {
  return prisma.pricingRule.updateMany({ where: { id, companyId }, data })
}

export async function findPricingRuleOrThrow(id: string) {
  return prisma.pricingRule.findUniqueOrThrow({ where: { id } })
}

export async function deletePricingRule(id: string, companyId: string) {
  return prisma.pricingRule.deleteMany({ where: { id, companyId } })
}

export async function findAccountingSettings(companyId: string) {
  return prisma.accountingSettings.findUnique({ where: { companyId } })
}

export async function upsertAccountingSettings(companyId: string, data: any) {
  return prisma.accountingSettings.upsert({
    where: { companyId },
    update: data,
    create: { companyId, ...data },
  })
}

export async function findApiKey(companyId: string) {
  const apiKeys = await (prisma as any).companyApiKey.findMany({
    where: { companyId, revokedAt: null },
    orderBy: { createdAt: 'desc' },
    select: { id: true, name: true, prefix: true, lastUsedAt: true, createdAt: true, revokedAt: true },
  })

  return { apiKeys }
}

export async function regenerateApiKey(companyId: string) {
  const nextKey = generateCompanyApiKey()

  await prisma.$transaction(async (tx: any) => {
    await (tx as any).companyApiKey.updateMany({
      where: { companyId, revokedAt: null },
      data: { revokedAt: new Date() },
    })
    await (tx as any).companyApiKey.create({
      data: {
        companyId,
        name: 'Default API key',
        prefix: nextKey.prefix,
        keyHash: nextKey.keyHash,
      },
    })
  })

  return { apiKey: nextKey.rawKey, prefix: nextKey.prefix, warning: 'This raw API key is shown once. Store it securely.' }
}

export async function findBrandBySubdomain(subdomain: string, excludeCompanyId: string) {
  return prisma.brandSettings.findFirst({ where: { subdomain, companyId: { not: excludeCompanyId } } })
}

export async function findBrandByCustomDomain(customDomain: string, excludeCompanyId: string) {
  return prisma.brandSettings.findFirst({ where: { customDomain, companyId: { not: excludeCompanyId } } })
}

export async function clearCustomDomain(companyId: string) {
  return prisma.brandSettings.updateMany({
    where: { companyId },
    data: { customDomain: null, customDomainVerified: false, customDomainAddedAt: null },
  })
}
