/**
 * Pfad → Resource → Owner Mapping für `/api/files/download`.
 *
 * Jeder Upload-Subdirectory ist mit genau einem Prisma-Model + Path-Field
 * verknüpft. Wir suchen den Record, der diesen Path referenziert, und
 * leiten daraus den zuständigen Customer/Contract ab. canAccessCustomer /
 * canAccessContract entscheidet danach über Zugriff.
 *
 * Pfade werden 1:1 mit dem in der DB gespeicherten Wert verglichen
 * (z.B. `/uploads/bank-cards/12345.pdf`). Damit ist Path-Traversal
 * automatisch ausgeschlossen – ein konstruierter Pfad findet keinen Record.
 */
import prisma from '../lib/prisma.js';

export type FileOwner =
  | { kind: 'customer'; customerId: number }
  | { kind: 'contract'; contractId: number }
  // Wie 'contract', aber Portal-Kunden ausgeschlossen (nur Mitarbeiter/Admin).
  | { kind: 'contract-staff'; contractId: number }
  | { kind: 'admin' }
  | { kind: 'gdpr-admin' };

export async function findUploadOwner(uploadPath: string): Promise<FileOwner | null> {
  // Format-Check: muss mit /uploads/<subDir>/<filename> beginnen, kein Traversal.
  if (!uploadPath.startsWith('/uploads/')) return null;
  if (uploadPath.includes('..') || uploadPath.includes('\0')) return null;

  const parts = uploadPath.split('/');
  // ['', 'uploads', '<subDir>', '<filename...>']
  if (parts.length < 4) return null;
  const subDir = parts[2];

  switch (subDir) {
    case 'bank-cards': {
      const r = await prisma.bankCard.findFirst({
        where: { documentPath: uploadPath },
        select: { customerId: true },
      });
      return r ? { kind: 'customer', customerId: r.customerId } : null;
    }

    case 'documents': {
      const r = await prisma.identityDocument.findFirst({
        where: { documentPath: uploadPath },
        select: { customerId: true },
      });
      return r ? { kind: 'customer', customerId: r.customerId } : null;
    }

    case 'business-registrations': {
      const r = await prisma.customer.findFirst({
        where: { businessRegistrationPath: uploadPath },
        select: { id: true },
      });
      return r ? { kind: 'customer', customerId: r.id } : null;
    }

    case 'commercial-registers': {
      const r = await prisma.customer.findFirst({
        where: { commercialRegisterPath: uploadPath },
        select: { id: true },
      });
      return r ? { kind: 'customer', customerId: r.id } : null;
    }

    case 'privacy-policies': {
      const r = await prisma.customer.findFirst({
        where: { privacyPolicyPath: uploadPath },
        select: { id: true },
      });
      return r ? { kind: 'customer', customerId: r.id } : null;
    }

    case 'authorizations': {
      const r = await prisma.representativeAuthorization.findFirst({
        where: { documentPath: uploadPath },
        select: { customerId: true },
      });
      return r ? { kind: 'customer', customerId: r.customerId } : null;
    }

    case 'contract-documents': {
      const r = await prisma.contractDocument.findFirst({
        where: { documentPath: uploadPath },
        select: { contractId: true },
      });
      return r ? { kind: 'contract', contractId: r.contractId } : null;
    }

    case 'invoices': {
      const r = await prisma.invoice.findFirst({
        where: { documentPath: uploadPath },
        select: { contractId: true },
      });
      return r?.contractId ? { kind: 'contract', contractId: r.contractId } : null;
    }

    case 'credit-note-receipts': {
      // Überweisungsbeleg: NUR Mitarbeiter/Admin. Portal-Kunden dürfen Belege
      // nicht herunterladen (nur ihre Gutschrift selbst).
      const r = await prisma.creditNote.findFirst({
        where: { receiptPath: uploadPath },
        select: { contractId: true },
      });
      return r ? { kind: 'contract-staff', contractId: r.contractId } : null;
    }

    case 'credit-notes': {
      // Generiertes Gutschrift-PDF: Owner ist der Vertrag der Gutschrift –
      // der besitzende Kunde darf seine eigene Gutschrift laden.
      const r = await prisma.creditNote.findFirst({
        where: { pdfPath: uploadPath },
        select: { contractId: true },
      });
      return r ? { kind: 'contract', contractId: r.contractId } : null;
    }

    case 'cancellation-letters':
    case 'cancellation-confirmations':
    case 'cancellation-letters-options':
    case 'cancellation-confirmations-options': {
      const fieldMap: Record<string, 'cancellationLetterPath' | 'cancellationConfirmationPath' | 'cancellationLetterOptionsPath' | 'cancellationConfirmationOptionsPath'> = {
        'cancellation-letters': 'cancellationLetterPath',
        'cancellation-confirmations': 'cancellationConfirmationPath',
        'cancellation-letters-options': 'cancellationLetterOptionsPath',
        'cancellation-confirmations-options': 'cancellationConfirmationOptionsPath',
      };
      const field = fieldMap[subDir];
      const r = await prisma.contract.findFirst({
        where: { [field]: uploadPath },
        select: { id: true },
      });
      return r ? { kind: 'contract', contractId: r.id } : null;
    }

    case 'pdf-templates': {
      // Admin-only Resource: Vorlagen gehören keinem Customer.
      const r = await prisma.pdfTemplate.findFirst({
        where: { templatePath: uploadPath },
        select: { id: true },
      });
      return r ? { kind: 'admin' } : null;
    }

    default:
      return null;
  }
}
