import { AuthConfig } from "../config/auth.config";
import { hashPassword, verifyPassword } from "../utils/password.utils";
import { validateEmail, validatePassword } from "../utils/validation.utils";
import { storeOtp, generateOtp } from "../services/email/otpStore.service";

// Signup Handler Function
export const signupHandler = async (
  email: string,
  password: string,
  name: string,
  config: AuthConfig
): Promise<{ status: number; message: string; user?: any }> => {
  try {
    // Validation for email, password, and check if the user already exists
    if (!validateEmail(email)) {
      return { status: 400, message: "Invalid email format" };
    }
    if (!validatePassword(password)) {
      return { status: 400, message: "Invalid password format" };
    }
    if (await config.checkUserExist?.(email)) {
      return { status: 409, message: "Email already exists" };
    }

    // Generation of secureKey, password hashing
    const secureKey = config.generateSecureKey
      ? config.generateSecureKey()
      : "defaultKey";
    const hashedPassword = await hashPassword(
      password,
      secureKey,
      config.hashAlgorithm ?? "crypto"
    );

    // Create a user
    const user = await config.createUser?.({
      email,
      name,
    });

    // Create an auth record for the user
    if (user) {
      await config.createAuthRecord?.({
        userId: user.id,
        password: hashedPassword,
        secureKey,
        ipAddress: "0.0.0.0",
        lastLogin: new Date(),
      });

      return { status: 201, message: "User created successfully" };
    } else {
      return { status: 500, message: "User creation failed" };
    }
  } catch (err: any) {
    console.error(err);
    return { status: 500, message: err.message };
  }
};

// Login Handler Function
export const loginHandler = async (
  email: string,
  password: string,
  config: AuthConfig
): Promise<{ status: number; message: string; user?: any }> => {
  try {
    // Check if the user and auth record are present
    const user = await config.getUserByEmail?.(email);
    if (!user) {
      return { status: 401, message: "Invalid email or password" };
    }

    const authRecord = await config.getAuthRecord?.(user.id);
    if (!authRecord) {
      return { status: 401, message: "authRecord not found" };
    }

    // Check if the password is valid
    const isPasswordValid = await verifyPassword(
      password,
      authRecord.secureKey,
      authRecord.password,
      config.hashAlgorithm ?? "crypto"
    );

    if (!isPasswordValid) {
      return { status: 401, message: "password is incorrect" };
    }

    // Generate OTP after successful password validation
    const otp = generateOtp();
    storeOtp(email, otp);

    // Send OTP to user via email (use config.sendEmail or your own email service)
    await config.sendEmail?.(
      email,
      "Your OTP for login",
      `Your OTP is: ${otp}`
    );

    return { status: 200, message: `OTP is sent to your ${email}` };
  } catch (err: any) {
    console.error(err);
    return { status: 500, message: err.message };
  }
};
