from flask_wtf import FlaskForm
from wtforms import (StringField, PasswordField, BooleanField, SubmitField, FileField, SelectField,
                     IntegerField, DecimalField, TextAreaField, FloatField, DateTimeField)
from wtforms.validators import DataRequired, ValidationError, Email, EqualTo, Length, NumberRange
from wtforms_sqlalchemy.fields import QuerySelectField, QuerySelectMultipleField
from app.models import User, Role

def user_choices():
    return User.query.all()

def role_choices():
    return Role.query.all()

class RoleAssignForm(FlaskForm):
    user = QuerySelectField(query_factory=user_choices, get_label='email', allow_blank=True)
    role = QuerySelectField(query_factory=role_choices, get_label='name', allow_blank=True)
    submit = SubmitField('Assign Role')


class RegistrationForm(FlaskForm):
    first_name = StringField('First Name', validators=[DataRequired()])
    last_name = StringField('Last Name', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    company_name = StringField('Company Name', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')])
    street_address = StringField('Street Address', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    state = StringField('State', validators=[DataRequired()])
    phone_number = StringField('Phone Number', validators=[DataRequired()])
    location = SelectField('Location',
                           choices=[('United States', 'United States'), ('United Kingdom', 'United Kingdom'),
                                    ('India', 'India'), ('Canada', 'Canada')])
    currency = SelectField('Currency',
                           choices=[('USD', 'US Dollar ($)'), ('GBP', 'United Kingdom (Pound)'), ('INR', 'India (INR)'),
                                    ('CAD', 'CA Dollar ($)')])
    profile_picture = FileField('Profile Picture')
    submit = SubmitField('Register')

    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError('Please use a different email address.')


class LoginForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField('Sign In')


class ProfileForm(FlaskForm):
    first_name = StringField('First Name', validators=[DataRequired()])
    last_name = StringField('Last Name', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    company_name = StringField('Company Name', validators=[DataRequired()])
    street_address = StringField('Street Address', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    state = StringField('State', validators=[DataRequired()])
    phone_number = StringField('Phone Number', validators=[DataRequired()])
    location = SelectField('Location', choices=[('United States', 'United States'), ('United Kingdom', 'United Kingdom'), ('India', 'India'), ('Canada', 'Canada')])
    currency = SelectField('Currency', choices=[('USD', 'US Dollar ($)'), ('GBP', 'United Kingdom (Pound)'), ('INR', 'India (INR)'), ('CAD', 'CA Dollar ($)')])
    submit = SubmitField('Save')

class ChangePasswordForm(FlaskForm):
    current_password = PasswordField('Current Password', validators=[DataRequired()])
    new_password = PasswordField('New Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('new_password')])
    submit = SubmitField('Change Password')

class NotificationForm(FlaskForm):
    notification_email = StringField('Email Address', validators=[DataRequired(), Email()])
    newsletter_notifications = BooleanField('Our newsletter')
    invoice_notifications = BooleanField('Invoices')
    delivery_notifications = BooleanField('Order Delivered')
    email_notifications = BooleanField('Email Notification')
    submit = SubmitField('Save')

class BillingInfoForm(FlaskForm):
    business_name = StringField('Business Name', validators=[DataRequired()])
    business_address = StringField('Business Address', validators=[DataRequired()])
    first_name = StringField('First Name', validators=[DataRequired()])
    last_name = StringField('Last Name', validators=[DataRequired()])
    business_sector = StringField('Business Sector', validators=[DataRequired()])
    country = StringField('Country', validators=[DataRequired()])
    submit = SubmitField('Save')


class EmptyForm(FlaskForm):
    submit = SubmitField('Submit')

class EditUserForm(FlaskForm):
    first_name = StringField('First Name', validators=[DataRequired(), Length(max=64)])
    last_name = StringField('Last Name', validators=[DataRequired(), Length(max=64)])
    email = StringField('Email', validators=[DataRequired(), Email(), Length(max=120)])
    company_name = StringField('Company Name', validators=[Length(max=120)])
    roles = QuerySelectMultipleField('Roles', query_factory=lambda: Role.query.all(), get_label='name')
    is_active = BooleanField('Active')
    submit = SubmitField('Save Changes')

class EditPlanForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired(), Length(max=50)])
    description = TextAreaField('Description')
    cost = FloatField('Cost', validators=[NumberRange(min=0)])
    usage_limit = IntegerField('Usage Limit', validators=[DataRequired()])
    company_id = SelectField('Company', coerce=int)
    submit = SubmitField('Save Changes')

class AddCompanyForm(FlaskForm):
    name = StringField('Company Name', validators=[DataRequired()])
    street_address = StringField('Street Address', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    state = StringField('State', validators=[DataRequired()])
    zip_code = StringField('Zip Code', validators=[DataRequired()])
    country = StringField('Country', validators=[DataRequired()])
    submit = SubmitField('Add Company')

class UpdateCompanyAddressForm(FlaskForm):
    name = StringField('Company Name', validators=[DataRequired()])
    street_address = StringField('Street Address', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    state = StringField('State', validators=[DataRequired()])
    zip_code = StringField('Zip Code', validators=[DataRequired()])
    country = StringField('Country', validators=[DataRequired()])
    submit = SubmitField('Update Address')