/**
 * Permission matrix config for Groups (Access & Groups model).
 * Used by GroupPermissionCrudMatrix and group form pages.
 *
 * Backend source of truth: apps/api/config/access_modules.php (Access Catalog).
 * Permission names are seeded from that catalog; frontend permission_prefix and module
 * lists should align so that levelToPermissionNames() produces names that exist in the API.
 *
 * Scopes:
 * - global: Settings-level (applicable to global groups → company/project inheritance)
 * - company: Company-level (company groups → project inheritance)
 * - project: Project-level only
 */

/** Permission key format: module.action or module.view (backend-ready). */
export const MATRIX_SCOPES = Object.freeze({
  GLOBAL: "global",
  COMPANY: "company",
  PROJECT: "project",
});

/**
 * Rows for the permission matrix per scope.
 * Each row: { id, label, permission }.
 * permission is the key used for resolver (e.g. companies.view, projects.view).
 */
export const PERMISSION_MATRIX_ROWS = Object.freeze({
  [MATRIX_SCOPES.GLOBAL]: [
    {
      id: "settings.company",
      label: "Bedrijfsgegevens",
      permission: "settings.company.view",
    },
    { id: "users", label: "Gebruikers", permission: "users.view" },
    { id: "roles", label: "Rollen", permission: "roles.view" },
    {
      id: "activitylog",
      label: "Activiteiten",
      permission: "activitylog.view",
    },
    { id: "sectors", label: "Sectoren", permission: "sectors.view" },
    { id: "jobfunctions", label: "Functies", permission: "jobfunctions.view" },
    { id: "departments", label: "Afdelingen", permission: "departments.view" },
    {
      id: "subsidythemes",
      label: "Thema's",
      permission: "subsidythemes.view",
    },
    {
      id: "subsidygrantors",
      label: "Subsidie verstrekkers",
      permission: "subsidygrantors.view",
    },
    { id: "groups", label: "Groepen", permission: "groups.view" },
    { id: "companies", label: "Bedrijven", permission: "companies.view" },
    { id: "projects", label: "Projecten", permission: "projects.view" },
    { id: "leads", label: "Leads", permission: "leads.view" },
    { id: "tasks", label: "Taken", permission: "tasks.view" },
    { id: "notes", label: "Notities", permission: "notes.view" },
    {
      id: "costs.internal",
      label: "Interne kosten",
      permission: "costs.internal.view",
    },
    {
      id: "costs.external",
      label: "Externe kosten",
      permission: "costs.external.view",
    },
    { id: "documents", label: "Documenten", permission: "documents.view" },
    { id: "hours", label: "Uren", permission: "hours.view" },
    { id: "invoices", label: "Facturen", permission: "invoices.view" },
    { id: "reports", label: "Rapporten", permission: "reports.view" },
  ],
  [MATRIX_SCOPES.COMPANY]: [
    {
      id: "company.dashboard",
      label: "Dashboard",
      permission: "companies.view",
    },
    {
      id: "company.edit",
      label: "Bedrijf bewerken",
      permission: "companies.edit",
    },
    { id: "company.projects", label: "Projecten", permission: "projects.view" },
    {
      id: "company.hierarchy",
      label: "Structuur",
      permission: "companies.view",
    },
    {
      id: "company.locations",
      label: "Locaties",
      permission: "companies.view",
    },
    {
      id: "company.contacts",
      label: "Contactpersonen",
      permission: "companies.view",
    },
    { id: "company.tasks", label: "Taken", permission: "companies.view" },
    {
      id: "company.documents",
      label: "Documenten",
      permission: "companies.view",
    },
    {
      id: "company.settings",
      label: "Instellingen",
      permission: "companies.view",
    },
    { id: "company.invoices", label: "Facturen", permission: "companies.view" },
    { id: "company.groups", label: "Groepen", permission: "groups.view" },
  ],
  [MATRIX_SCOPES.PROJECT]: [
    {
      id: "project.dashboard",
      label: "Dashboard",
      permission: "projects.view",
    },
    { id: "project.workflow", label: "Workflow", permission: "projects.view" },
    {
      id: "project.milestones",
      label: "Mijlpalen",
      permission: "projects.view",
    },
    { id: "project.taken", label: "Taken", permission: "projects.view" },
    {
      id: "project.bestanden",
      label: "Bestanden",
      permission: "projects.view",
    },
    {
      id: "project.activiteiten",
      label: "Activiteiten",
      permission: "projects.view",
    },
    {
      id: "project.budget-planning",
      label: "Budgetplanning",
      permission: "projects.view",
    },
    {
      id: "project.bewijsstukken-planning",
      label: "Bewijsstukken planning",
      permission: "projects.view",
    },
    {
      id: "project.interne-kosten",
      label: "Interne kosten",
      permission: "projects.view",
    },
    {
      id: "project.externe-kosten",
      label: "Externe kosten",
      permission: "projects.view",
    },
    {
      id: "project.bewijsstukken",
      label: "Bewijsstukken",
      permission: "projects.view",
    },
    {
      id: "project.facturatie",
      label: "Facturatie",
      permission: "projects.view",
    },
    {
      id: "project.budget-realisatie",
      label: "Budgetrealisatie",
      permission: "projects.view",
    },
    {
      id: "project.instellingen",
      label: "Instellingen",
      permission: "projects.view",
    },
    { id: "project.groups", label: "Groepen", permission: "groups.view" },
  ],
});

