export enum PermissionGroupEnum {
  SERVICES = "services",
  CUSTOMERS = "customers",
  USERS = "users",
  FINANCIAL = "financial",
  CONTENT = "content",
  SUPPORT = "support",
  OTHER = "other",
  PRODUCTS = "products",
  REPRESENTATIVES = "representatives",
  TASK_MANAGER = "task_manager",
}

export const PERMISSION_GROUP_ORDER: PermissionGroupEnum[] = [
  PermissionGroupEnum.SERVICES,
  PermissionGroupEnum.CUSTOMERS,
  PermissionGroupEnum.USERS,
  PermissionGroupEnum.FINANCIAL,
  PermissionGroupEnum.CONTENT,
  PermissionGroupEnum.SUPPORT,
  PermissionGroupEnum.OTHER,
  PermissionGroupEnum.PRODUCTS,
  PermissionGroupEnum.REPRESENTATIVES,
  PermissionGroupEnum.TASK_MANAGER,
];

export enum PermissionEnum {
  SERVICES_CREATE = "services_create",
  SERVICES_READ = "services_read",
  SERVICES_UPDATE = "services_update",
  SERVICES_DELETE = "services_delete",

  CUSTOMERS_CREATE = "customers_create",
  CUSTOMERS_READ = "customers_read",
  CUSTOMERS_UPDATE = "customers_update",
  CUSTOMERS_DELETE = "customers_delete",

  AGENTS_CREATE = "agents_create",
  AGENTS_READ = "agents_read",
  AGENTS_UPDATE = "agents_update",
  AGENTS_DELETE = "agents_delete",

  DEVELOPERS_CREATE = "developers_create",
  DEVELOPERS_READ = "developers_read",
  DEVELOPERS_UPDATE = "developers_update",
  DEVELOPERS_DELETE = "developers_delete",

  INVOICES_CREATE = "invoices_create",
  INVOICES_READ = "invoices_read",
  INVOICES_UPDATE = "invoices_update",
  INVOICES_DELETE = "invoices_delete",

  TRANSACTIONS_CREATE = "transactions_create",
  TRANSACTIONS_READ = "transactions_read",
  TRANSACTIONS_UPDATE = "transactions_update",
  TRANSACTIONS_DELETE = "transactions_delete",

  DISCOUNTS_CREATE = "discounts_create",
  DISCOUNTS_READ = "discounts_read",
  DISCOUNTS_UPDATE = "discounts_update",
  DISCOUNTS_DELETE = "discounts_delete",

  ADMINS_CREATE = "admins_create",
  ADMINS_READ = "admins_read",
  ADMINS_UPDATE = "admins_update",
  ADMINS_DELETE = "admins_delete",

  TICKETS_CREATE = "tickets_create",
  TICKETS_READ = "tickets_read",
  TICKETS_UPDATE = "tickets_update",
  TICKETS_DELETE = "tickets_delete",

  CRITICISMS_CREATE = "criticisms_create",
  CRITICISMS_READ = "criticisms_read",
  CRITICISMS_UPDATE = "criticisms_update",
  CRITICISMS_DELETE = "criticisms_delete",

  CONTACTS_US_CREATE = "contacts_us_create",
  CONTACTS_US_READ = "contacts_us_read",
  CONTACTS_US_UPDATE = "contacts_us_update",
  CONTACTS_US_DELETE = "contacts_us_delete",

  ADVERTISEMENTS_CREATE = "advertisements_create",
  ADVERTISEMENTS_READ = "advertisements_read",
  ADVERTISEMENTS_UPDATE = "advertisements_update",
  ADVERTISEMENTS_DELETE = "advertisements_delete",

  ANNOUNCEMENTS_CREATE = "announcements_create",
  ANNOUNCEMENTS_READ = "announcements_read",
  ANNOUNCEMENTS_UPDATE = "announcements_update",
  ANNOUNCEMENTS_DELETE = "announcements_delete",

  BLOGS_CREATE = "blogs_create",
  BLOGS_READ = "blogs_read",
  BLOGS_UPDATE = "blogs_update",
  BLOGS_DELETE = "blogs_delete",

