"use server";

import { revalidatePath } from "next/cache";
import { and, eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/db";
import { dealerInactiveNotes, customers } from "@/db/schema";
import { requireSession } from "@/lib/auth";
import { scopeFilter } from "@/lib/rbac";
import { isRealMonth } from "@/lib/period";
import { writeAudit } from "@/lib/audit";

const noteSchema = z.object({
  customerId: z.string().uuid(),
  periodKey: z.string().refine(isRealMonth, "Kỳ không hợp lệ."),
  reason: z.string().trim().max(300),
});

/**
 * Ghi lý do một đại lý không lấy hàng trong kỳ (yêu cầu mục 4).
 *
 * Lưu theo từng kỳ nên tháng sau đại lý vẫn im lặng thì phải ghi lý do mới —
 * đó chính là thông tin quản lý cần: lý do có đổi hay vẫn thế.
 */
export async function saveInactiveReasonAction(formData: FormData): Promise<{ ok?: string; error?: string }> {
  const session = await requireSession();

  const parsed = noteSchema.safeParse({
    customerId: formData.get("customerId"),
    periodKey: formData.get("periodKey"),
    reason: formData.get("reason"),
  });

  if (!parsed.success) return { error: parsed.error.issues[0].message };
  const data = parsed.data;

  // Chỉ ghi lý do cho khách trong PHẠM VI của mình (quản lý: nhánh mình; NVKD: khách mình phụ trách) — trước đây quản lý ghi được cho mọi đại lý.
  const scope = await scopeFilter(session, { tenantId: customers.tenantId, ownerId: customers.ownerId, territoryId: customers.territoryId });
  const [customer] = await db
    .select({ code: customers.code, orgName: customers.orgName })
    .from(customers)
    .where(and(scope, eq(customers.id, data.customerId)))
    .limit(1);
  if (!customer) return { error: "Không tìm thấy đại lý trong phạm vi của bạn." };

  const [previous] = await db
    .select({ reason: dealerInactiveNotes.reason })
    .from(dealerInactiveNotes)
    .where(and(eq(dealerInactiveNotes.tenantId, session.tenantId), eq(dealerInactiveNotes.customerId, data.customerId), eq(dealerInactiveNotes.periodKey, data.periodKey)))
    .limit(1);

  // Xoá trắng ô lý do nghĩa là gỡ ghi chú, không lưu chuỗi rỗng.
  if (!data.reason) {
    await db
      .delete(dealerInactiveNotes)
      .where(
        and(
          eq(dealerInactiveNotes.tenantId, session.tenantId),
          eq(dealerInactiveNotes.customerId, data.customerId),
          eq(dealerInactiveNotes.periodKey, data.periodKey),
        ),
      );
    if (previous) await writeAudit(session, "DELETE", "inactive_reason", data.customerId, { code: customer.code, orgName: customer.orgName, periodKey: data.periodKey, reason: previous.reason });
  } else {
    await db
      .insert(dealerInactiveNotes)
      .values({
        tenantId: session.tenantId,
        customerId: data.customerId,
        periodKey: data.periodKey,
        reason: data.reason,
        recordedBy: session.userId,
      })
      .onConflictDoUpdate({
        target: [dealerInactiveNotes.customerId, dealerInactiveNotes.periodKey],
        set: { reason: data.reason, recordedBy: session.userId, recordedAt: new Date() },
      });
    if (previous?.reason !== data.reason) {
      await writeAudit(session, previous ? "UPDATE" : "CREATE", "inactive_reason", data.customerId, {
        code: customer.code,
        orgName: customer.orgName,
        periodKey: data.periodKey,
        ...(previous ? { changes: { reason: { from: previous.reason, to: data.reason } } } : { reason: data.reason }),
      });
    }
  }

  revalidatePath("/bao-cao");
  return { ok: "Đã lưu lý do." };
}
