import { adminProcedure, createTRPCRouter, managerProcedure, protectedProcedure, publicProcedure } from "../trpc.js";
import {
  autoLinkUsersByEmail,
  countActiveUsers,
  CreateUserInputSchema,
  createUser,
  deactivateUser,
  reactivateUser,
  deleteUser,
  disableTotp,
  getEffectiveUserPermissions,
  LinkUserResourceInputSchema,
  linkUserResource,
  listAssignableUsers,
  listUsers,
  SetUserPasswordInputSchema,
  setUserPassword,
  SetUserPermissionsInputSchema,
  setUserPermissions,
  UpdateUserNameInputSchema,
  updateUserName,
  UpdateUserRoleInputSchema,
  updateUserRole,
  UserIdInputSchema,
  resetUserPermissions,
} from "./user-procedure-support.js";
import {
  generateTotpSecret,
  getColumnPreferences,
  getCurrentMfaStatus,
  getCurrentUserProfile,
  getDashboardLayout,
  getFavoriteProjectIds,
  SaveDashboardLayoutInputSchema,
  saveDashboardLayout,
  SetColumnPreferencesInputSchema,
  setColumnPreferences,
  ToggleFavoriteProjectInputSchema,
  toggleFavoriteProject,
  verifyAndEnableTotp as verifyAndEnableTotpSelfService,
  VerifyAndEnableTotpInputSchema,
  verifyTotp,
  VerifyTotpInputSchema,
} from "./user-self-service-procedure-support.js";

export const userRouter = createTRPCRouter({
  /** Lightweight user list for task assignment (ADMIN + MANAGER) */
  listAssignable: managerProcedure.query(({ ctx }) => listAssignableUsers(ctx)),

  list: adminProcedure.query(({ ctx }) => listUsers(ctx)),

  /** Count of users active in the last 5 minutes */
  activeCount: adminProcedure.query(({ ctx }) => countActiveUsers(ctx)),

  me: protectedProcedure.query(({ ctx }) => getCurrentUserProfile(ctx)),

  create: adminProcedure
    .input(CreateUserInputSchema)
    .mutation(({ ctx, input }) => createUser(ctx, input)),

  setPassword: adminProcedure
    .input(SetUserPasswordInputSchema)
    .mutation(({ ctx, input }) => setUserPassword(ctx, input)),

  updateRole: adminProcedure
    .input(UpdateUserRoleInputSchema)
    .mutation(({ ctx, input }) => updateUserRole(ctx, input)),

  updateName: adminProcedure
    .input(UpdateUserNameInputSchema)
    .mutation(({ ctx, input }) => updateUserName(ctx, input)),

  // ─── Resource Linking ──────────────────────────────────────────────────

  linkResource: adminProcedure
    .input(LinkUserResourceInputSchema)
    .mutation(({ ctx, input }) => linkUserResource(ctx, input)),

  autoLinkAllByEmail: adminProcedure.mutation(({ ctx }) => autoLinkUsersByEmail(ctx)),

  getDashboardLayout: protectedProcedure.query(({ ctx }) => getDashboardLayout(ctx)),

  saveDashboardLayout: protectedProcedure
    .input(SaveDashboardLayoutInputSchema)
    .mutation(({ ctx, input }) => saveDashboardLayout(ctx, input)),

  // ─── Favorite Projects ──────────────────────────────────────────────────
  getFavoriteProjectIds: protectedProcedure.query(({ ctx }) => getFavoriteProjectIds(ctx)),

  toggleFavoriteProject: protectedProcedure
    .input(ToggleFavoriteProjectInputSchema)
    .mutation(({ ctx, input }) => toggleFavoriteProject(ctx, input)),

  setPermissions: adminProcedure
    .input(SetUserPermissionsInputSchema)
    .mutation(({ ctx, input }) => setUserPermissions(ctx, input)),

  resetPermissions: adminProcedure
    .input(UserIdInputSchema)
    .mutation(({ ctx, input }) => resetUserPermissions(ctx, input)),

  getColumnPreferences: protectedProcedure.query(({ ctx }) => getColumnPreferences(ctx)),

  setColumnPreferences: protectedProcedure
    .input(SetColumnPreferencesInputSchema)
    .mutation(({ ctx, input }) => setColumnPreferences(ctx, input)),

  getEffectivePermissions: adminProcedure
    .input(UserIdInputSchema)
    .query(({ ctx, input }) => getEffectiveUserPermissions(ctx, input)),

  // ─── TOTP / MFA ─────────────────────────────────────────────────────────────

  /** Generate a new TOTP secret for the current user (not yet enabled). */
  generateTotpSecret: protectedProcedure.mutation(({ ctx }) => generateTotpSecret(ctx)),

  /** Verify a TOTP token and enable MFA for the current user. */
  verifyAndEnableTotp: protectedProcedure
    .input(VerifyAndEnableTotpInputSchema)
    .mutation(({ ctx, input }) => verifyAndEnableTotpSelfService(ctx, input)),

  deactivate: adminProcedure
    .input(UserIdInputSchema)
    .mutation(({ ctx, input }) => deactivateUser(ctx, input)),

  reactivate: adminProcedure
    .input(UserIdInputSchema)
    .mutation(({ ctx, input }) => reactivateUser(ctx, input)),

  delete: adminProcedure
    .input(UserIdInputSchema)
    .mutation(({ ctx, input }) => deleteUser(ctx, input)),

  /** Admin override: disable TOTP for a specific user. */
  disableTotp: adminProcedure
    .input(UserIdInputSchema)
    .mutation(({ ctx, input }) => disableTotp(ctx, input)),

  /** Verify a TOTP token (used during the login flow — public procedure). */
  verifyTotp: publicProcedure
    .input(VerifyTotpInputSchema)
    .mutation(({ ctx, input }) => verifyTotp(ctx, input)),

  /** Get MFA status for the current user. */
  getMfaStatus: protectedProcedure.query(({ ctx }) => getCurrentMfaStatus(ctx)),
});
