from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, SelectMultipleField, BooleanField, TextAreaField, HiddenField, IntegerField
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError, Optional
from flask_wtf.file import FileField
from ..models import User

class AddUserForm(FlaskForm):
    username = StringField('Nombre de usuario', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Contraseña', validators=[DataRequired()])
    confirm_password = PasswordField('Confirmar Contraseña', validators=[DataRequired(), EqualTo('password')])
    roles = SelectMultipleField('Roles', coerce=int, validators=[DataRequired()])
    submit = SubmitField('Crear Usuario')

    def validate_username(self, username):
        user = User.query.filter_by(username=username.data).first()
        if user:
            raise ValidationError('Ese nombre de usuario ya está en uso. Por favor, elige otro.')

    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user:
            raise ValidationError('Esa dirección de email ya está en uso. Por favor, elige otra.')

class EditUserForm(FlaskForm):
    username = StringField('Nombre de usuario', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Contraseña', validators=[Optional()])
    confirm_password = PasswordField('Confirmar Contraseña', validators=[EqualTo('password')])
    roles = SelectMultipleField('Roles', coerce=int, validators=[DataRequired()])
    is_active = BooleanField('Usuario Activo')
    submit = SubmitField('Actualizar Usuario')

    def __init__(self, *args, **kwargs):
        super(EditUserForm, self).__init__(*args, **kwargs)
        self.original_username = kwargs.get('obj', None)
        self.original_email = kwargs.get('obj', None)

    def validate_username(self, username):
        if self.original_username and self.original_username.username == username.data:
            return
        user = User.query.filter_by(username=username.data).first()
        if user:
            raise ValidationError('Ese nombre de usuario ya está en uso. Por favor, elige otro.')

    def validate_email(self, email):
        if self.original_email and self.original_email.email == email.data:
            return
        user = User.query.filter_by(email=email.data).first()
        if user:
            raise ValidationError('Esa dirección de email ya está en uso. Por favor, elige otra.')


class ArticleForm(FlaskForm):
    """Formulario para crear/editar artículos del blog con protección CSRF."""
    title = StringField('Título', validators=[DataRequired()])
    slug = StringField('Slug', validators=[Optional()])
    summary = StringField('Resumen', validators=[DataRequired()])
    content = TextAreaField('Contenido', validators=[DataRequired()])
    featured_image = FileField('Imagen destacada')
    is_published = BooleanField('Publicar', default=False)
    remove_image = BooleanField('Eliminar imagen')
    existing_featured_image = HiddenField()
    submit = SubmitField('Guardar')


class EmptyForm(FlaskForm):
    """Formulario vacío para protección CSRF."""
    pass


class RateLimitSettingsForm(FlaskForm):
    """Formulario para configurar límites de tasa y whitelist de IPs."""
    login_limit = StringField('Límite Login', validators=[DataRequired()])
    register_limit = StringField('Límite Registro', validators=[DataRequired()])
    reset_request_limit = StringField('Límite Solicitud Reset', validators=[DataRequired()])
    reset_limit = StringField('Límite Reset', validators=[DataRequired()])
    whitelist = TextAreaField('Whitelist de IPs/CIDR (una por línea)', validators=[Optional()])
    strict_minutes = IntegerField('Minutos de modo estricto', default=60, validators=[Optional()])
    submit = SubmitField('Guardar Cambios')
    activate_strict = SubmitField('Activar Modo Estricto')
    deactivate_strict = SubmitField('Desactivar Modo Estricto')
