"""
WTForms for user authentication and other forms.
"""
import re
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired
from wtforms import StringField, PasswordField, SubmitField, TextAreaField, FloatField, IntegerField, SelectField
from wtforms.validators import DataRequired, Email, EqualTo, Length, ValidationError, NumberRange, Optional
from app.models import User


def validate_email_format(form, field):
    """Custom email validation using regex pattern."""
    email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if not re.match(email_pattern, field.data):
        raise ValidationError('Please enter a valid email address.')


class LoginForm(FlaskForm):
    """User login form."""
    email = StringField('Email', validators=[
        DataRequired(message='Email is required'),
        validate_email_format
    ])
    password = PasswordField('Password', validators=[
        DataRequired(message='Password is required')
    ])
    submit = SubmitField('Sign In')


class SignupForm(FlaskForm):
    """User signup/registration form."""
    full_name = StringField('Full Name', validators=[
        DataRequired(message='Full name is required'),
        Length(min=4, max=120, message='Full name must be between 4 and 120 characters')
    ])
    email = StringField('Email', validators=[
        DataRequired(message='Email is required'),
        validate_email_format
    ])
    password = PasswordField('Password', validators=[
        DataRequired(message='Password is required'),
        Length(min=8, message='Password must be at least 8 characters')
    ])
    confirm_password = PasswordField('Confirm Password', validators=[
        DataRequired(message='Password confirmation is required'),
        EqualTo('password', message='Passwords must match')
    ])
    submit = SubmitField('Sign Up')

    def validate_email(self, email):
        """Check if email is already registered."""
        user = User.query.filter_by(email=email.data).first()
        if user:
            raise ValidationError('Email already registered. Please log in.')


class ProductForm(FlaskForm):
    """Admin form for adding/editing products."""
    name = StringField('Product Name', validators=[
        DataRequired(message='Product name is required'),
        Length(min=3, max=100, message='Product name must be between 3 and 100 characters')
    ])
    price = FloatField('Price (₦)', validators=[
        DataRequired(message='Price is required'),
        NumberRange(min=0.01, message='Price must be greater than 0')
    ])
    image = FileField('Product Image', validators=[
        FileAllowed(['jpg', 'jpeg', 'png', 'gif', 'webp'], 'Only image files (jpg, jpeg, png, gif, webp) are allowed!')
    ])
    badge = SelectField('Badge', choices=[
        ('', 'None'),
        ('Bestseller', 'Bestseller'),
        ('Popular', 'Popular'),
        ('New', 'New')
    ], validators=[Optional()])
    description = TextAreaField('Description', validators=[
        DataRequired(message='Description is required'),
        Length(min=10, max=500, message='Description must be between 10 and 500 characters')
    ])
    quantity_available = IntegerField('Quantity Available', validators=[
        DataRequired(message='Quantity is required'),
        NumberRange(min=0, message='Quantity cannot be negative')
    ])
    submit = SubmitField('Save Product')


class ProfileForm(FlaskForm):
    """User profile form for updating account information."""
    full_name = StringField('Full Name', validators=[
        DataRequired(message='Full name is required'),
        Length(min=4, max=120, message='Full name must be between 4 and 120 characters')
    ])
    email = StringField('Email', validators=[
        DataRequired(message='Email is required'),
        validate_email_format
    ])
    profile_picture = FileField('Profile Picture', validators=[
        FileAllowed(['jpg', 'jpeg', 'png', 'gif', 'webp'], 'Only image files (jpg, jpeg, png, gif, webp) are allowed!')
    ])
    submit = SubmitField('Update Profile')

    def __init__(self, original_email, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        self.original_email = original_email

    def validate_email(self, email):
        """Check if email is already registered by another user."""
        if email.data != self.original_email:
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email already registered. Please use a different email.')
