import type { Knex } from "knex";

export async function seed(knex: Knex): Promise<void> {
  // Deletes all existing entries to avoid duplicates
  await knex("role_permissions").del();

  // Fetch role IDs from roles table
  const roles = await knex("roles").select("id", "role_code");
  const roleMap = new Map(roles.map((r) => [r.role_code, r.id]));

  if (roleMap.size === 0) {
    throw new Error("No roles found in roles table. Run roles seeder first.");
  }
  console.log("Roles found:", Array.from(roleMap.entries()));

  // Fetch permission IDs from permissions table
  const permissions = await knex("permissions").select("id", "code");
  const permissionMap = new Map(
    permissions.map((p) => {
      const codeObj = typeof p.code === "string" ? JSON.parse(p.code) : p.code;
      return [`${codeObj.action}:${codeObj.resource}`, p.id];
    })
  );

  if (permissionMap.size === 0) {
    throw new Error(
      "No permissions found in permissions table. Run permissions seeder first."
    );
  }
  console.log(
    "Permissions found:",
    permissions.map((p) => ({ id: p.id, code: p.code }))
  );

  const getPermissionId = (action: string, resource: string) => {
    return permissionMap.get(`${action}:${resource}`);
  };

  // Define explicit action-resource mappings
  const permissionDefinitions = [
    { action: "manage_users", resource: "users" },
    { action: "view_users", resource: "users" },
    { action: "manage_pages", resource: "pages" },
    { action: "view_pages", resource: "pages" },
    { action: "manage_prompts", resource: "prompts" },
    { action: "view_prompts", resource: "prompts" },
    { action: "manage_tools", resource: "tools" },
    { action: "view_tools", resource: "tools" },
    { action: "manage_settings", resource: "settings" },
    { action: "use_tools", resource: "tools" },
    { action: "view_pages", resource: "pages" },
  ];

  // Define role-to-permission mappings
  const rolePermissions = [
    // Admin: All permissions
    ...permissionDefinitions.map(({ action, resource }) => {
      const permissionId = getPermissionId(action, resource);
      if (!permissionId) {
        console.error(`Permission not found for: ${action}:${resource}`);
      }
      return {
        role_id: roleMap.get("admin"),
        permission_id: permissionId,
        created_at: new Date(),
        updated_at: new Date(),
      };
    }),
    // Developer: All permissions
    ...permissionDefinitions.map(({ action, resource }) => {
      const permissionId = getPermissionId(action, resource);
      if (!permissionId) {
        console.error(`Permission not found for: ${action}:${resource}`);
      }
      return {
        role_id: roleMap.get("developer"),
        permission_id: permissionId,
        created_at: new Date(),
        updated_at: new Date(),
      };
    }),
    // Project Manager: Page-related permissions
    ...permissionDefinitions
      .filter(({ action }) => ["manage_pages", "view_pages"].includes(action))
      .map(({ action, resource }) => {
        const permissionId = getPermissionId(action, resource);
        if (!permissionId) {
          console.error(`Permission not found for: ${action}:${resource}`);
        }
        return {
          role_id: roleMap.get("project_manager"),
          permission_id: permissionId,
          created_at: new Date(),
          updated_at: new Date(),
        };
      }),
    // Content Writer: Prompt-related permissions
    ...permissionDefinitions
      .filter(({ action }) =>
        ["manage_prompts", "view_prompts"].includes(action)
      )
      .map(({ action, resource }) => {
        const permissionId = getPermissionId(action, resource);
        if (!permissionId) {
          console.error(`Permission not found for: ${action}:${resource}`);
        }
        return {
          role_id: roleMap.get("content_writer"),
          permission_id: permissionId,
          created_at: new Date(),
          updated_at: new Date(),
        };
      }),
    ...permissionDefinitions
      .filter(({ action }) => ["view_pages", "use_tools"].includes(action))
      .map(({ action, resource }) => {
        const permissionId = getPermissionId(action, resource);
        if (!permissionId) {
          console.error(`Permission not found for: ${action}:${resource}`);
        }
        return {
          role_id: roleMap.get("web_user"),
          permission_id: permissionId,
          created_at: new Date(),
          updated_at: new Date(),
        };
      }),
  ];

  // Filter out entries with undefined permission_id or role_id
  const validRolePermissions = rolePermissions.filter(
    (rp) => rp.permission_id !== undefined && rp.role_id !== undefined
  );

  console.log("Valid Role Permissions to Insert:", validRolePermissions);

  if (validRolePermissions.length === 0) {
    throw new Error(
      "No valid role permissions to insert. Check permissions and roles tables."
    );
  }

  // Insert role permissions
  await knex("role_permissions").insert(validRolePermissions);
}
