import { body, ValidationChain } from 'express-validator';
import { handleValidationErrors, strictBodyValidation, isStrongPassword, isPositiveNumber } from './common';

// createUser validation
export const validateCreateUser: ValidationChain[] = [
    body('name')
        .trim()
        .notEmpty().withMessage('Name is required')
        .isLength({ min: 2, max: 100 }).withMessage('Name must be between 2 and 100 characters'),
    body('email')
        .trim()
        .notEmpty().withMessage('Email is required')
        .isEmail().withMessage('Invalid email format')
        .normalizeEmail(),
    body('password')
        .notEmpty().withMessage('Password is required')
        .custom(isStrongPassword).withMessage('Password must be at least 8 characters long and contain letters and numbers'),
    body('referredBy')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('Referred by must not exceed 100 characters'),
    body('referredCode')
        .optional()
        .trim()
        .isLength({ max: 50 }).withMessage('Referral code must not exceed 50 characters'),
    body('profileImg')
        .optional()
        .trim()
        .isLength({ max: 500 }).withMessage('Profile image URL must not exceed 500 characters'),
    body('accountName')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('Account name must not exceed 100 characters'),
    body('accountNumber')
        .optional()
        .trim()
        .isLength({ max: 50 }).withMessage('Account number must not exceed 50 characters'),
    body('address')
        .optional()
        .trim()
        .isLength({ max: 200 }).withMessage('Address must not exceed 200 characters'),
    body('bsbNumber')
        .optional()
        .trim()
        .isLength({ max: 20 }).withMessage('BSB number must not exceed 20 characters'),
    body('city')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('City must not exceed 100 characters'),
    body('country')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('Country must not exceed 100 characters'),
    body('state')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('State must not exceed 100 characters'),
    body('zipCode')
        .optional()
        .trim()
        .isLength({ max: 20 }).withMessage('Zip code must not exceed 20 characters'),
];

export const createUserValidation = [
    strictBodyValidation(['name', 'email', 'password', 'referredBy', 'referredCode', 'profileImg', 'accountName', 'accountNumber', 'address', 'bsbNumber', 'city', 'country', 'state', 'zipCode']),
    ...validateCreateUser,
    handleValidationErrors
];

// login validation
export const validateLogin: ValidationChain[] = [
    body('email')
        .trim()
        .notEmpty().withMessage('Email is required')
        .isEmail().withMessage('Invalid email format')
        .normalizeEmail(),
    body('password')
        .notEmpty().withMessage('Password is required')
];

export const loginValidation = [
    strictBodyValidation(['email', 'password']),
    ...validateLogin,
    handleValidationErrors
];

// refresh token validation
export const validateRefreshToken: ValidationChain[] = [
    body('refreshToken')
        .notEmpty().withMessage('Refresh token is required')
        .isString().withMessage('Refresh token must be a string')
];

export const refreshTokenValidation = [
    strictBodyValidation(['refreshToken']),
    ...validateRefreshToken,
    handleValidationErrors
];

// logout validation
export const validateLogout: ValidationChain[] = [
    body('refreshToken')
        .optional()
        .isString().withMessage('Refresh token must be a string')
];

export const logoutValidation = [
    strictBodyValidation(['refreshToken']),
    ...validateLogout,
    handleValidationErrors
];

// revoke all tokens validation
export const validateRevokeAllTokens: ValidationChain[] = [
    body('userId')
        .notEmpty().withMessage('User ID is required')
        .isUUID().withMessage('Invalid user ID format')
];

export const revokeAllTokensValidation = [
    strictBodyValidation(['userId']),
    ...validateRevokeAllTokens,
    handleValidationErrors
];

