import { PermissionKey, SystemRole } from "@capakraken/shared";
import { ADVANCED_ASSISTANT_TOOLS, TOOL_DEFINITIONS } from "./assistant-tools.js";
import type { ToolDef } from "./assistant-tools/shared.js";

const TOOL_PERMISSION_MAP: Record<string, string> = {
  update_resource: "manageResources",
  create_resource: "manageResources",
  deactivate_resource: "manageResources",
  create_role: PermissionKey.MANAGE_ROLES,
  update_role: PermissionKey.MANAGE_ROLES,
  delete_role: PermissionKey.MANAGE_ROLES,
  update_project: "manageProjects",
  create_project: "manageProjects",
  delete_project: "manageProjects",
  create_estimate: "manageProjects",
  clone_estimate: "manageProjects",
  update_estimate_draft: "manageProjects",
  submit_estimate_version: "manageProjects",
  approve_estimate_version: "manageProjects",
  create_estimate_revision: "manageProjects",
  create_estimate_export: "manageProjects",
  generate_estimate_weekly_phasing: "manageProjects",
  update_estimate_commercial_terms: "manageProjects",
  generate_project_cover: "manageProjects",
  remove_project_cover: "manageProjects",
  import_csv_data: PermissionKey.IMPORT_DATA,
  create_allocation: "manageAllocations",
  cancel_allocation: "manageAllocations",
  update_allocation_status: "manageAllocations",
  update_timeline_allocation_inline: "manageAllocations",
  apply_timeline_project_shift: "manageAllocations",
  quick_assign_timeline_resource: "manageAllocations",
  batch_quick_assign_timeline_resources: "manageAllocations",
  batch_shift_timeline_allocations: "manageAllocations",
  create_demand: "manageAllocations",
  fill_demand: "manageAllocations",
  create_estimate_planning_handoff: "manageAllocations",
  execute_task_action: "manageAllocations",
};

const COST_TOOLS = new Set([
  "get_budget_status",
  "get_chargeability",
  "get_chargeability_report",
  "get_resource_computation_graph",
  "get_project_computation_graph",
  "resolve_rate",
  "list_rate_cards",
  "get_estimate_detail",
  "get_estimate_version_snapshot",
  "find_best_project_resource",
  "get_staffing_suggestions",
]);

const PLANNING_READ_TOOLS = new Set([
  "list_allocations",
  "list_demands",
  "list_blueprints",
  "get_blueprint",
  "list_clients",
  "list_roles",
  "list_management_levels",
  "list_utilization_categories",
  "check_resource_availability",
  "get_staffing_suggestions",
  "find_capacity",
  "find_best_project_resource",
]);

const RESOURCE_OVERVIEW_TOOLS = new Set([
  "search_resources",
  "get_country",
  "list_org_units",
]);

const CONTROLLER_ONLY_TOOLS = new Set([
  "search_by_skill",
  "search_projects",
  "get_project",
  "search_estimates",
  "get_timeline_entries_view",
  "get_timeline_holiday_overlays",
  "get_project_timeline_context",
  "preview_project_shift",
  "get_statistics",
  "get_dashboard_detail",
  "get_skill_gaps",
  "get_project_health",
  "get_budget_forecast",
  "query_change_history",
  "get_entity_timeline",
  "export_resources_csv",
  "export_projects_csv",
  "list_audit_log_entries",
  "get_audit_log_entry",
  "get_audit_log_timeline",
  "get_audit_activity_summary",
  "get_chargeability_report",
  "get_resource_computation_graph",
  "get_project_computation_graph",
  "get_estimate_detail",
  "list_estimate_versions",
  "get_estimate_version_snapshot",
  "get_estimate_weekly_phasing",
  "get_estimate_commercial_terms",
]);

const MANAGER_ONLY_TOOLS = new Set([
  "import_csv_data",
  "list_assignable_users",
  "create_notification",
  "update_timeline_allocation_inline",
  "apply_timeline_project_shift",
  "quick_assign_timeline_resource",
  "batch_quick_assign_timeline_resources",
  "batch_shift_timeline_allocations",
  "create_estimate",
  "clone_estimate",
  "update_estimate_draft",
  "submit_estimate_version",
  "approve_estimate_version",
  "create_estimate_revision",
  "create_estimate_export",
  "create_estimate_planning_handoff",
  "generate_estimate_weekly_phasing",
  "update_estimate_commercial_terms",
  "create_task_for_user",
  "assign_task",
  "send_broadcast",
  "list_broadcasts",
  "get_broadcast_detail",
  "approve_vacation",
  "reject_vacation",
  "get_pending_vacation_approvals",
  "get_entitlement_summary",
  "set_entitlement",
  "create_role",
  "update_role",
  "delete_role",
  "create_client",
  "update_client",
]);

