"use server";

import { revalidatePath } from "next/cache";
import { and, eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/db";
import { events, territories, auditLogs } from "@/db/schema";
import { requireSession } from "@/lib/auth";
import { isRealDate } from "@/lib/period";
import { isUuid } from "@/lib/route-params";
import { canManageEvents, eventOwnerOptions, eventScope } from "@/lib/events-scope";

const eventSchema = z.object({
  name: z.string().trim().min(3, "Tên chuyên đề quá ngắn."),
  eventDate: z.string().refine(isRealDate, "Ngày tổ chức không hợp lệ."),
  kind: z.string().trim().max(50),
  territoryId: z.string().uuid().optional().or(z.literal("")),
  ownerId: z.string().uuid().optional().or(z.literal("")),
  invitedCount: z.coerce.number().int().min(0, "Số lượng mời không được âm."),
  attendedCount: z.coerce.number().int().min(0, "Số lượng tham dự không được âm."),
  resultOrderCount: z.coerce.number().int().min(0).default(0),
  resultRevenue: z.coerce.number().int().min(0).default(0),
  note: z.string().trim().max(500).optional(),
});

export type EventState = { error?: string; ok?: string };

export async function saveEventAction(_prev: EventState, formData: FormData): Promise<EventState> {
  const session = await requireSession();
  if (!(await canManageEvents(session))) return { error: "Bạn không có quyền quản lý chuyên đề." };

  const parsed = eventSchema.safeParse({
    name: formData.get("name"),
    eventDate: formData.get("eventDate"),
    kind: formData.get("kind") || "Chuyên đề",
    territoryId: formData.get("territoryId") || "",
    ownerId: formData.get("ownerId") || "",
    invitedCount: formData.get("invitedCount") || 0,
    attendedCount: formData.get("attendedCount") || 0,
    resultOrderCount: formData.get("resultOrderCount") || 0,
    resultRevenue: formData.get("resultRevenue") || 0,
    note: formData.get("note") || undefined,
  });

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

  // Số người tham dự không thể vượt số người được mời — sai ở đây làm tỷ lệ tham
  // dự vượt 100% và mọi so sánh giữa các chuyên đề mất ý nghĩa.
  if (data.attendedCount > data.invitedCount) {
    return { error: "Số lượng tham dự không thể lớn hơn số lượng mời." };
  }

  const values = {
    tenantId: session.tenantId,
    name: data.name,
    eventDate: data.eventDate,
    kind: data.kind,
    territoryId: data.territoryId || null,
    ownerId: data.ownerId || null,
    invitedCount: data.invitedCount,
    attendedCount: data.attendedCount,
    resultOrderCount: data.resultOrderCount,
    resultRevenue: data.resultRevenue,
    note: data.note ?? null,
  };

  const id = String(formData.get("id") ?? "");

  // Người phụ trách chỉ được là nhân viên trong phạm vi của người ghi (nhân viên chuyên môn: chính mình) — không gán lớp cho người ngoài nhánh.
  const owners = await eventOwnerOptions(session);
  if (session.role === "SALES") values.ownerId = session.userId;
  else if (values.ownerId && !owners.some((o) => o.id === values.ownerId)) return { error: "Người phụ trách nằm ngoài phạm vi của bạn." };
  if (values.territoryId) {
    const [area] = await db.select({ id: territories.id }).from(territories).where(and(eq(territories.tenantId, session.tenantId), eq(territories.id, values.territoryId))).limit(1);
    if (!area) return { error: "Khu vực không hợp lệ." };
  }

  if (id) {
    // Chỉ sửa lớp nằm trong phạm vi của mình (trước đây chỉ kiểm tenant nên quản lý sửa được lớp của vùng khác).
    if (!isUuid(id)) return { error: "Không tìm thấy chuyên đề." };
    const [mine] = await db.select({ id: events.id }).from(events).where(and(await eventScope(session, "edit"), eq(events.id, id))).limit(1);
    if (!mine) return { error: "Chuyên đề không còn tồn tại hoặc nằm ngoài phạm vi của bạn." };
    await db
      .update(events)
      .set(values)
      .where(and(eq(events.tenantId, session.tenantId), eq(events.id, id)));
  } else {
    await db.insert(events).values(values);
  }

  await db.insert(auditLogs).values({
    tenantId: session.tenantId,
    userId: session.userId,
    action: id ? "UPDATE" : "CREATE",
    entityType: "event",
    entityId: id || null,
    payload: { name: data.name, eventDate: data.eventDate, attended: data.attendedCount },
  });

  revalidatePath("/danh-muc/su-kien");
  revalidatePath("/bao-cao");
  revalidatePath("/bao-cao/chuyen-giao");
  return { ok: id ? "Đã cập nhật chuyên đề." : `Đã thêm "${data.name}".` };
}

export async function deleteEventAction(formData: FormData): Promise<{ ok?: string; error?: string }> {
  const session = await requireSession();
  if (!(await canManageEvents(session))) return { error: "Bạn không có quyền xoá chuyên đề." };

  const id = String(formData.get("id") ?? "");
  if (!isUuid(id)) return { error: "Không tìm thấy chuyên đề." };
  // Chỉ xoá lớp nằm trong phạm vi của mình.
  const [mine] = await db.select({ id: events.id, name: events.name }).from(events).where(and(await eventScope(session, "edit"), eq(events.id, id))).limit(1);
  if (!mine) return { error: "Chuyên đề đã được xoá trước đó hoặc nằm ngoài phạm vi của bạn — hãy tải lại trang." };

  await db.delete(events).where(and(eq(events.tenantId, session.tenantId), eq(events.id, id)));
  await db.insert(auditLogs).values({ tenantId: session.tenantId, userId: session.userId, action: "DELETE", entityType: "event", entityId: id, payload: { name: mine.name } });

  revalidatePath("/danh-muc/su-kien");
  revalidatePath("/bao-cao");
  revalidatePath("/bao-cao/chuyen-giao");
  return { ok: "Đã xoá." };
}
