"use server";

import { and, eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { db } from "@/db";
import {
  vehicleTemplates,
  vehicleTemplateMerkmale,
  vehicleTemplateAliasse,
} from "@/db/schema";
import { requirePlatformAdmin } from "@/lib/auth/guards";
import { writeAudit } from "@/lib/audit";
import {
  templateCreateSchema,
  templateUpdateSchema,
  templateMerkmalSchema,
  aliasSchema,
} from "@/lib/validation/template";
import { uuidSchema } from "@/lib/validation/common";

export type ActionResult = { ok: true } | { ok: false; error: string };

export async function createTemplate(input: unknown): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const p = templateCreateSchema.safeParse(input);
  if (!p.success) {
    return { ok: false, error: p.error.issues[0]?.message ?? "Ungültige Eingabe." };
  }
  await db.transaction(async (tx) => {
    const [t] = await tx
      .insert(vehicleTemplates)
      .values({
        code: p.data.code,
        name: p.data.name,
        beschreibung: p.data.beschreibung ?? null,
      })
      .returning();
    if (!t) throw new Error("Vorlage konnte nicht angelegt werden.");
    await writeAudit(s.user.id, "template.create", "vehicle_template", t.id, undefined, tx);
  });
  revalidatePath("/admin/vorlagen");
  return { ok: true };
}

export async function updateTemplate(input: unknown): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const p = templateUpdateSchema.safeParse(input);
  if (!p.success) {
    return { ok: false, error: p.error.issues[0]?.message ?? "Ungültige Eingabe." };
  }
  await db.transaction(async (tx) => {
    await tx
      .update(vehicleTemplates)
      .set({
        code: p.data.code,
        name: p.data.name,
        beschreibung: p.data.beschreibung ?? null,
      })
      .where(eq(vehicleTemplates.id, p.data.id));
    await writeAudit(s.user.id, "template.update", "vehicle_template", p.data.id, undefined, tx);
  });
  revalidatePath(`/admin/vorlagen/${p.data.id}`);
  return { ok: true };
}

/**
 * Setzt (upsert) ein Vorgabe-Merkmal einer Vorlage mit typisiertem Vorgabewert.
 */
export async function setTemplateMerkmal(input: {
  templateId: unknown;
  merkmal: unknown;
}): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const tid = uuidSchema.safeParse(input.templateId);
  const m = templateMerkmalSchema.safeParse(input.merkmal);
  if (!tid.success || !m.success) {
    return { ok: false, error: "Ungültige Eingabe." };
  }
  await db.transaction(async (tx) => {
    await tx
      .insert(vehicleTemplateMerkmale)
      .values({
        templateId: tid.data,
        merkmalId: m.data.merkmalId,
        vorgabewertNum: m.data.vorgabewertNum ?? null,
        vorgabewertText: m.data.vorgabewertText ?? null,
        vorgabewertBool: m.data.vorgabewertBool ?? null,
        pflicht: m.data.pflicht,
        reihenfolge: m.data.reihenfolge,
      })
      .onConflictDoUpdate({
        target: [
          vehicleTemplateMerkmale.templateId,
          vehicleTemplateMerkmale.merkmalId,
        ],
        set: {
          vorgabewertNum: m.data.vorgabewertNum ?? null,
          vorgabewertText: m.data.vorgabewertText ?? null,
          vorgabewertBool: m.data.vorgabewertBool ?? null,
          pflicht: m.data.pflicht,
          reihenfolge: m.data.reihenfolge,
        },
      });
    await writeAudit(
      s.user.id,
      "template.merkmal_set",
      "vehicle_template",
      tid.data,
      { merkmalId: m.data.merkmalId },
      tx,
    );
  });
  revalidatePath(`/admin/vorlagen/${tid.data}`);
  return { ok: true };
}

export async function removeTemplateMerkmal(input: {
  templateId: unknown;
  merkmalId: unknown;
}): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const tid = uuidSchema.safeParse(input.templateId);
  const mid = uuidSchema.safeParse(input.merkmalId);
  if (!tid.success || !mid.success) return { ok: false, error: "Ungültige ID." };
  await db.transaction(async (tx) => {
    await tx
      .delete(vehicleTemplateMerkmale)
      .where(
        and(
          eq(vehicleTemplateMerkmale.templateId, tid.data),
          eq(vehicleTemplateMerkmale.merkmalId, mid.data),
        ),
      );
    await writeAudit(
      s.user.id,
      "template.merkmal_remove",
      "vehicle_template",
      tid.data,
      { merkmalId: mid.data },
      tx,
    );
  });
  revalidatePath(`/admin/vorlagen/${tid.data}`);
  return { ok: true };
}

export async function addAlias(input: unknown): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const p = aliasSchema.safeParse(input);
  if (!p.success) {
    return { ok: false, error: p.error.issues[0]?.message ?? "Ungültige Eingabe." };
  }
  await db.transaction(async (tx) => {
    await tx
      .insert(vehicleTemplateAliasse)
      .values({
        templateId: p.data.templateId,
        alias: p.data.alias,
        bestaetigt: p.data.bestaetigt,
      })
      .onConflictDoUpdate({
        target: [
          vehicleTemplateAliasse.templateId,
          vehicleTemplateAliasse.alias,
        ],
        set: { bestaetigt: p.data.bestaetigt },
      });
    await writeAudit(
      s.user.id,
      "template.alias_set",
      "vehicle_template",
      p.data.templateId,
      { alias: p.data.alias, bestaetigt: p.data.bestaetigt },
      tx,
    );
  });
  revalidatePath(`/admin/vorlagen/${p.data.templateId}`);
  return { ok: true };
}

export async function removeAlias(aliasId: unknown): Promise<ActionResult> {
  const s = await requirePlatformAdmin();
  const id = uuidSchema.safeParse(aliasId);
  if (!id.success) return { ok: false, error: "Ungültige ID." };
  await db.transaction(async (tx) => {
    await tx
      .delete(vehicleTemplateAliasse)
      .where(eq(vehicleTemplateAliasse.id, id.data));
    await writeAudit(
      s.user.id,
      "template.alias_remove",
      "vehicle_template",
      id.data,
      undefined,
      tx,
    );
  });
  revalidatePath("/admin/vorlagen");
  return { ok: true };
}
