"use server";

import { revalidatePath } from "next/cache";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/db";
import { tenants, auditLogs } from "@/db/schema";
import { requireSession } from "@/lib/auth";
import { canManageSettings } from "@/lib/rbac";

const MAX_LOGO_BYTES = 500 * 1024;
const ALLOWED_LOGO_TYPES = ["image/png", "image/jpeg", "image/webp", "image/svg+xml"];

const nameSchema = z.string().trim().min(2, "Tên công ty quá ngắn.").max(200);
const taxCodeSchema = z.string().trim().max(20, "Mã số thuế quá dài.").optional();
const percentSchema = z.coerce.number().int().min(1, "Ngưỡng phải từ 1-99%.").max(99, "Ngưỡng phải từ 1-99%.");

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

async function requireAdmin() {
  const session = await requireSession();
  if (!canManageSettings(session)) {
    throw new Error("Chỉ Ban giám đốc mới được sửa cài đặt chung.");
  }
  return session;
}

export async function updateTenantSettingsAction(
  _prev: SettingsState,
  formData: FormData,
): Promise<SettingsState> {
  let session;
  try {
    session = await requireAdmin();
  } catch (error) {
    return { error: error instanceof Error ? error.message : "Không có quyền." };
  }

  const parsedName = nameSchema.safeParse(formData.get("name"));
  if (!parsedName.success) return { error: parsedName.error.issues[0].message };
  const name = parsedName.data;

  const parsedTaxCode = taxCodeSchema.safeParse(formData.get("taxCode") || undefined);
  if (!parsedTaxCode.success) return { error: parsedTaxCode.error.issues[0].message };
  const taxCode = parsedTaxCode.data || null;

  const parsedRevenueDrop = percentSchema.safeParse(formData.get("alertRevenueDropPercent"));
  if (!parsedRevenueDrop.success) return { error: parsedRevenueDrop.error.issues[0].message };
  const alertRevenueDropPercent = parsedRevenueDrop.data;

  const parsedStaffMin = percentSchema.safeParse(formData.get("alertStaffMinAchievementPercent"));
  if (!parsedStaffMin.success) return { error: parsedStaffMin.error.issues[0].message };
  const alertStaffMinAchievementPercent = parsedStaffMin.data;

  const logoFile = formData.get("logo");
  let logoDataUrl: string | undefined;

  if (logoFile instanceof File && logoFile.size > 0) {
    if (!ALLOWED_LOGO_TYPES.includes(logoFile.type)) {
      return { error: "Logo phải là ảnh PNG, JPEG, WEBP hoặc SVG." };
    }
    if (logoFile.size > MAX_LOGO_BYTES) {
      return { error: "Ảnh logo quá lớn — tối đa 500KB." };
    }
    const bytes = Buffer.from(await logoFile.arrayBuffer());
    logoDataUrl = `data:${logoFile.type};base64,${bytes.toString("base64")}`;
  }

  const [current] = await db
    .select({
      name: tenants.name,
      taxCode: tenants.taxCode,
      hasLogo: tenants.logoDataUrl,
      alertRevenueDropPercent: tenants.alertRevenueDropPercent,
      alertStaffMinAchievementPercent: tenants.alertStaffMinAchievementPercent,
    })
    .from(tenants)
    .where(eq(tenants.id, session.tenantId))
    .limit(1);
  if (!current) return { error: "Không tìm thấy công ty." };

  await db
    .update(tenants)
    .set({
      name,
      taxCode,
      alertRevenueDropPercent,
      alertStaffMinAchievementPercent,
      ...(logoDataUrl ? { logoDataUrl } : {}),
    })
    .where(eq(tenants.id, session.tenantId));

  const changes: Record<string, { from: unknown; to: unknown }> = {};
  if (current.name !== name) changes.name = { from: current.name, to: name };
  if (current.taxCode !== taxCode) changes.taxCode = { from: current.taxCode, to: taxCode };
  if (current.alertRevenueDropPercent !== alertRevenueDropPercent)
    changes.alertRevenueDropPercent = { from: current.alertRevenueDropPercent, to: alertRevenueDropPercent };
  if (current.alertStaffMinAchievementPercent !== alertStaffMinAchievementPercent)
    changes.alertStaffMinAchievementPercent = {
      from: current.alertStaffMinAchievementPercent,
      to: alertStaffMinAchievementPercent,
    };
  if (logoDataUrl) changes.logo = { from: current.hasLogo ? "đã có" : "chưa có", to: "đã đổi" };

  if (Object.keys(changes).length > 0) {
    await db.insert(auditLogs).values({
      tenantId: session.tenantId,
      userId: session.userId,
      action: "UPDATE",
      entityType: "tenant_settings",
      entityId: session.tenantId,
      payload: { changes },
    });
  }

  revalidatePath("/danh-muc/cai-dat");
  revalidatePath("/");
  revalidatePath("/canh-bao");
  return { ok: "Đã lưu cài đặt." };
}

export async function removeTenantLogoAction() {
  const session = await requireAdmin();

  await db.update(tenants).set({ logoDataUrl: null }).where(eq(tenants.id, session.tenantId));

  await db.insert(auditLogs).values({
    tenantId: session.tenantId,
    userId: session.userId,
    action: "UPDATE",
    entityType: "tenant_settings",
    entityId: session.tenantId,
    payload: { changes: { logo: { from: "đã có", to: "đã xoá" } } },
  });

  revalidatePath("/danh-muc/cai-dat");
  revalidatePath("/");
}
