import { and, asc, eq, inArray, ne, or } from "drizzle-orm";
import { db } from "@/db";
import { channels, territories, users } from "@/db/schema";
import type { SessionUser } from "@/lib/auth";
import { canViewAllStaff, visibleTerritoryIds, visibleUserIds } from "@/lib/rbac";

type Current = { channelId?: string | null; territoryId?: string | null; ownerId?: string | null };

/**
 * Danh sách lựa chọn cho form khách hàng (tạo mới và chỉnh sửa) — theo phạm vi của người xem.
 *
 * `current` là giá trị đang lưu của hồ sơ khi sửa: luôn được thêm vào danh sách dù nằm ngoài phạm vi chọn thông thường
 * (kênh đã ngưng, khu vực cũ, người phụ trách không phải NVKD...). Nếu thiếu, ô chọn hiện "— Chưa xác định —" và
 * bấm Lưu sẽ xoá mất giá trị đó khỏi hồ sơ.
 */
export async function loadCustomerFormOptions(session: SessionUser, current: Current = {}) {
  const canAssignOwner = canViewAllStaff(session);
  const [allowedTerritories, allowedUsers] = await Promise.all([
    visibleTerritoryIds(session),
    canAssignOwner ? visibleUserIds(session) : Promise.resolve(null),
  ]);

  const [channelRows, territoryRows, staffRows] = await Promise.all([
    db
      .select({ id: channels.id, name: channels.name })
      .from(channels)
      .where(
        and(
          eq(channels.tenantId, session.tenantId),
          current.channelId ? or(eq(channels.isActive, true), eq(channels.id, current.channelId)) : eq(channels.isActive, true),
        ),
      )
      .orderBy(asc(channels.name)),
    db
      .select({ id: territories.id, name: territories.name })
      .from(territories)
      .where(
        and(
          eq(territories.tenantId, session.tenantId),
          eq(territories.isActive, true),
          // Khu vực của khách là tỉnh/quận — cấp Miền chỉ dùng để gom báo cáo, không gán cho từng khách.
          current.territoryId ? or(ne(territories.level, "REGION"), eq(territories.id, current.territoryId)) : ne(territories.level, "REGION"),
          // NVKD và quản lý vùng chỉ chọn được khu vực mình phụ trách.
          // (khu vực đang lưu của hồ sơ luôn chọn được, kể cả khi nằm ngoài khu vực của người sửa — ví dụ khách được giao chéo vùng)
          allowedTerritories
            ? or(inArray(territories.id, allowedTerritories), current.territoryId ? eq(territories.id, current.territoryId) : undefined)
            : undefined,
        ),
      )
      .orderBy(asc(territories.code)),
    canAssignOwner
      ? db
          .select({ id: users.id, name: users.fullName })
          .from(users)
          .where(
            and(
              eq(users.tenantId, session.tenantId),
              eq(users.isActive, true),
              // Cha chỉ giao khách cho nhân viên trong nhánh của mình (Ban giám đốc: tất cả).
              or(
                and(eq(users.role, "SALES"), allowedUsers && allowedUsers.length > 0 ? inArray(users.id, allowedUsers) : undefined),
                current.ownerId ? eq(users.id, current.ownerId) : undefined,
              ),
            ),
          )
          .orderBy(asc(users.fullName))
      : Promise.resolve([]),
  ]);

  return {
    channels: channelRows,
    territories: territoryRows,
    staff: staffRows,
    canAssignOwner,
    // Khách chưa có người phụ trách chỉ Ban giám đốc nhìn thấy, nên cấp dưới bắt buộc chọn người phụ trách.
    allowUnassigned: session.role === "DIRECTOR",
  };
}
