from flask_wtf import FlaskForm
from wtforms import (
    StringField,
    SelectField,
    DateField,
    SubmitField
)
from wtforms.validators import (
    DataRequired,
    Length,
    ValidationError
)

def validate_tooling_id_format(form, field):
    """Custom validator to ensure tooling_id is exactly 5 digits"""
    if not field.data.isdigit() or len(field.data) != 5:
        raise ValidationError('Tooling ID must be exactly 5 digits')

class QuotationForm(FlaskForm):
    # Factory Information
    mold_shop_name = StringField('Mold Shop Name', validators=[DataRequired()])
    mold_shop_country = SelectField('Mold Shop Country', validators=[DataRequired()], choices=[
        ('', 'Select Country'),
        ('China', 'China'),
        ('Vietnam', 'Vietnam'),
        ('Indonesia', 'Indonesia')
    ])
    t1_shoe_factory_name = StringField('T1 Shoe Factory Name', validators=[DataRequired()])
    t1_shoe_factory_country = SelectField('T1 Shoe Factory Country', validators=[DataRequired()], choices=[
        ('', 'Select Country'),
        ('China', 'China'),
        ('Vietnam', 'Vietnam'),
        ('Indonesia', 'Indonesia')
    ])
    t2_component_factory_name = StringField('T2 Component Factory Name', validators=[DataRequired()])
    t2_component_factory_country = SelectField('T2 Component Factory Country', validators=[DataRequired()], choices=[
        ('', 'Select Country'),
        ('China', 'China'),
        ('Vietnam', 'Vietnam'),
        ('Indonesia', 'Indonesia')
    ])
    
    # Mold Information
    model_name = StringField('Model Name', validators=[DataRequired()])
    tooling_id = StringField('Tooling ID', validators=[DataRequired(), Length(min=5, max=5), validate_tooling_id_format], id='tooling_id')
    season = StringField('Season', validators=[DataRequired()])
    
    # Define stage-type mapping
    STAGE_TYPE_MAPPING = {
        'CR0': ['Sample'],
        'CR1': ['Sample'],
        'CR2': ['Sample'],
        'SMS': ['A Set'],
        'commercialization': ['A Set'],
        'production': ['Additional']
    }
    
    # Define the mapping of main types to sub-types
    MOLD_TYPE_MAPPING = {
        'Rubber': ['Flat Outsole', 'Cupsole', 'Rubber Sole'],
        'CMEVA': ['2 Plates Mold', '3 Plates Mold', '2 Plates with in-mold channel', 'Breathable + in-mold channel'],
        'IMEVA': ['2 Plates Mold', '3 Plates Mold'],
        'Sandal': ['Sandal with Upper Bandage', '2 Plate without Upper Bandage'],
        'Co-shot mold': ['Co-shot mold', 'Foaming mold'],
        'PU': ['2 Plates Mold', '3 Plates Mold']
    }
    
    # Define the mapping of sub-types to their specific options
    MOLD_SPECIFIC_TYPE_OPTIONS = {
        'Flat Outsole': ['Flat', 'Flat with Top/Heel Tip'],
        'Cupsole': ['Top PL', 'Visible PL'],
        'Rubber Sole': ['Top PL', 'Short PL (Heel/Forefoot)', 'Visible PL', 'Wave PL']
    }
    
    mold_main_type = SelectField('Mold Main Type', validators=[DataRequired()], choices=[
        ('', 'Select Main Type'),
        ('Rubber', 'Rubber'),
        ('CMEVA', 'CMEVA'),
        ('IMEVA', 'IMEVA'),
        ('Sandal', 'Sandal'),
        ('Co-shot mold', 'Co-shot mold'),
        ('PU', 'PU')
    ], id='mold_main_type')
    
    mold_sub_type = SelectField('Mold Sub Type', validators=[DataRequired()], choices=[
        ('', 'Select Sub Type')
    ], id='mold_sub_type')
    
    mold_specific_type = SelectField('Mold Specific Type', validators=[], choices=[
        ('', 'Select Specific Type')
    ], id='mold_specific_type', coerce=str, default='')
    
    stage = SelectField('Stage', validators=[DataRequired()], choices=[
        ('', 'Select Stage'),
        ('CR0', 'CR0'),
        ('CR1', 'CR1'),
        ('CR2', 'CR2'),
        ('SMS', 'SMS'),
        ('commercialization', 'Commercialization'),
        ('production', 'Production')
    ], id='stage')
    
    type = SelectField('Type', validators=[DataRequired()], choices=[
        ('', 'Select Type'),
        ('Sample', 'Sample'),
        ('A Set', 'A Set'),
        ('Additional', 'Additional')
    ], id='type')

    # Dates and Approvals
    issue_date = DateField('Issue Date', validators=[DataRequired()])
    approved_by_mold_shop = StringField('Approved by (Mold Shop Representative)', validators=[DataRequired()])
    approved_by_t1_tooling = StringField('Approved by (T1 Tooling Representative)', validators=[DataRequired()])
    approved_by_lo_tooling = StringField('Approved by (LO Tooling)', validators=[DataRequired()])

    # Mold Cost
    sliders_count = SelectField('Number of Sliders', validators=[DataRequired()], choices=[
        ('', 'Select Number of Sliders'),
        ('0', '0'),
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4')
    ])
    cavity_count = SelectField('Number of Cavities', validators=[DataRequired()], choices=[
        ('', 'Select Number of Pairs'),
        ('0.5', '0.5 pair'),
        ('1', '1 pair'),
        ('1.5', '1.5 pair'),
        ('2', '2 pair'),
        ('2.5', '2.5 pair'),
        ('3', '3 pair')
    ])
    digital_texture_type = SelectField('Digital Texture', validators=[DataRequired()], choices=[
        ('', 'Select Texture Type'),
        ('adidas_digital', 'adidas digital texture'),
        ('customized texture', 'customized texture'),
        ('laser', 'laser texture')
    ])
    complexity_high_sidewall = SelectField('High Sidewall >60mm', validators=[DataRequired()], choices=[('no', 'No'), ('yes', 'Yes')])
    submit = SubmitField('Calculate')

    def __init__(self, *args, **kwargs):
        super(QuotationForm, self).__init__(*args, **kwargs)
        # Set initial choices for mold_sub_type based on default mold_main_type
        if self.mold_main_type.data in self.MOLD_TYPE_MAPPING:
            self.mold_sub_type.choices = [('', 'Select Sub Type')] + [(x, x) for x in self.MOLD_TYPE_MAPPING[self.mold_main_type.data]]
    
    def validate_mold_sub_type(self, field):
        main_type = self.mold_main_type.data
        print(f"Validating sub_type: {field.data} for main_type: {main_type}")
        if main_type and main_type in self.MOLD_TYPE_MAPPING:
            valid_sub_types = self.MOLD_TYPE_MAPPING[main_type]
            print(f"Valid sub_types for {main_type}: {valid_sub_types}")
            if field.data not in valid_sub_types and field.data != '':
                print(f"Invalid sub_type: {field.data}. Valid types: {valid_sub_types}")
                raise ValidationError('Invalid sub-type for selected main type')
    
    def validate_mold_specific_type(self, field):
        """Validate that the selected specific type is valid for the selected sub type."""
        sub_type = self.mold_sub_type.data
        if not sub_type:
            field.data = ''
            return

        # Get valid specific types for the selected sub type
        valid_specific_types = self.MOLD_SPECIFIC_TYPE_OPTIONS.get(sub_type, [])

        # If there are no specific types for this sub-type, the field should be empty
        if not valid_specific_types:
            field.data = ''  # Always clear the field if it shouldn't have a value
            return

        # If there are specific types, validate the selection
        if field.data is None or field.data == '':
            raise ValidationError(f'Specific type is required for {sub_type}')
        if field.data not in valid_specific_types:
            raise ValidationError(f'Invalid specific type for {sub_type}. Valid options are: {", ".join(valid_specific_types)}')
    
    def validate_type(self, field):
        stage = self.stage.data
        print(f"Validating type: {field.data} for stage: {stage}")
        if stage and stage in self.STAGE_TYPE_MAPPING:
            valid_types = self.STAGE_TYPE_MAPPING[stage]
            print(f"Valid types for {stage}: {valid_types}")
            if field.data not in valid_types and field.data != '':
                print(f"Invalid type: {field.data}")
                raise ValidationError(f'Invalid type for {stage} stage. Allowed types: {", ".join(valid_types)}')
        elif field.data != '':
            raise ValidationError('Please select a stage first')
    
    def validate_tooling_id(self, field):
        validate_tooling_id_format(self, field) 