  LEARNINGS_CREATE = "learnings_create",
  LEARNINGS_READ = "learnings_read",
  LEARNINGS_UPDATE = "learnings_update",
  LEARNINGS_DELETE = "learnings_delete",

  SETTINGS_CREATE = "settings_create",
  SETTINGS_READ = "settings_read",
  SETTINGS_UPDATE = "settings_update",
  SETTINGS_DELETE = "settings_delete",

  BANK_ACCOUNTS_CREATE = "bank_accounts_create",
  BANK_ACCOUNTS_READ = "bank_accounts_read",
  BANK_ACCOUNTS_UPDATE = "bank_accounts_update",
  BANK_ACCOUNTS_DELETE = "bank_accounts_delete",

  PAYMENTS_CREATE = "payments_create",
  PAYMENTS_READ = "payments_read",
  PAYMENTS_UPDATE = "payments_update",
  PAYMENTS_DELETE = "payments_delete",

  SUPPORT_PLAN_CREATE = "support_plan_create",
  SUPPORT_PLAN_READ = "support_plan_read",
  SUPPORT_PLAN_UPDATE = "support_plan_update",
  SUPPORT_PLAN_DELETE = "support_plan_delete",

  RESELLER_CREATE = "reseller_create",
  RESELLER_READ = "reseller_read",
  RESELLER_UPDATE = "reseller_update",
  RESELLER_DELETE = "reseller_delete",

  WORKSPACE_CREATE = "workspace_create",
  WORKSPACE_READ = "workspace_read",
  WORKSPACE_UPDATE = "workspace_update",
  WORKSPACE_DELETE = "workspace_delete",

  PROJECT_CREATE = "project_create",
  PROJECT_READ = "project_read",
  PROJECT_UPDATE = "project_update",
  PROJECT_DELETE = "project_delete",

  TASK_CREATE = "task_create",
  TASK_READ = "task_read",
  TASK_UPDATE = "task_update",
  TASK_DELETE = "task_delete",

  TASK_PHASE_CREATE = "task_phase_create",
  TASK_PHASE_READ = "task_phase_read",
  TASK_PHASE_UPDATE = "task_phase_update",
  TASK_PHASE_DELETE = "task_phase_delete",

  LOGS = "logs",
  MANAGE_SSO_CLIENTS = "manage_sso_clients",
  DMENU = "dmenu",
  DKALA = "dkala",
  DPAGE = "dpage",
  DMAIL = "dmail",
}

const CRUD_ACTIONS = ["create", "read", "update", "delete"] as const;

export const CONTENT_PERMISSION_RESOURCES = ["blogs", "learnings", "advertisements", "announcements"] as const;
export const FINANCIAL_PERMISSION_RESOURCES = ["payments", "invoices", "transactions", "discounts", "bank_accounts"] as const;
export const SUPPORT_PERMISSION_RESOURCES = ["support_plan", "tickets"] as const;
export const TASK_MANAGER_PERMISSION_RESOURCES = ["workspace", "project", "task", "task_phase"] as const;
export const USERS_SIDEBAR_PERMISSION_RESOURCES = ["admins"] as const;
export const PRODUCT_PERMISSION_RESOURCES = ["dmenu", "dkala", "dpage", "dmail"] as const;

type PermissionEntry = { name: string };

export const getPermissionNames = (permissions: PermissionEntry[] | undefined): string[] =>
  permissions?.map((permission) => permission.name) ?? [];

export const hasPermission = (
  permissions: PermissionEntry[] | undefined,
  resourceOrPermission: string,
): boolean => {
  const names = getPermissionNames(permissions);

  if (names.includes(resourceOrPermission)) {
    return true;
  }

  return CRUD_ACTIONS.some((action) => names.includes(`${resourceOrPermission}_${action}`));
};

export const hasAnyPermission = (
  permissions: PermissionEntry[] | undefined,
  resources: readonly string[],
): boolean => resources.some((resource) => hasPermission(permissions, resource));

export const canAccessMenuItem = (
  permissions: PermissionEntry[] | undefined,
  activeName?: string,
  activeNames?: readonly string[],
): boolean => {
  if (activeNames && activeNames.length > 0) {
    return hasAnyPermission(permissions, activeNames);
  }

  if (!activeName) {
    return true;
  }

  return hasPermission(permissions, activeName);
};
