// plugins/router/routePermissions.ts
import type { RouteLocationNormalized } from "vue-router";
import { useUserStore } from "@/stores/user";

export interface RoutePermissions {
  permissions?: string[];
  permissionLogic?: "AND" | "OR";
  roles?: string[];
  roleLogic?: "AND" | "OR";
}

// ========================================================================
// PERMISSIONS MAP — PORTAL ROUTES REMOVED
// ========================================================================
export const routePermissionsMap: Record<string, RoutePermissions> = {
  // PUBLIC ROUTES
  "/login": { permissions: [] },
  "/forgot-password": { permissions: [] },
  "/reset-password": { permissions: [] },
  "/force-reset-password": { permissions: [] },
  "/not-authorized": { permissions: [] },
  "/error": { permissions: [] },
  "/account-error": { permissions: [] }, // ← Added this

  // DASHBOARD — All authenticated users
  "/dashboard": { permissions: [] },

  // SHAREHOLDERS MANAGEMENT
  "/shareholders": {
    permissions: ["view shareholders", "manage shareholders"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/shareholders/create": {
    permissions: ["view shareholders", "manage shareholders"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },

  "/shareholders/:id": {
    permissions: ["view shareholders", "manage shareholders"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },

  // PAYMENTS
  "/payments": {
    permissions: ["view payments", "manage payments", "view own payments"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner", "Shareholder"],
    roleLogic: "OR",
  },

  "/payments/:id": {
    permissions: ["view payments", "manage payments", "view own payments"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },

  // INVOICES
  "/invoices": {
    permissions: ["view invoices", "manage invoices", "view own invoices"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner", "Shareholder"],
    roleLogic: "OR",
  },

  "/invoices/generate-annual": {
    permissions: ["manage invoices"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/invoices/:id": {
    permissions: ["view invoices", "manage invoices"],
    permissionLogic: "OR",
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },

  // REPORTS
  "/reports": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/reports/shareholder-summary": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/reports/payment-history": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/reports/arrears": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/reports/monthly-contributions": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },
  "/reports/shareholder/:id/statement": {
    permissions: ["view reports"],
    roles: ["Admin", "Finance", "SystemOwner"],
    roleLogic: "OR",
  },

  // USER MANAGEMENT
  "/users": {
    permissions: ["manage users"],
    roles: ["Admin", "SystemOwner"],
    roleLogic: "OR",
  },

  "/users/:id": {
    permissions: ["manage users"],
    roles: ["Admin", "SystemOwner"],
    roleLogic: "OR",
  },

  // PROFILE & AUDIT
  "/profile": { permissions: [] },
  "/my-profile": { permissions: [] }, // ← Added this
  "/audit-logs": {
    permissions: ["view audit logs"],
    roles: ["SystemOwner", "Admin"],
    roleLogic: "OR",
  },
};

// ========================================================================
// HELPER: Get permissions for a route
// ========================================================================
export const getRoutePermissions = (
  route: RouteLocationNormalized,
): RoutePermissions | null => {
  let path = route.path;
  if (!path.startsWith("/")) path = `/${path}`;
  if (path !== "/" && path.endsWith("/")) path = path.slice(0, -1);

  // Exact match
  if (routePermissionsMap[path]) return routePermissionsMap[path];

  // Match dynamic segments (:id, :anything)
  const segments = path.split("/").filter(Boolean);
  for (let i = segments.length; i > 0; i--) {
    const partialPath = "/" + segments.slice(0, i).join("/");

    // Check exact parent path
    if (routePermissionsMap[partialPath])
      return routePermissionsMap[partialPath];

    // Match dynamic patterns
    for (const pattern in routePermissionsMap) {
      if (!pattern.includes(":")) continue;
      const patternSegments = pattern.split("/").filter(Boolean);
      if (patternSegments.length !== i) continue;

      const matches = patternSegments.every(
        (seg, idx) => seg.startsWith(":") || seg === segments[idx],
      );
      if (matches) return routePermissionsMap[pattern];
    }
  }

  // Fallback to route.meta
  if (route.meta.permissions || route.meta.roles) {
    return {
      permissions: (route.meta.permissions as string[]) || [],
      permissionLogic: (route.meta.permissionLogic as "AND" | "OR") || "AND",
      roles: (route.meta.roles as string[]) || [],
      roleLogic: (route.meta.roleLogic as "AND" | "OR") || "AND",
    };
  }

  return null;
};

// ========================================================================
// PINIA-BASED USER HELPERS
// ========================================================================
const userStore = () => useUserStore();
const currentUser = () => userStore().user;

export const isAuthenticated = (): boolean =>
  userStore().isAuthenticated && !!userStore().token;

export const isAdmin = (): boolean => userStore().isAdmin;
export const isShareholder = (): boolean => userStore().isShareholder;

export const hasRole = (role: string): boolean => {
  const roleName = currentUser()?.user_role;
  return roleName?.toLowerCase() === role.toLowerCase();
};

export const getUserPermissions = (): string[] => {
  // Use the abilityRules from the store (this is where your Spatie permissions live)
  return userStore().abilityRules || [];
};

// ========================================================================
// PERMISSION & ROLE CHECKERS (now respect AND/OR logic!)
// ========================================================================
const checkRoles = (
  required: string[] = [],
  userRole: string,
  logic: "AND" | "OR" = "OR",
): boolean => {
  if (required.length === 0) return true;
  const lowerUserRole = userRole.toLowerCase();
  const lowerRequired = required.map((r) => r.toLowerCase());

  return logic === "OR"
    ? lowerRequired.includes(lowerUserRole)
    : lowerRequired.every((r) => r === lowerUserRole);
};

const checkPermissions = (
  required: string[] = [],
  userPerms: string[],
  logic: "AND" | "OR" = "OR",
): boolean => {
  if (required.length === 0) return true;
  return logic === "OR"
    ? required.some((p) => userPerms.includes(p))
    : required.every((p) => userPerms.includes(p));
};

// ========================================================================
// MAIN: canAccessRoute
// ========================================================================
export const canAccessRoute = (route: RouteLocationNormalized): boolean => {
  const user = currentUser();
  if (!user) return false;

  const perms = getRoutePermissions(route);
  if (!perms) return true; // No restrictions defined → allow

  const userRole = user.user_role || "";
  const userPermissions = getUserPermissions();

  // Check roles
  if (perms.roles && perms.roles.length > 0) {
    const roleLogic = perms.roleLogic || "OR";
    if (!checkRoles(perms.roles, userRole, roleLogic)) {
      return false;
    }
  }

  // Check permissions
  if (perms.permissions && perms.permissions.length > 0) {
    const permLogic = perms.permissionLogic || "OR";
    if (!checkPermissions(perms.permissions, userPermissions, permLogic)) {
      return false;
    }
  }

  return true;
};
