import { router, protectedProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { TwoFactorAuthService } from "../services/twoFactorAuth.ts";

export const auth2FARouter = router({
  /**
   * Generate 2FA QR code and secret
   */
  generate: protectedProcedure.mutation(async ({ ctx }) => {
    try {
      const { secret, qrCodeUrl, qrCode } = await TwoFactorAuthService.generateSecret(
        ctx.user.id
      );

      return {
        success: true,
        secret,
        qrCode: qrCodeUrl,
        qrCodeData: qrCode,
      };
    } catch (error) {
      console.error("[2FA] Error generating secret:", error);
      throw new Error("Failed to generate 2FA secret");
    }
  }),

  /**
   * Verify 2FA code and enable 2FA
   */
  verify: protectedProcedure
    .input(
      z.object({
        code: z.string().length(6),
        secret: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      try {
        // Verify the code
        const isValid = TwoFactorAuthService.verifyCode(input.secret, input.code);

        if (!isValid) {
          throw new Error("Invalid verification code");
        }

        // Enable 2FA for user
        await TwoFactorAuthService.enable2FA(ctx.user.id, input.secret);

        return {
          success: true,
          message: "2FA enabled successfully",
        };
      } catch (error) {
        console.error("[2FA] Error verifying code:", error);
        throw new Error("Failed to verify 2FA code");
      }
    }),

  /**
   * Check if 2FA is enabled for user
   */
  isEnabled: protectedProcedure.query(async ({ ctx }) => {
    try {
      const enabled = await TwoFactorAuthService.is2FAEnabled(ctx.user.id);
      return { enabled };
    } catch (error) {
      console.error("[2FA] Error checking 2FA status:", error);
      throw new Error("Failed to check 2FA status");
    }
  }),

  /**
   * Disable 2FA for user
   */
  disable: protectedProcedure
    .input(
      z.object({
        code: z.string().length(6),
      })
    )
    .mutation(async ({ ctx, input }) => {
      try {
        // Verify the code before disabling
        const secret = await TwoFactorAuthService.getSecret(ctx.user.id);
        if (!secret) {
          throw new Error("2FA not enabled");
        }

        const isValid = TwoFactorAuthService.verifyCode(secret, input.code);
        if (!isValid) {
          throw new Error("Invalid verification code");
        }

        // Disable 2FA
        await TwoFactorAuthService.disable2FA(ctx.user.id);

        return {
          success: true,
          message: "2FA disabled successfully",
        };
      } catch (error) {
        console.error("[2FA] Error disabling 2FA:", error);
        throw new Error("Failed to disable 2FA");
      }
    }),

  /**
   * Verify 2FA code during login
   */
  verifyLogin: protectedProcedure
    .input(
      z.object({
        code: z.string().length(6),
      })
    )
    .mutation(async ({ ctx, input }) => {
      try {
        const secret = await TwoFactorAuthService.getSecret(ctx.user.id);
        if (!secret) {
          throw new Error("2FA not enabled");
        }

        const isValid = TwoFactorAuthService.verifyCode(secret, input.code);
        if (!isValid) {
          throw new Error("Invalid verification code");
        }

        return {
          success: true,
          message: "2FA verification successful",
        };
      } catch (error) {
        console.error("[2FA] Error verifying login code:", error);
        throw new Error("Failed to verify 2FA code");
      }
    }),
});
