import type { User } from "../drizzle/schema";
import * as db from "./db";

export const LOGISTICS_GROUP_SETTING_KEY = "system.logistics.group";

export type LogisticsGroupSettings = {
  label: string;
  memberUserIds: number[];
  updatedAt: string | null;
};

const defaultLogisticsGroup: LogisticsGroupSettings = {
  label: "Groupe interne matériel CCDS - logistique et contrôle",
  memberUserIds: [],
  updatedAt: null,
};

function sanitizeMemberUserIds(value: unknown) {
  if (!Array.isArray(value)) return [];
  return Array.from(
    new Set(
      value
        .map((entry) => Number(entry))
        .filter((entry) => Number.isInteger(entry) && entry > 0)
    )
  );
}

export async function getLogisticsGroupSettings(): Promise<LogisticsGroupSettings> {
  const storedValue = await db.getPortalSetting(LOGISTICS_GROUP_SETTING_KEY);
  if (!storedValue) return defaultLogisticsGroup;

  try {
    const parsed = JSON.parse(storedValue) as Partial<LogisticsGroupSettings>;
    return {
      label: typeof parsed.label === "string" && parsed.label.trim()
        ? parsed.label.trim()
        : defaultLogisticsGroup.label,
      memberUserIds: sanitizeMemberUserIds(parsed.memberUserIds),
      updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : null,
    };
  } catch {
    return defaultLogisticsGroup;
  }
}

export async function saveLogisticsGroupSettings(input: {
  label?: string;
  memberUserIds?: number[];
}) {
  const nextValue: LogisticsGroupSettings = {
    label: input.label?.trim() || defaultLogisticsGroup.label,
    memberUserIds: sanitizeMemberUserIds(input.memberUserIds),
    updatedAt: new Date().toISOString(),
  };

  await db.setPortalSetting(
    LOGISTICS_GROUP_SETTING_KEY,
    JSON.stringify(nextValue),
    "Groupe interne à accès limité autorisé à traiter les demandes de matériel CCDS, piloter les restitutions et contrôler les retours"
  );

  return nextValue;
}

export async function userHasLogisticsAccess(user: Pick<User, "id" | "role" | "canManageLogistics">) {
  if (user.role === "super_admin" || user.canManageLogistics) {
    return true;
  }

  const group = await getLogisticsGroupSettings();
  return group.memberUserIds.includes(user.id);
}

export async function withEffectiveLogisticsAccess<TUser extends User | null>(user: TUser): Promise<TUser> {
  if (!user) return user;
  const effectiveAccess = await userHasLogisticsAccess(user);
  return {
    ...user,
    canManageLogistics: effectiveAccess,
  } as TUser;
}