/**
 * Get matrix rows for a scope.
 * @param {string} scope - MATRIX_SCOPES.GLOBAL | COMPANY | PROJECT
 * @returns {Array<{ id: string, label: string, permission: string }>}
 */
export function getMatrixRowsForScope(scope) {
  return PERMISSION_MATRIX_ROWS[scope] ?? [];
}

// --- CRUD-level permission UI (group form full page) ---

/** Permission level for module dropdown: none | view | create | edit | delete */
export const PERMISSION_LEVELS = Object.freeze([
  { value: "none", label: "Geen" },
  { value: "view", label: "Bekijken" },
  { value: "create", label: "Aanmaken" },
  { value: "edit", label: "Bewerken" },
  { value: "delete", label: "Verwijderen" },
]);

const LEVEL_ORDER = ["none", "view", "create", "edit", "delete"];

/**
 * Map permission level to permission names. Uses editSuffix for the "edit" action (e.g. 'update' for groups).
 * @param {string} prefix - unique permission prefix (e.g. 'company.contacts', 'project.workflow')
 * @param {string} level - 'none' | 'view' | 'create' | 'edit' | 'delete'
 * @param {string} [editSuffix='edit'] - suffix for edit level (e.g. 'update' for company.groups, project.groups)
 * @returns {string[]}
 */
export function levelToPermissionNames(prefix, level, editSuffix = "edit") {
  if (!prefix || level === "none") return [];
  const normalized = normalizeLevel(level);
  const idx = LEVEL_ORDER.indexOf(normalized);
  if (idx <= 0) return [];
  const actionNames = ["view", "create", "edit", "delete"];
  return actionNames.slice(0, idx).map((action) => {
    const suffix = action === "edit" ? editSuffix : action;
    return `${prefix}.${suffix}`;
  });
}

/**
 * Infer highest permission level from permission names for a prefix.
 * @param {string} prefix - e.g. 'company.contacts'
 * @param {string[]} permissionNames - full list of permission names (e.g. from API)
 * @param {string} [editSuffix='edit'] - suffix used for edit (e.g. 'update')
 * @returns {string} - 'none' | 'view' | 'create' | 'edit' | 'delete'
 */
export function permissionNamesToLevel(
  prefix,
  permissionNames,
  editSuffix = "edit",
) {
  if (!prefix || !Array.isArray(permissionNames)) return "none";
  const set = new Set(permissionNames);
  if (set.has(`${prefix}.delete`)) return "delete";
  const editKey = `${prefix}.${editSuffix}`;
  if (set.has(editKey)) return "edit";
  if (set.has(`${prefix}.create`)) return "create";
  if (set.has(`${prefix}.view`)) return "view";
  return "none";
}

export function normalizeLevel(level) {
  if (level == null) return "none";
  if (typeof level === "string") return level;
  if (
    typeof level === "object" &&
    level !== null &&
    "value" in level &&
    typeof level.value === "string"
  )
    return level.value;
  return "none";
}

/**
 * Flatten permissions object to array of permission name strings.
 * Handles flat API shape { "company.contacts.view": true } and nested { company: { contacts: { view: true } } }.
 */
export function flattenPermissionNamesFromObject(obj, keyPrefix = "") {
  if (!obj || typeof obj !== "object") return [];
  const out = [];
  for (const [key, value] of Object.entries(obj)) {
    if (value === true && key.includes(".")) {
      out.push(key);
    } else if (value === true && !key.includes(".")) {
      out.push(keyPrefix ? `${keyPrefix}.${key}` : key);
    } else if (value && typeof value === "object" && !Array.isArray(value)) {
      out.push(
        ...flattenPermissionNamesFromObject(
          value,
          keyPrefix ? `${keyPrefix}.${key}` : key,
        ),
      );
    }
  }
  return out.filter((s) => typeof s === "string" && s.includes("."));
}

/**
 * Normalized catalog module for matrix: id = permission_prefix, label, permission_prefix, edit_suffix.
 * When using backend catalog, pass modules from GET /api/access/catalog (company or project array).
 */
export function catalogModulesToMatrix(catalogModules) {
  if (!Array.isArray(catalogModules)) return [];
  return catalogModules.map((m) => ({
    id: m.permission_prefix,
    label: m.label,
    permission_prefix: m.permission_prefix,
    edit_suffix: m.edit_suffix ?? "edit",
  }));
}
