import * as v from 'valibot';
import { isValidPhoneNumber } from './phoneUtils';

// Common validation schemas
export const fullNameSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Please enter your full name'),
    v.trim(),
    v.minLength(1, 'Full name cannot be empty')
);

export const emailSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Please enter your email address'),
    v.email('Please enter a valid email address'),
    v.trim()
);

export const phoneNumberSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Please enter a phone number'),
    v.trim(),
    v.custom((value) => {
        if (typeof value !== 'string') return false;
        const cleanPhone = value.replace(/[^+\d]/g, '');
        if (cleanPhone.length < 7) {
            return false;
        }
        // Use the existing phone validation utility
        return isValidPhoneNumber(value);
    }, 'Please enter a valid phone number')
);

export const pinSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Please enter a PIN'),
    v.length(6, 'PIN must be exactly 6 digits'),
    v.regex(/^\d{6}$/, 'PIN must contain only digits')
);

export const confirmPinSchema = (pin: string) => v.pipe(
    v.string(),
    v.minLength(1, 'Please confirm your PIN'),
    v.custom((value) => {
        return typeof value === 'string' && value === pin;
    }, 'PIN and confirm PIN do not match')
);

export const addressSchema = v.optional(
    v.pipe(
        v.string(),
        v.trim()
    )
);

export const cardNumberSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Card number is required'),
    v.trim(),
    v.custom((value) => {
        if (typeof value !== 'string') return false;
        const cleanNumber = value.replace(/\s/g, '');
        // Basic card number validation (13-19 digits)
        return /^\d{13,19}$/.test(cleanNumber);
    }, 'Please enter a valid card number')
);

export const expiryDateSchema = v.pipe(
    v.string(),
    v.minLength(1, 'Expiry date is required'),
    v.trim(),
    v.custom((value) => {
        if (typeof value !== 'string') return false;
        // Validate MM/YY format
        if (!/^\d{2}\/\d{2}$/.test(value)) {
            return false;
        }
        const [month, year] = value.split('/');
        const monthNum = parseInt(month, 10);
        const yearNum = parseInt(year, 10);

        if (monthNum < 1 || monthNum > 12) {
            return false;
        }

        // Check if card is expired (basic check - assumes 20XX)
        const currentYear = new Date().getFullYear() % 100;
        const currentMonth = new Date().getMonth() + 1;

        if (yearNum < currentYear || (yearNum === currentYear && monthNum < currentMonth)) {
            return false;
        }

        return true;
    }, 'Please enter a valid expiry date')
);

export const cvvSchema = v.pipe(
    v.string(),
    v.minLength(1, 'CVV is required'),
    v.trim(),
    v.regex(/^\d{3,4}$/, 'CVV must be 3 or 4 digits')
);

// Amount validation schemas
export const amountSchema = (options?: {
    min?: number; // in cents
    max?: number; // in cents
    minDisplay?: string; // for error messages
    maxDisplay?: string; // for error messages
}) => {
    const min = options?.min ?? 1; // Default 1 cent
    const max = options?.max ?? 99999; // Default $999.99
    const minDisplay = options?.minDisplay ?? '$0.01';
    const maxDisplay = options?.maxDisplay ?? '$999.99';

    return v.pipe(
        v.string(),
        v.custom((value) => {
            if (typeof value !== 'string') return false;
            return !(!value || value === '' || value === '0' || value === '0.' || value === '0.00');
        }, 'Please enter an amount'),
        v.custom((value) => {
            if (typeof value !== 'string') return false;
            // Parse amount to cents
            const numValue = parseFloat(value);
            if (isNaN(numValue)) {
                return false;
            }
            const amountInCents = Math.round(numValue * 100);

            return amountInCents >= min && amountInCents <= max;
        }, `Amount must be between ${minDisplay} and ${maxDisplay}`)
    );
};

// Form schemas
export const phoneSetupSchema = v.object({
    fullName: fullNameSchema,
    email: emailSchema,
    address: addressSchema,
    pin: pinSchema,
    confirmPin: v.string(), // Will be validated separately with confirmPinSchema
});

export const addRecipientSchema = v.object({
    fullName: fullNameSchema,
    phoneNumber: phoneNumberSchema,
});

export const addCardSchema = v.object({
    cardNumber: cardNumberSchema,
    expiryDate: expiryDateSchema,
    cvv: cvvSchema,
});

export const profileUpdateSchema = v.object({
    fullName: fullNameSchema,
    phoneNumber: v.optional(phoneNumberSchema),
    email: v.optional(emailSchema),
    address: addressSchema,
});

// Helper function to get validation errors
export const getValidationError = (error: v.ValiError<any>): string => {
    if (error.issues && error.issues.length > 0) {
        return error.issues[0].message || 'Validation error';
    }
    return 'Validation error';
};

// Helper function to validate and get errors
export const validate = <T extends v.BaseSchema<any, any, any>>(
    schema: T,
    input: unknown
): { success: true; data: v.InferInput<T> } | { success: false; error: string } => {
    try {
        const data = v.parse(schema, input);
        return { success: true, data };
    } catch (error) {
        if (error instanceof v.ValiError) {
            return { success: false, error: getValidationError(error) };
        }
        return { success: false, error: 'Validation error' };
    }
};

