import prisma from '../lib/prisma.js';
import { stripHtml } from '../utils/sanitize.js';

export interface CreateHistoryEntryData {
  title: string;
  description?: string;
  isAutomatic?: boolean;
  createdBy: string;
}

// Read-Time-Defensive: title + description durch stripHtml schicken, damit
// Alt-Einträge (vor Pentest 43.6) mit rohen HTML-Payloads nicht roh
// rausgehen. Schützt zusätzlich gegen einen umgangenen Write-Filter.
function sanitizeEntry<T extends { title: string; description: string | null }>(entry: T): T {
  return {
    ...entry,
    title: stripHtml(entry.title) as string,
    description: entry.description != null ? (stripHtml(entry.description) as string) : entry.description,
  };
}

/**
 * Alle Historie-Einträge für einen Vertrag abrufen
 */
export async function getHistoryEntries(contractId: number) {
  const entries = await prisma.contractHistoryEntry.findMany({
    where: { contractId },
    orderBy: { createdAt: 'desc' },
  });
  return entries.map(sanitizeEntry);
}

/**
 * Einzelnen Historie-Eintrag abrufen
 */
export async function getHistoryEntry(contractId: number, entryId: number) {
  const entry = await prisma.contractHistoryEntry.findFirst({
    where: { id: entryId, contractId },
  });
  return entry ? sanitizeEntry(entry) : null;
}

/**
 * Neuen Historie-Eintrag erstellen
 */
export async function createHistoryEntry(contractId: number, data: CreateHistoryEntryData) {
  // Prüfen ob Vertrag existiert
  const contract = await prisma.contract.findUnique({
    where: { id: contractId },
  });

  if (!contract) {
    throw new Error('Vertrag nicht gefunden');
  }

  // Pentest 2026-05-30 (MEDIUM, 43.6): Admin konnte HTML-Tags in title +
  // description schreiben, Portal-User las sie roh zurück. stripHtml räumt
  // Tags + gefährliche URI-Schemata vor dem Persistieren weg.
  return prisma.contractHistoryEntry.create({
    data: {
      contractId,
      title: stripHtml(data.title) as string,
      description: data.description != null ? (stripHtml(data.description) as string) : data.description,
      isAutomatic: data.isAutomatic ?? false,
      createdBy: data.createdBy,
    },
  });
}

/**
 * Historie-Eintrag aktualisieren (nur manuelle Einträge)
 */
export async function updateHistoryEntry(
  contractId: number,
  entryId: number,
  data: { title?: string; description?: string }
) {
  const entry = await prisma.contractHistoryEntry.findFirst({
    where: { id: entryId, contractId },
  });

  if (!entry) {
    throw new Error('Historie-Eintrag nicht gefunden');
  }

  if (entry.isAutomatic) {
    throw new Error('Automatische Einträge können nicht bearbeitet werden');
  }

  return prisma.contractHistoryEntry.update({
    where: { id: entryId },
    data: {
      title: data.title != null ? (stripHtml(data.title) as string) : undefined,
      description: data.description != null ? (stripHtml(data.description) as string) : undefined,
    },
  });
}

/**
 * Historie-Eintrag löschen (nur manuelle Einträge)
 */
export async function deleteHistoryEntry(contractId: number, entryId: number) {
  const entry = await prisma.contractHistoryEntry.findFirst({
    where: { id: entryId, contractId },
  });

  if (!entry) {
    throw new Error('Historie-Eintrag nicht gefunden');
  }

  if (entry.isAutomatic) {
    throw new Error('Automatische Einträge können nicht gelöscht werden');
  }

  return prisma.contractHistoryEntry.delete({ where: { id: entryId } });
}

/**
 * Automatischen Historie-Eintrag für Folgevertrag erstellen (im Vorgängervertrag)
 */
export async function createFollowUpHistoryEntry(
  previousContractId: number,
  newContractNumber: string,
  createdBy: string
) {
  return createHistoryEntry(previousContractId, {
    title: `Folgevertrag erstellt: ${newContractNumber}`,
    description: `Ein neuer Folgevertrag (${newContractNumber}) wurde aus diesem Vertrag erstellt.`,
    isAutomatic: true,
    createdBy,
  });
}

/**
 * Automatischen Historie-Eintrag für neuen Folgevertrag erstellen (im neuen Vertrag selbst)
 */
export async function createNewContractFromPredecessorEntry(
  newContractId: number,
  previousContractNumber: string,
  createdBy: string
) {
  return createHistoryEntry(newContractId, {
    title: `Folgevertrag zu ${previousContractNumber}`,
    description: `Dieser Vertrag wurde als Folgevertrag zu ${previousContractNumber} erstellt.`,
    isAutomatic: true,
    createdBy,
  });
}

/**
 * Automatischen Historie-Eintrag für VVL (Vertragsverlängerung) im Vorgängervertrag.
 */
export async function createRenewalHistoryEntry(
  previousContractId: number,
  newContractNumber: string,
  createdBy: string
) {
  return createHistoryEntry(previousContractId, {
    title: `Vertragsverlängerung erstellt: ${newContractNumber}`,
    description: `Eine Vertragsverlängerung (VVL) als ${newContractNumber} wurde aus diesem Vertrag erstellt – alle Daten wurden 1:1 übernommen, das Auftragsdokument muss neu hochgeladen werden.`,
    isAutomatic: true,
    createdBy,
  });
}

/**
 * Automatischen Historie-Eintrag im neuen VVL-Vertrag.
 */
export async function createNewRenewalFromPredecessorEntry(
  newContractId: number,
  previousContractNumber: string,
  createdBy: string
) {
  return createHistoryEntry(newContractId, {
    title: `VVL zu ${previousContractNumber}`,
    description: `Dieser Vertrag wurde als Vertragsverlängerung (VVL) zu ${previousContractNumber} erstellt.`,
    isAutomatic: true,
    createdBy,
  });
}