const ADMIN_ONLY_TOOLS = new Set([
  "list_users",
  "get_active_user_count",
  "create_user",
  "set_user_password",
  "update_user_role",
  "update_user_name",
  "link_user_resource",
  "auto_link_users_by_email",
  "set_user_permissions",
  "reset_user_permissions",
  "get_effective_user_permissions",
  "disable_user_totp",
  "list_dispo_import_batches",
  "get_dispo_import_batch",
  "stage_dispo_import_batch",
  "validate_dispo_import_batch",
  "cancel_dispo_import_batch",
  "list_dispo_staged_resources",
  "list_dispo_staged_projects",
  "list_dispo_staged_assignments",
  "list_dispo_staged_vacations",
  "list_dispo_staged_unresolved_records",
  "resolve_dispo_staged_record",
  "commit_dispo_import_batch",
  "get_system_settings",
  "update_system_settings",
  "clear_stored_runtime_secrets",
  "get_ai_configured",
  "test_ai_connection",
  "test_smtp_connection",
  "test_gemini_connection",
  "list_system_role_configs",
  "update_system_role_config",
  "list_webhooks",
  "get_webhook",
  "create_webhook",
  "update_webhook",
  "delete_webhook",
  "test_webhook",
  "create_org_unit",
  "update_org_unit",
  "create_country",
  "update_country",
  "create_metro_city",
  "update_metro_city",
  "delete_metro_city",
  "list_holiday_calendars",
  "get_holiday_calendar",
  "create_holiday_calendar",
  "update_holiday_calendar",
  "delete_holiday_calendar",
  "create_holiday_calendar_entry",
  "update_holiday_calendar_entry",
  "delete_holiday_calendar_entry",
]);

function hasLegacyToolAccess(
  toolName: string,
  permissions: Set<PermissionKey>,
  userRole: string,
  hasResourceOverviewAccess: boolean,
  hasControllerAccess: boolean,
  hasManagerAccess: boolean,
) {
  const requiredPerm = TOOL_PERMISSION_MAP[toolName];

  if (requiredPerm && !permissions.has(requiredPerm as PermissionKey)) {
    return false;
  }
  if (ADMIN_ONLY_TOOLS.has(toolName) && userRole !== SystemRole.ADMIN) {
    return false;
  }
  if (MANAGER_ONLY_TOOLS.has(toolName) && !hasManagerAccess) {
    return false;
  }
  if (RESOURCE_OVERVIEW_TOOLS.has(toolName) && !hasResourceOverviewAccess) {
    return false;
  }
  if (CONTROLLER_ONLY_TOOLS.has(toolName) && !hasControllerAccess) {
    return false;
  }
  if (PLANNING_READ_TOOLS.has(toolName) && !permissions.has(PermissionKey.VIEW_PLANNING)) {
    return false;
  }
  if (COST_TOOLS.has(toolName) && !permissions.has(PermissionKey.VIEW_COSTS)) {
    return false;
  }
  if (ADVANCED_ASSISTANT_TOOLS.has(toolName) && !permissions.has(PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS)) {
    return false;
  }

  return true;
}

function hasToolAccess(
  tool: ToolDef,
  permissions: Set<PermissionKey>,
  userRole: string,
  hasResourceOverviewAccess: boolean,
): boolean {
  if (!tool.access) {
    const hasControllerAccess = userRole === SystemRole.ADMIN
      || userRole === SystemRole.MANAGER
      || userRole === SystemRole.CONTROLLER;
    const hasManagerAccess = userRole === SystemRole.ADMIN
      || userRole === SystemRole.MANAGER;

    return hasLegacyToolAccess(
      tool.function.name,
      permissions,
      userRole,
      hasResourceOverviewAccess,
      hasControllerAccess,
      hasManagerAccess,
    );
  }

  if (tool.access.requiredPermissions?.some((permission) => !permissions.has(permission))) {
    return false;
  }
  if (tool.access.allowedSystemRoles && !tool.access.allowedSystemRoles.includes(userRole as SystemRole)) {
    return false;
  }
  if (tool.access.requiresResourceOverview && !hasResourceOverviewAccess) {
    return false;
  }
  if (tool.access.requiresPlanningRead && !permissions.has(PermissionKey.VIEW_PLANNING)) {
    return false;
  }
  if (tool.access.requiresCostView && !permissions.has(PermissionKey.VIEW_COSTS)) {
    return false;
  }
  if (tool.access.requiresAdvancedAssistant && !permissions.has(PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS)) {
    return false;
  }

  return true;
}

export function getAvailableAssistantTools(
  permissions: Set<PermissionKey>,
  userRole: string,
): ToolDef[] {
  const hasResourceOverviewAccess = permissions.has(PermissionKey.VIEW_ALL_RESOURCES)
    || permissions.has(PermissionKey.MANAGE_RESOURCES);

  return TOOL_DEFINITIONS.filter((tool) => (
    hasToolAccess(tool, permissions, userRole, hasResourceOverviewAccess)
  ));
}
