import type { AuthUser } from "@/auth/types";
import type { RuleEngineResourceSlug } from "@/types/rule-engine";

export const FREIGHT_PERMS = {
  bookings: {
    view: "edr_freight_app:bookings:view",
    staffAccept: "edr_freight_app:bookings:staff_accept",
    requestChanges: "edr_freight_app:bookings:request_changes",
    reject: "edr_freight_app:bookings:reject",
    approveLineStaff: "edr_freight_app:bookings:approve_line_staff",
    approveDirector: "edr_freight_app:bookings:approve_director",
    approveCeo: "edr_freight_app:bookings:approve_ceo",
    rejectApproval: "edr_freight_app:bookings:reject_approval",
    generateContract: "edr_freight_app:bookings:generate_contract",
    signStaff: "edr_freight_app:bookings:sign_staff",
    operations: "edr_freight_app:bookings:operations",
    cancel: "edr_freight_app:bookings:cancel",
    reviewDocuments: "edr_freight_app:bookings:review_documents",
    uploadClearanceOutput: "edr_freight_app:bookings:upload_clearance_output",
    finalizeClearance: "edr_freight_app:bookings:finalize_clearance",
  },
  trainScheduling: {
    view: "edr_freight_app:train_scheduling:view",
    manage: "edr_freight_app:train_scheduling:manage",
  },
  fleet: {
    view: "edr_freight_app:fleet:view",
    manage: "edr_freight_app:fleet:manage",
  },
  admin: "edr_freight_app:admin",
} as const;

const slugToResourceKey = (slug: RuleEngineResourceSlug): string =>
  slug.replace(/-/g, "_");

export function getPermissionKeys(user: AuthUser | null | undefined): string[] {
  if (!user) return [];
  if (user.permissionKeys?.length) return user.permissionKeys;

  const keys = new Set<string>();
  for (const p of user.permissions ?? []) {
    if (p.key) keys.add(p.key);
  }
  for (const emp of user.employee ?? []) {
    for (const pos of emp.positions ?? []) {
      for (const p of pos.permissions ?? []) {
        if (p.key) keys.add(p.key);
      }
    }
  }
  return [...keys];
}

export function isSuperAdmin(user: AuthUser | null | undefined): boolean {
  if (user?.isSuperAdmin) return true;
  return Boolean(user?.roles?.some((r) => r.key === "super_admin"));
}

/** Org-level admins may act on any approval step in the chain. */
export function isOrganizationAdmin(
  user: AuthUser | null | undefined,
): boolean {
  return Boolean(user?.roles?.some((r) => r.key === "organization_admin"));
}

export function isFreightApprovalAdmin(
  user: AuthUser | null | undefined,
): boolean {
  return isSuperAdmin(user) || isOrganizationAdmin(user);
}

export function hasPermission(
  user: AuthUser | null | undefined,
  key: string,
): boolean {
  if (!user) return false;
  if (isSuperAdmin(user)) return true;
  return getPermissionKeys(user).includes(key);
}

export function canAccessBookings(user: AuthUser | null | undefined): boolean {
  return hasPermission(user, FREIGHT_PERMS.bookings.view);
}

export function canViewScheduling(user: AuthUser | null | undefined): boolean {
  return hasPermission(user, FREIGHT_PERMS.trainScheduling.view);
}

export function canManageScheduling(user: AuthUser | null | undefined): boolean {
  return hasPermission(user, FREIGHT_PERMS.trainScheduling.manage);
}

export function canViewFleet(user: AuthUser | null | undefined): boolean {
  return hasPermission(user, FREIGHT_PERMS.fleet.view);
}

export function isFreightAdmin(user: AuthUser | null | undefined): boolean {
  return hasPermission(user, FREIGHT_PERMS.admin);
}

export function ruleEngineViewKey(slug: RuleEngineResourceSlug): string {
  return `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:view`;
}

export function ruleEngineManageKey(slug: RuleEngineResourceSlug): string {
  return `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:manage`;
}

export function canAccessRuleEngineResource(
  user: AuthUser | null | undefined,
  slug: RuleEngineResourceSlug,
  mode: "view" | "manage",
): boolean {
  const key = mode === "manage" ? ruleEngineManageKey(slug) : ruleEngineViewKey(slug);
  return hasPermission(user, key);
}

export function canAccessAnyRuleEngineView(
  user: AuthUser | null | undefined,
  slugs: RuleEngineResourceSlug[],
): boolean {
  return slugs.some((slug) => canAccessRuleEngineResource(user, slug, "view"));
}
