"""
Forms for LabRat setup:
- Database configuration
- Device configuration
- Sensor configuration
"""

import os
from flask_wtf import FlaskForm
from wtforms import (
    StringField,
    IntegerField,
    SelectField,
    FieldList,
    FormField,
    SubmitField,
)
from wtforms.validators import DataRequired, ValidationError, NumberRange
from wtforms.form import Form


# ==========================================================
# DATABASE SETUP FORM
# ==========================================================


class LabRatSetUpForm(FlaskForm):
    """
    Form to configure SQLite database.
    """

    file_path = StringField(
        "SQLite Database File Path (including filename)",
        validators=[DataRequired()],
    )

    submit = SubmitField("Create / Connect Database")

    def validate_file_path(self, field):
        """
        Validate path ends in .db and ensure directory exists.
        """
        path = field.data.strip()

        if not path.endswith(".db"):
            raise ValidationError("Database file must end with .db")

        directory = os.path.dirname(path)

        if directory and not os.path.exists(directory):
            try:
                os.makedirs(directory)
            except OSError:
                raise ValidationError("Unable to create directory.")


# ==========================================================
# SENSOR FORM (SUBFORM)
# ==========================================================


class SensorForm(Form):
    """
    Subform for a single sensor.
    """

    sens_name = StringField("Sensor Name", validators=[DataRequired()])
    measures = StringField("Measures", validators=[DataRequired()])
    returns = StringField("Returns", validators=[DataRequired()])
    calib = StringField("Calibration", validators=[DataRequired()])
    range = StringField("Range", validators=[DataRequired()])
    info = StringField("Info", validators=[DataRequired()])
    comments = StringField("Comments", validators=[DataRequired()])


# ==========================================================
# DEVICE FORM (SUBFORM)
# ==========================================================


class DeviceForm(Form):
    """
    Subform for a single device, including sensors.
    """

    device_name = StringField("Device Name", validators=[DataRequired()])
    device_guid = StringField("Device GUID")

    num_sensors = IntegerField(
        "Number of Sensors", default=0, validators=[NumberRange(min=0)]
    )

    device_info = StringField("Device Info", validators=[DataRequired()])
    device_type = StringField("Device Type", validators=[DataRequired()])
    device_location = StringField("Device Location", validators=[DataRequired()])

    device_active = IntegerField(
        "Device Active (0 or 1)",
        validators=[DataRequired(), NumberRange(min=0, max=1)],
    )

    connection = SelectField(
        "Connection",
        choices=[
            ("", "--Select Connection--"),
            ("Serial", "Serial"),
            ("MQTT", "MQTT"),
            ("http", "HTTP"),
            ("Other", "Other"),
        ],
        validators=[DataRequired()],
    )

    # IMPORTANT:
    # min_entries=0 so no sensor shows unless added dynamically
    sensors = FieldList(FormField(SensorForm), min_entries=0)


# ==========================================================
# MAIN DEVICE SETUP FORM
# ==========================================================


class DeviceSetupForm(FlaskForm):
    """
    Main form containing multiple devices.
    """

    # At least one device should render
    devices = FieldList(FormField(DeviceForm), min_entries=1)

    submit = SubmitField("Save Devices")