// updateUser validation
export const validateUpdateUser: ValidationChain[] = [
    body('id')
        .notEmpty().withMessage('User ID is required')
        .isUUID().withMessage('Invalid user ID format'),
    body('name')
        .optional()
        .trim()
        .isLength({ min: 2, max: 100 }).withMessage('Name must be between 2 and 100 characters'),
    body('dob')
        .optional()
        .trim()
        .isISO8601().withMessage('Invalid date format for date of birth'),
    body('phone')
        .optional()
        .trim()
        .isLength({ max: 20 }).withMessage('Phone number must not exceed 20 characters'),
    body('accountName')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('Account name must not exceed 100 characters'),
    body('accountNumber')
        .optional()
        .trim()
        .isLength({ max: 50 }).withMessage('Account number must not exceed 50 characters'),
    body('bsbNumber')
        .optional()
        .trim()
        .isLength({ max: 20 }).withMessage('BSB number must not exceed 20 characters'),
    body('address')
        .optional()
        .trim()
        .isLength({ max: 200 }).withMessage('Address must not exceed 200 characters'),
    body('country')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('Country must not exceed 100 characters'),
    body('state')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('State must not exceed 100 characters'),
    body('city')
        .optional()
        .trim()
        .isLength({ max: 100 }).withMessage('City must not exceed 100 characters'),
    body('zipCode')
        .optional()
        .trim()
        .isLength({ max: 20 }).withMessage('Zip code must not exceed 20 characters'),
];

export const updateUserValidation = [
    strictBodyValidation(['id', 'name', 'dob', 'phone', 'accountName', 'accountNumber', 'bsbNumber', 'address', 'country', 'state', 'city', 'zipCode']),
    ...validateUpdateUser,
    handleValidationErrors
];

// depositByUser validation
export const validateDepositByUser: ValidationChain[] = [
    body('depositAmount')
        .notEmpty().withMessage('Deposit amount is required')
        .custom(isPositiveNumber).withMessage('Deposit amount must be a positive number'),
    body('userId')
        .notEmpty().withMessage('User ID is required')
        .isUUID().withMessage('Invalid user ID format')
];

export const depositByUserValidation = [
    strictBodyValidation(['depositAmount', 'userId']),
    ...validateDepositByUser,
    handleValidationErrors
];

// withdrawByUser validation
export const validateWithdrawByUser: ValidationChain[] = [
    body('withdrawAmount')
        .notEmpty().withMessage('Withdraw amount is required')
        .custom(isPositiveNumber).withMessage('Withdraw amount must be a positive number'),
    body('userId')
        .notEmpty().withMessage('User ID is required')
        .isUUID().withMessage('Invalid user ID format')
];

export const withdrawByUserValidation = [
    strictBodyValidation(['withdrawAmount', 'userId']),
    ...validateWithdrawByUser,
    handleValidationErrors
];

// forgotPassword validation
export const validateForgotPassword: ValidationChain[] = [
    body('email')
        .trim()
        .notEmpty().withMessage('Email is required')
        .isEmail().withMessage('Invalid email format')
        .normalizeEmail()
];

export const forgotPasswordValidation = [
    strictBodyValidation(['email']),
    ...validateForgotPassword,
    handleValidationErrors
];

// verifyOTP validation
export const validateVerifyOTP: ValidationChain[] = [
    body('email')
        .trim()
        .notEmpty().withMessage('Email is required')
        .isEmail().withMessage('Invalid email format')
        .normalizeEmail(),
    body('otp')
        .notEmpty().withMessage('OTP is required')
        .isString().withMessage('OTP must be a string')
        .isLength({ min: 6, max: 6 }).withMessage('OTP must be exactly 6 characters')
        .matches(/^\d+$/).withMessage('OTP must contain only digits')
];

export const verifyOTPValidation = [
    strictBodyValidation(['email', 'otp']),
    ...validateVerifyOTP,
    handleValidationErrors
];

// changePassword validation
export const validateChangePassword: ValidationChain[] = [
    body('email')
        .trim()
        .notEmpty().withMessage('Email is required')
        .isEmail().withMessage('Invalid email format')
        .normalizeEmail(),
    body('password')
        .notEmpty().withMessage('Password is required')
        .custom(isStrongPassword).withMessage('Password must be at least 8 characters long and contain letters and numbers')
];

export const changePasswordValidation = [
    strictBodyValidation(['email', 'password']),
    ...validateChangePassword,
    handleValidationErrors
];
