"""Route to set up a inator and sensors"""

import json

from flask import (
    Blueprint,
    current_app,
    render_template,
    flash,
    redirect,
    url_for,
)

from src.in_io import sqlite as pysql
from src.http.forms.setup_form import LabRatSetUpForm, DeviceSetupForm
from src.http.services.device_service import validate_devices, save_devices_to_db

setup_bp = Blueprint("setup", __name__)


def _parse_sensor_entry(sensor_entry):
    return {
        "sens_name": sensor_entry.sens_name.data,
        "measures": sensor_entry.measures.data,
        "returns": sensor_entry.returns.data,
        "calib": sensor_entry.calib.data,
        "range": sensor_entry.range.data,
        "info": sensor_entry.info.data,
        "comments": sensor_entry.comments.data,
    }


def _parse_device_form(device_form):
    devices = []
    for device_entry in device_form.devices.entries:
        device_data = {
            "device_name": device_entry.device_name.data,
            "device_guid": device_entry.device_guid.data,
            "num_sensors": device_entry.num_sensors.data,
            "device_info": device_entry.device_info.data,
            "device_type": device_entry.device_type.data,
            "device_location": device_entry.device_location.data,
            "device_active": device_entry.device_active.data,
            "connection": device_entry.connection.data,
            "sensors": [_parse_sensor_entry(s) for s in device_entry.sensors.entries],
        }
        devices.append(device_data)
    return devices


def _handle_db_setup(db_form):
    """Handles database creation and devlist table setup. Returns True on success."""
    db_path = db_form.file_path.data.strip()

    dberror, connection, cursor = pysql.connect_db(db_path, db_create=1)
    if dberror != 0:
        flash(f"Database connection error: {dberror}", "danger")
        return False

    if not pysql.check_table_exists(cursor, "devlist"):
        if pysql.create_dev_table(cursor) == -1:
            flash("Failed to create devlist table.", "danger")
            connection.close()
            return False

    connection.commit()
    connection.close()
    current_app.handler.save_dict["sqlite"] = {"db_path": db_path}
    flash(f"Database ready at: {db_path}", "success")
    return True


def register_setup(app):
    """Register the /setup blueprint routes onto the Flask app."""
    if app.handler.setup:

        @setup_bp.route("/setup", methods=["GET", "POST"])
        def setup_log():
            db_form = LabRatSetUpForm()
            device_form = DeviceSetupForm()

            if db_form.submit.data and db_form.validate_on_submit():
                if _handle_db_setup(db_form):
                    return redirect(url_for("setup.setup_log"))

            if device_form.submit.data and device_form.validate_on_submit():
                if "sqlite" not in current_app.handler.save_dict:
                    flash(
                        "Please configure the database before adding devices.",
                        "warning",
                    )
                    return redirect(url_for("setup.setup_log"))

                devices_json = _parse_device_form(device_form)
                validated, error = validate_devices(devices_json)
                if error:
                    flash(f"Validation Error: {error}", "error")
                    return redirect(url_for("setup.setup_log"))

                dberror, connection, cursor = pysql.connect_db(
                    current_app.handler.save_dict["sqlite"]["db_path"], db_create=1
                )
                if dberror != 0:
                    flash(f"Database connection error: {dberror}", "danger")
                    return redirect(url_for("setup.setup_log"))

                if save_devices_to_db(cursor, connection, validated["devices"]):
                    flash(
                        "Devices and sensors successfully saved to database!", "success"
                    )
                else:
                    flash("SQL Error inserting device.", "error")

                return render_template(
                    "device_success.html", data=json.dumps(validated, indent=2)
                )

            return render_template(
                "setup_labrat.html",
                db_form=db_form,
                device_form=device_form,
                set_mess="Configure SQLite Logging",
            )

    else:

        @setup_bp.route("/setup", methods=["GET", "POST"])
        def setup_disabled():
            return render_template(
                "setup_labrat_disabled.html", set_mess="Setup is currently disabled."
            )

    app.register_blueprint(setup_bp)
