import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:math' as math;
import 'dart:html' as html;

import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter/material.dart';
import 'package:memorias_calculo_web/src/widgets/encabezado_pais.dart';

import '../widgets/circulo_diametro.dart';
import '../widgets/formatters.dart';
import 'interfaz_cuadricula_page.dart';

class ConfiguracionProyectoNuevoPage extends StatefulWidget {
  final String tipoInstalacion;
  final String datos;
  final String token;
  final String idUsuario;
  final String idProyecto;
  final String estatus;
  final String archpdf;
  final String pais;
  final String code;
  final String noProyecto;

  const ConfiguracionProyectoNuevoPage({
    Key? key,
    required this.tipoInstalacion,
    required this.datos,
    required this.token,
    required this.idUsuario,
    required this.idProyecto,
    required this.estatus,
    required this.archpdf,
    required this.pais,
    required this.code,
    required this.noProyecto
  }) : super(key: key);

  @override
  State<ConfiguracionProyectoNuevoPage> createState() => _ConfiguracionProyectoNuevoPageState();
}

class _ConfiguracionProyectoNuevoPageState extends State<ConfiguracionProyectoNuevoPage> {
  late String _tipoInstalacion;

  final TextEditingController _longitudCampanaController = TextEditingController();
  final TextEditingController _anchoCampanaController = TextEditingController();
  final TextEditingController _distCapCampanaController = TextEditingController();
  final TextEditingController _medidaDuctoController = TextEditingController();
  final List<int> _velocidadesAire = [];
  final List<int> _velRec = [];

  String _aplicacionCampana = "";
  String _montajeCampana = "";
  String _eqCocinaCampana = "(Minimo) Estufas Gas, Hornos Electricos, Lavaplatos";
  String _tipoDucto = "";
  String _tipoDuctoInstalado = "";
  String _unidadLongitudes = "m";
  String _unidadCaudal = "m³/h";
  String _unidadDucto = "cm";
  String _hintTextUnidadDucto = "";
  String _msgVel = "";
  String _jsonCalculos = "";

  double _valLongitud = 0.0;
  double _valAncho = 0.0;
  double _valDistCap = 0.0;
  double _caudalExtraccion = 0.0;

  int _velocidadAire = 0;
  int _ductoCuadradoCM = 0;
  int _ductoCuadradoIN = 0;
  int _ductoCircularCM = 0;
  int _ductoCircularIN = 0;

  bool _errorVel = false;
  bool _continuarHabilitado = false;
  bool _isLoading = true;
  bool _finalizado = false;

  Map<String, String> _confCuad = {};
  Map<String, String> _cuadricula = {};

  //Constantes para los cálculos
  static const Map<String, double> _velocidades ={
    "Campana Domestica" : 0.15 * 3600,
    "Campana Comercial" : 0.25 * 3600,
    "Campana Humo soldadura" : 0.5 * 3600
  };
  static const Map<String, double> _factores ={
    "(Minimo) Estufas Gas, Hornos Electricos, Lavaplatos" : 1,
    "(Medium) Freidoras Sushi, WOK Comida China, Planchas" : 1.25,
    "(Heavy) Parrilla Cortes Carne, Combustibles Solidos (Carbón, Leña)" : 1.5
  };
  static const double _conversion = 1.7;
  static const List<String> _unidadesLongitudes = ["m", "ft"];
  static const List<String> _unidadesCaudal = ["m³/h", "CFM"];

  @override
  void initState() {
    super.initState();
    _finalizado = widget.estatus == "F";

    _longitudCampanaController.text = "0.00";
    _anchoCampanaController.text = "0.00";
    _distCapCampanaController.text = "0.00";

    if(widget.datos.isEmpty){
      _tipoInstalacion = widget.tipoInstalacion;

      Map<String, Map<String, String>> datos = {
        "datos": {
          "tipoInstalacion": _tipoInstalacion
        }
      };

      String datosStr = jsonEncode(datos);
      _cambiarDatos(datosStr).then((value) => setState(() => _isLoading = false));
    }else{
      _leerJson(widget.datos).then((value) => setState(() => _isLoading = false));
    }

    _hintTextUnidadDucto = _unidadDucto == "cm" ? "Unidades en centimetros." : "Unidades en pulgadas.";
    int velMin = 600;
    int velMax = 3000;

    int rangoVelocidades = velMax - velMin;
    rangoVelocidades = rangoVelocidades~/100;
    rangoVelocidades++;

    for(int i = 0; i < rangoVelocidades; i++){
      int vel = velMin + (i * 100);
      _velocidadesAire.add(vel);
    }
  }

  Future<bool> _cambiarDatos(String datos) async{
    final url = Uri.https("smart.solerpalau.mx", "PR/api/v1/quiosco/matrizMemoriasCalculo/actualizarProyecto");
    _finalizado = false;
    final res = await http.post(url,
      headers: {
        "Authorization": "Bearer ${widget.token}"
      },
      body: {
        "IDUSUARIO": widget.idUsuario,
        "IDPROYECTO": widget.idProyecto,
        "FMODIF": DateTime.now().toIso8601String().substring(0, 19),
        "ESTATUS": "C",
        "DATOS": base64Encode(utf8.encode(datos)),
        "ARCHPDF" : ""
      },
    );

    final decoded = jsonDecode(res.body);
    return decoded['response'];
  }

  Future<void> _leerJson(String datos) async{
    final datosStr = utf8.decode(base64Decode(datos));
    final json = await jsonDecode(datosStr);
    if(json.containsKey("campana")){
      _confCuad = {
        "salidas": json["campana"]["salidas"],
        "codos": json["campana"]["codos"],
      };
    }
    if(json.containsKey("cuadricula")){
      _cuadricula = {
        "historial" : json["cuadricula"]["historial"],
        "properties": json["cuadricula"]["properties"],
        "tramosRectos": json["cuadricula"]["tramosRectos"],
        "codosInstalados": json["cuadricula"]["codosInstalados"],
        "perdidasAdicionales": json["cuadricula"]["perdidasAdicionales"],
        "reducciones": json["cuadricula"]["reducciones"],
        "ampliaciones": json["cuadricula"]["ampliaciones"],
      };
    }
    if(json.containsKey("calculos")){
      _jsonCalculos =  json["calculos"]["resultados"];
    }

    _tipoInstalacion = json["datos"]["tipoInstalacion"];

    if(json["datos"].containsKey("tipoCampana")){
      final tipoCampana = json["datos"]["tipoCampana"];
      final tipoCampanaArr = tipoCampana.split(" ");

      if(tipoCampanaArr[1].isNotEmpty){
        _aplicacionCampana = tipoCampanaArr[1];
      }else{
        return;
      }

      if(tipoCampanaArr[2].isNotEmpty){
        String montaje = "";
        for(int i = 2; i < tipoCampanaArr.length; i++){
          montaje = "$montaje${tipoCampanaArr[i]} ";
        }
        _montajeCampana = montaje.trim();
      }else{
        return;
      }
    }else{
      return;
    }

    if(json["datos"].containsKey("eqCocina")){
      _eqCocinaCampana = json["datos"]["eqCocina"];
    }

    if(json["datos"].containsKey("longitud")){
      final longitud = json["datos"]["longitud"];
      final longitudArr = longitud.split(" ");

      _valLongitud = double.parse(longitudArr[0]);
      _unidadLongitudes = longitudArr[1];

      if(_valLongitud == 0){
        _longitudCampanaController.text = "0.00";
        return;
      }else{
        _longitudCampanaController.text = _valLongitud.toStringAsFixed(2);
      }
    }

    if(json["datos"].containsKey("ancho")){
      final longitud = json["datos"]["ancho"];
      final longitudArr = longitud.split(" ");

      _valAncho = double.parse(longitudArr[0]);

      if(_valAncho == 0){
        _anchoCampanaController.text = "0.00";
        return;
      }else{
        _anchoCampanaController.text = _valAncho.toStringAsFixed(2);
      }
    }

    if(json["datos"].containsKey("distCapt")){
      final longitud = json["datos"]["distCapt"];
      final longitudArr = longitud.split(" ");

      _valDistCap = double.parse(longitudArr[0]);

      if(_valDistCap == 0){
        _distCapCampanaController.text = "0.00";
        return;
      }else{
        _distCapCampanaController.text = _valDistCap.toStringAsFixed(2);
      }
    }

    if(json["datos"].containsKey("caudalEx")){
      final longitud = json["datos"]["caudalEx"];
      final longitudArr = longitud.split(" ");

      _caudalExtraccion = double.parse(longitudArr[0]) / _factores[_eqCocinaCampana]!;
      _unidadCaudal = longitudArr[1];
    }

    if(json["datos"].containsKey("velAire")){
      final velocidad = json["datos"]["velAire"];

      if(json["datos"]["tipoInstalacion"] == "N"){
        _velocidadAire = int.parse(velocidad);
      }else{
        _velRec.add(int.parse(velocidad));
      }
    }

    if(_tipoInstalacion == "N") _calcularDucto();

    if(json["datos"].containsKey("ductoSeleccion")){
      final ductoSeleccion = json["datos"]["ductoSeleccion"];

      if(ductoSeleccion.isNotEmpty && json["datos"]["tipoInstalacion"] == "N"){
        _tipoDucto = ductoSeleccion;
        _continuarHabilitado = true;
      }else if(ductoSeleccion.isNotEmpty && json["datos"]["tipoInstalacion"] == "E"){
        _tipoDuctoInstalado = ductoSeleccion;
      }
    }

    if(_tipoInstalacion == "E" && _tipoDuctoInstalado.isNotEmpty){
      final medidacmStr = _tipoDuctoInstalado == "circular" ? json["datos"]["ductoCircularCM"] : json["datos"]["ductoCuadradoCM"];
      final medidainStr = _tipoDuctoInstalado == "circular" ? json["datos"]["ductoCircularIN"] : json["datos"]["ductoCuadradoIN"];

      final medidacmArr = medidacmStr.split(" ");
      final medidainArr = medidainStr.split(" ");

      final unidadesInstaladas = json["datos"]["unidadesInstalado"];

      if(unidadesInstaladas == "cm" && medidacmArr[0].isEmpty) return;
      if(unidadesInstaladas == "in" && medidainArr[0].isEmpty) return;

      _medidaDuctoController.text = unidadesInstaladas == "cm" ? medidacmArr[0] : medidainArr[0];
      _unidadDucto = unidadesInstaladas;

      _continuarHabilitado = true;
      _calcularVelocidad();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _isLoading ? const Center(
        child: CircularProgressIndicator(),
      ) : LayoutBuilder(
        builder: (context, constraints) {
          final parentWidth = constraints.maxWidth;

          double containerWidth = parentWidth > 1440
              ? parentWidth*0.5 : parentWidth > 1280 && parentWidth <= 1440
              ? parentWidth*0.6 : parentWidth > 1080 && parentWidth <= 1280
              ? parentWidth*0.75 : parentWidth > 900 && parentWidth <= 1080
              ? parentWidth*0.8 : parentWidth > 720 && parentWidth <= 900
              ? parentWidth*0.85 : parentWidth > 540 && parentWidth <= 720
              ? parentWidth*0.9 : parentWidth;
          double containerMargin = (parentWidth - containerWidth) / 2;

          return SingleChildScrollView(
            child: Container(
              width: containerWidth,
              margin: EdgeInsets.symmetric(horizontal: containerMargin),
              child: Column(
                children: [
                  const SizedBox(height: 8.0),
                  Container(
                    margin: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Row(
                      children: [
                        TextButton(
                          child: Text(
                            "Memoria de cálculo de ventilación localizada >",
                            style: GoogleFonts.roboto(
                              fontSize: 16.0,
                              fontWeight: FontWeight.bold,
                              fontStyle: FontStyle.italic,
                            ),
                          ),
                          onPressed: () async{
                            final accion = await showDialog(
                              context: context,
                              barrierDismissible: false,
                              builder: (context) => AlertDialog(
                                title: Text(
                                  "Salir sin guardar",
                                  textAlign: TextAlign.center,
                                  style: GoogleFonts.roboto(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 20.0,
                                    color: Colors.black87,
                                  ),
                                ),
                                content: Text(
                                  "¿Está seguro de salir sin guardar los cambios?",
                                  textAlign: TextAlign.center,
                                  style: GoogleFonts.roboto(
                                    fontSize: 16.0,
                                  ),
                                ),
                                actions: [
                                  TextButton(
                                    child: const Text("Salir sin guardar"),
                                    onPressed: () => Navigator.pop(context, "salir"),
                                  ),
                                  TextButton(
                                    child: const Text("Guardar y salir"),
                                    onPressed: () => Navigator.pop(context, "guardar"),
                                  ),
                                  TextButton(
                                    child: const Text("Cancelar"),
                                    onPressed: () => Navigator.pop(context, "cancelar"),
                                  )
                                ],
                              ),
                            );

                            if(accion == "salir"){
                              Navigator.pop(context);
                            }else if(accion == "guardar"){
                              Map<String, Map<String, String>> datos = {
                                "datos": {
                                  "tipoInstalacion" : _tipoInstalacion,
                                  "tipoCampana" : "Campana $_aplicacionCampana $_montajeCampana",
                                  "eqCocina" : _eqCocinaCampana,
                                  "longitud" : "$_valLongitud $_unidadLongitudes",
                                  "ancho" : "$_valAncho $_unidadLongitudes",
                                  "distCapt" : "$_valDistCap $_unidadLongitudes",
                                  "caudalEx" : "${(_caudalExtraccion * _factores[_eqCocinaCampana]!).round()} $_unidadCaudal",
                                  "cauInySug" : "${((_caudalExtraccion * _factores[_eqCocinaCampana]!) * 0.85).round()} $_unidadCaudal",
                                  "velAire" : _tipoInstalacion == "N" ? "$_velocidadAire" : "${_velRec.first}",
                                  "ductoCuadradoCM" : _tipoInstalacion == "N" ? "$_ductoCuadradoCM cm" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCuadradoIN" : _tipoInstalacion == "N" ? "$_ductoCuadradoIN in" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoCircularCM" : _tipoInstalacion == "N" ? "$_ductoCircularCM cm" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCircularIN" : _tipoInstalacion == "N" ? "$_ductoCircularIN in" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoSeleccion" : _tipoInstalacion == "N" ? _tipoDucto : _tipoDuctoInstalado,
                                  "unidadesInstalado" : _unidadDucto
                                },
                                if(_confCuad.isNotEmpty)
                                  "campana": _confCuad,
                                if(_cuadricula.isNotEmpty)
                                  "cuadricula": _cuadricula,
                                if(_jsonCalculos.isNotEmpty)
                                  "calculos": { "resultados": _jsonCalculos }
                              };
                              String datosStr = jsonEncode(datos);

                              final guardado = await _cambiarDatos(datosStr);
                              if(guardado){
                                Fluttertoast.showToast(
                                  msg: "El proyecto se guardó satisfactoriamente",
                                  toastLength: Toast.LENGTH_SHORT,
                                  timeInSecForIosWeb: 4,
                                  gravity: ToastGravity.CENTER,
                                  webBgColor: "linear-gradient(to right, #266B1F, #98F58F)",
                                );
                              }else{
                                Fluttertoast.showToast(
                                  msg: "Hubo un error al intentar guardar el proyecto, intentelo de nuevo más tarde.",
                                  toastLength: Toast.LENGTH_SHORT,
                                  timeInSecForIosWeb: 4,
                                  gravity: ToastGravity.CENTER,
                                  webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                );
                              }

                              Navigator.pop(context);
                            }
                          },
                          style: TextButton.styleFrom(
                              padding: const EdgeInsets.fromLTRB(0.0, 0.0, 8.0, 0.0),
                              minimumSize: const Size(0.0, 0.0),
                              tapTargetSize: MaterialTapTargetSize.shrinkWrap
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: Container(
                            padding: const EdgeInsets.fromLTRB(0.0, 0.0, 8.0, 0.0),
                            child: Text(
                              "Equipos de extracción de cocina doméstica y comercial",
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                              style: GoogleFonts.roboto(
                                fontSize: 16.0,
                                color: Colors.black54,
                                fontWeight: FontWeight.bold,
                                fontStyle: FontStyle.italic,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 8.0),
                  EncabezadoPais(paisCode: widget.code, paisName: widget.pais),
                  const SizedBox(height: 32.0),
                  Image.asset(
                    "campana.png",
                    width: 120.0,
                  ),
                  const SizedBox(height: 48.0),
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Text(
                      "Equipos de extracción de cocina doméstica y comercial".toUpperCase(),
                      textAlign: TextAlign.center,
                      style: const TextStyle(
                        fontFamily: "Helvetica Neue Black Cond",
                        fontSize: 28.0,
                      ),
                    ),
                  ),
                  const SizedBox(height: 8.0),
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 32.0),
                    width: double.infinity,
                    child: const Text(
                      "Por favor ingresa los datos requeridos para el cálculo de la campana.",
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontFamily: "Helvetica Neue Light",
                        fontSize: 22.0,
                        fontWeight: FontWeight.w600,
                        color: Color.fromRGBO(104, 104, 104, 1),
                      ),
                    ),
                  ),
                  const SizedBox(height: 32.0),
                  Container(
                    margin: const EdgeInsets.symmetric(horizontal: 32.0),
                    child: Row(
                      children: [
                        Text(
                          "Aplicación:",
                          style: GoogleFonts.roboto(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: DropdownButton<String>(
                            focusColor: Colors.transparent,
                            value: _aplicacionCampana.isEmpty ? null : _aplicacionCampana,
                            isExpanded: true,
                            hint: Text(
                              "Selecciona una opción",
                              style: GoogleFonts.roboto(
                                color: Colors.grey,
                                fontSize: 18.0,
                                fontStyle: FontStyle.italic,
                              ),
                            ),
                            onChanged: (newValue) => setState((){
                              _aplicacionCampana = newValue!;
                              _calcularCaudal();
                            }),
                            items: <String>["Domestica", "Comercial"/*, "Humo soldadura"*/].map((e) => DropdownMenuItem<String>(
                              child: Text(
                                e == "Domestica" ? "$e (Estufa de casa, estufa de oficina, etc.)"
                                  : e == "Comercial" ? "$e (Restaurante, Cocina comercial, etc.)"
                                  : "Industrial ($e, Tinas de lavado, etc.)",
                                style: GoogleFonts.roboto(
                                  fontSize: 18.0,
                                ),
                              ),
                              value: e,
                            )).toList(),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 16.0),
                  Container(
                    margin: const EdgeInsets.symmetric(horizontal: 32.0),
                    child: Row(
                      children: [
                        Text(
                          "Montaje:",
                          style: GoogleFonts.roboto(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: DropdownButton<String>(
                            focusColor: Colors.transparent,
                            value: _montajeCampana.isEmpty ? null : _montajeCampana,
                            isExpanded: true,
                            hint: Text(
                              "Selecciona una opción",
                              style: GoogleFonts.roboto(
                                color: Colors.grey,
                                fontSize: 18.0,
                                fontStyle: FontStyle.italic,
                              ),
                            ),
                            onChanged: (newValue) => setState((){
                              _montajeCampana = newValue!;
                              _calcularCaudal();
                            }),
                            items: <String>["Adosada 1 Pared", "Adosada 2 Paredes", "Adosada 3 Paredes", "Tipo Isla"].map((e) => DropdownMenuItem<String>(
                              child: Text(
                                e,
                                style: GoogleFonts.roboto(
                                  fontSize: 18.0,
                                ),
                              ),
                              value: e,
                            )).toList(),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 16.0),
                  Container(
                    margin: const EdgeInsets.symmetric(horizontal: 32.0),
                    child: Row(
                      children: [
                        Text(
                          "Longitud:",
                          style: GoogleFonts.roboto(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: SizedBox(
                            height: 64.0,
                            width: double.infinity,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                TextField(
                                  textAlign: TextAlign.center,
                                  controller: _longitudCampanaController,
                                  maxLength: 6,
                                  decoration: const InputDecoration(
                                    counterText: "",
                                    counterStyle: TextStyle(
                                      height: double.minPositive,
                                    ),
                                  ),
                                  inputFormatters: [
                                    DecimalTextInputFormatter()
                                  ],
                                  onChanged: (val){
                                    if(val.isNotEmpty){
                                      _valLongitud = double.parse(val);
                                    }else{
                                      _valLongitud = 0.0;
                                    }

                                    _calcularCaudal();
                                  },
                                ),
                                Positioned(
                                  left: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.remove,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valLongitud = _valLongitud - 0.1;

                                      if(_valLongitud < 0){
                                        _valLongitud = 0.0;
                                      }

                                      _longitudCampanaController.text = _valLongitud.toStringAsFixed(2);
                                      _calcularCaudal();
                                    }),
                                  ),
                                ),
                                Positioned(
                                  right: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.add,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valLongitud = _valLongitud + 0.1;

                                      if(_valLongitud > 999){
                                        _valLongitud = 999.0;
                                      }

                                      _longitudCampanaController.text = _valLongitud.toStringAsFixed(2);
                                      _calcularCaudal();
                                    }),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        DropdownButton<String>(
                          value: _unidadLongitudes,
                          onChanged: (value) => setState((){
                            _unidadLongitudes = value!;
                            _calcularCaudal();
                          }),
                          items: _unidadesLongitudes.map((e) => DropdownMenuItem<String>(
                            child: Text(
                              e,
                              style: GoogleFonts.roboto(
                                fontSize: 18.0,
                              ),
                            ),
                            value: e,
                          )).toList(),
                        ),
                        const SizedBox(width: 8.0),
                        IconButton(
                          icon: const Icon(
                            Icons.info_outline,
                          ),
                          onPressed: () => showDialog(
                            context: context,
                            barrierDismissible: true,
                            builder: (context) => AlertDialog(
                              title: const Text(
                                "Longitud",
                              ),
                              content: Image.asset(
                                "medidaLongitud.png",
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 16.0),
                  Container(
                    margin: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Row(
                      children: [
                        Text(
                          "Ancho:",
                          style: GoogleFonts.roboto(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: Stack(
                            alignment: Alignment.center,
                            children: [
                              TextField(
                                textAlign: TextAlign.center,
                                controller: _anchoCampanaController,
                                maxLength: 6,
                                decoration: const InputDecoration(
                                  counterText: "",
                                  counterStyle: TextStyle(
                                      height: double.minPositive
                                  ),
                                ),
                                inputFormatters: [
                                  DecimalTextInputFormatter()
                                ],
                                onChanged: (val){
                                  if(val.isEmpty){
                                    _valAncho = 0.0;
                                  }else{
                                    _valAncho = double.parse(val);
                                  }

                                  _calcularCaudal();
                                },
                              ),
                              Positioned(
                                left: 0.0,
                                child: IconButton(
                                  icon: const Icon(
                                    Icons.remove,
                                    color: Colors.black45,
                                  ),
                                  onPressed: () => setState(() {
                                    _valAncho = _valAncho - 0.1;

                                    if(_valAncho < 0){
                                      _valAncho = 0.0;
                                    }

                                    _anchoCampanaController.text = _valAncho.toStringAsFixed(2);
                                    _calcularCaudal();
                                  }),
                                ),
                              ),
                              Positioned(
                                right: 0.0,
                                child: IconButton(
                                  icon: const Icon(
                                    Icons.add,
                                    color: Colors.black45,
                                  ),
                                  onPressed: () => setState(() {
                                    _valAncho = _valAncho + 0.1;

                                    if(_valAncho > 999){
                                      _valAncho = 999.0;
                                    }

                                    _anchoCampanaController.text = _valAncho.toStringAsFixed(2);
                                    _calcularCaudal();
                                  }),
                                ),
                              ),
                            ],
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Container(
                          child: Text(
                            _unidadLongitudes,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                          padding: const EdgeInsets.fromLTRB(0, 0, 24.0, 8.0),
                          decoration: BoxDecoration(
                            border: Border(
                              bottom: BorderSide(
                                color: Colors.black.withOpacity(0.18),
                                width: 2.0,
                              ),
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        IconButton(
                          icon: const Icon(
                            Icons.info_outline,
                          ),
                          onPressed: () => showDialog(
                            context: context,
                            barrierDismissible: true,
                            builder: (context) => AlertDialog(
                              title: const Text(
                                "Ancho",
                              ),
                              content: Image.asset(
                                  "medidaAncho.png"
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 16.0),
                  Container(
                    margin: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Row(
                      children: [
                        Text(
                          "Distancia Captación:",
                          style: GoogleFonts.roboto(
                              fontWeight: FontWeight.bold,
                              fontSize: 18.0
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: Stack(
                            alignment: Alignment.center,
                            children: [
                              TextField(
                                textAlign: TextAlign.center,
                                controller: _distCapCampanaController,
                                maxLength: 6,
                                decoration: const InputDecoration(
                                  counterText: "",
                                  counterStyle: TextStyle(
                                      height: double.minPositive
                                  ),
                                ),
                                inputFormatters: [
                                  DecimalTextInputFormatter()
                                ],
                                onChanged: (val) {
                                  if(val.isEmpty){
                                    _valDistCap = 0.0;
                                  }else{
                                    _valDistCap = double.parse(val);
                                  }

                                  _calcularCaudal();
                                },
                              ),
                              Positioned(
                                left: 0.0,
                                child: IconButton(
                                  icon: const Icon(
                                    Icons.remove,
                                    color: Colors.black45,
                                  ),
                                  onPressed: () => setState(() {
                                    _valDistCap = _valDistCap - 0.1;

                                    if(_valDistCap < 0){
                                      _valDistCap = 0.0;
                                    }

                                    _distCapCampanaController.text = _valDistCap.toStringAsFixed(2);
                                    _calcularCaudal();
                                  }),
                                ),
                              ),
                              Positioned(
                                right: 0.0,
                                child: IconButton(
                                  icon: const Icon(
                                    Icons.add,
                                    color: Colors.black45,
                                  ),
                                  onPressed: () => setState(() {
                                    _valDistCap = _valDistCap + 0.1;

                                    if(_valDistCap > 999){
                                      _valDistCap = 999.0;
                                    }

                                    _distCapCampanaController.text = _valDistCap.toStringAsFixed(2);
                                    _calcularCaudal();
                                  }),
                                ),
                              ),
                            ],
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Container(
                          child: Text(
                            _unidadLongitudes,
                            style: GoogleFonts.roboto(
                                fontSize: 18.0
                            ),
                          ),
                          padding: const EdgeInsets.fromLTRB(0, 0, 24.0, 8.0),
                          decoration: BoxDecoration(
                              border: Border(
                                  bottom: BorderSide(
                                      color: Colors.black.withOpacity(0.18),
                                      width: 2.0
                                  )
                              )
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        IconButton(
                          icon: const Icon(
                            Icons.info_outline,
                          ),
                          onPressed: () => showDialog(
                            context: context,
                            barrierDismissible: true,
                            builder: (context) => AlertDialog(
                              title: const Text(
                                "Distancia Captación",
                              ),
                              content: Image.asset(
                                "medidaDistCap.png",
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 16.0),
                  Container(
                    margin: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Row(
                      children: [
                        Text(
                          "Equipo Cocina:",
                          style: GoogleFonts.roboto(
                              fontWeight: FontWeight.bold,
                              fontSize: 18.0
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: DropdownButton<String>(
                            value: _eqCocinaCampana.isEmpty ? null : _eqCocinaCampana,
                            isExpanded: true,
                            hint: Text(
                              "Selecciona una opción",
                              style: GoogleFonts.roboto(
                                  color: Colors.grey,
                                  fontSize: 18.0,
                                  fontStyle: FontStyle.italic
                              ),
                            ),
                            onChanged: (newValue) => setState((){
                              _eqCocinaCampana = newValue!;
                              _calcularCaudal();
                            }),
                            items: <String>["(Minimo) Estufas Gas, Hornos Electricos, Lavaplatos",
                              "(Medium) Freidoras Sushi, WOK Comida China, Planchas",
                              "(Heavy) Parrilla Cortes Carne, Combustibles Solidos (Carbón, Leña)"].map((e) => DropdownMenuItem<String>(
                              child: Text(
                                e,
                                style: GoogleFonts.roboto(
                                    fontSize: 18.0
                                ),
                              ),
                              value: e,
                            )).toList(),
                          ),
                        )
                      ],
                    ),
                  ),
                  AnimatedCrossFade(
                    firstChild: Container(),
                    secondChild: Column(
                      children: [
                        const SizedBox(
                          height: 16.0,
                        ),
                        Container(
                          margin: const EdgeInsets.symmetric(
                            horizontal: 32.0,
                          ),
                          child: Row(
                            children: [
                              Expanded(
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    RichText(
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      text: TextSpan(
                                        style: GoogleFonts.roboto(fontSize: 18.0),
                                        children: [
                                          TextSpan(
                                            text: "Caudal Extracción: ",
                                            style: GoogleFonts.roboto(fontWeight: FontWeight.bold),
                                          ),
                                          TextSpan(text: "${(_caudalExtraccion * _factores[_eqCocinaCampana]!).round()}"),
                                        ],
                                      ),
                                    ),
                                    const SizedBox(width: 8.0),
                                    DropdownButton<String>(
                                      value: _unidadCaudal,
                                      onChanged: (value) => setState((){
                                        _unidadCaudal = value!;
                                        _calcularCaudal();
                                      }),
                                      items: _unidadesCaudal.map((e) => DropdownMenuItem<String>(
                                        child: Text(
                                          e,
                                          style: GoogleFonts.roboto(
                                              fontSize: 18.0
                                          ),
                                        ),
                                        value: e,
                                      )).toList(),
                                    ),
                                  ],
                                ),
                              ),
                              const SizedBox(width: 8.0),
                              Expanded(
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    RichText(
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      text: TextSpan(
                                        style: GoogleFonts.roboto(fontSize: 18.0),
                                        children: [
                                          TextSpan(
                                            text: "Caudal Inyección Sugerida: ",
                                            style: GoogleFonts.roboto(fontWeight: FontWeight.bold),
                                          ),
                                          TextSpan(text: "${((_caudalExtraccion * _factores[_eqCocinaCampana]!) * 0.85).round()}")
                                        ]
                                      ),
                                    ),
                                    const SizedBox(width: 8.0),
                                    Container(
                                      decoration: BoxDecoration(
                                        border: Border(
                                          bottom: BorderSide(
                                            color: Colors.black.withOpacity(0.18),
                                            width: 2.0,
                                          ),
                                        ),
                                      ),
                                      padding: const EdgeInsets.only(
                                        bottom: 6.0,
                                        top: 8.0,
                                        right: 24.0
                                      ),
                                      child: Text(
                                        _unidadCaudal,
                                        style: GoogleFonts.roboto(
                                          fontSize: 18.0,
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              ),
                              const SizedBox(width: 8.0),
                              IconButton(
                                icon: const Icon(
                                    Icons.info_outline
                                ),
                                onPressed: () => showDialog(
                                    context: context,
                                    barrierDismissible: true,
                                    builder: (context) => const AlertDialog(
                                        title: Text(
                                            "Caudal Inyección Sugerida"
                                        ),
                                        content: Text(
                                            "Se recomienda una inyección de aire filtrado del 85% con respecto al caudal de extracción para mantener una presión negativa en el interior cocina."
                                        )
                                    )
                                ),
                              ),
                            ],
                          ),
                        ),
                        const SizedBox(
                          height: 16.0,
                        ),
                        if(_tipoInstalacion == "N")
                          Container(
                            margin: const EdgeInsets.symmetric(
                              horizontal: 32.0,
                            ),
                            child: Row(
                              children: [
                                Text(
                                  "Aplicación:",
                                  style: GoogleFonts.roboto(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 18.0,
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                Expanded(
                                  child: DropdownButton<int>(
                                    focusColor: Colors.transparent,
                                    value: _velocidadAire == 0 ? null : _velocidadAire,
                                    isExpanded: true,
                                    hint: Text(
                                      "Selecciona una opción",
                                      style: GoogleFonts.roboto(
                                        color: Colors.grey,
                                        fontSize: 18.0,
                                        fontStyle: FontStyle.italic,
                                      ),
                                    ),
                                    onChanged: (newValue) => setState((){
                                      _velocidadAire = newValue!;
                                      _calcularDucto();
                                    }),
                                    items: _velocidadesAire.map((e) => DropdownMenuItem<int>(
                                      child: Text(
                                        e >= 600 && e < 1000
                                            ? "Residencial ($e)"
                                            : e >= 1000 && e < 1600
                                            ? "Comercial ($e)"
                                            : e >= 1600 && e < 1800
                                            ? "Industrial ($e)"
                                            : e >= 1800 && e < 2200
                                            ? "Ideal Aire Grasa ($e)"
                                            : e >= 2200 && e < 3000
                                            ? "Adecuado Aire Grasa ($e)"
                                            : "Límite Superior Manejo Aire Grasa ($e)",
                                        style: GoogleFonts.roboto(
                                          fontSize: 18.0,
                                        ),
                                      ),
                                      value: e,
                                    )).toList(),
                                  ),
                                )
                              ],
                            ),
                          ),
                        if(_tipoInstalacion == "E")
                          Container(
                            margin: const EdgeInsets.symmetric(
                              horizontal: 32.0,
                            ),
                            child: Row(
                              children: [
                                Text(
                                  "Tipo Ducto Instalado:",
                                  style: GoogleFonts.roboto(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                Expanded(
                                  child: RadioListTile(
                                    value: "circular",
                                    groupValue: _tipoDuctoInstalado,
                                    onChanged: (value) => setState((){
                                      _tipoDuctoInstalado = value.toString();
                                      _calcularCaudal();
                                    }),
                                    activeColor: const Color(0xFFB40404),
                                    title: Text(
                                      "Ducto Circular",
                                      style: GoogleFonts.roboto(),
                                    ),
                                    selected: _tipoDuctoInstalado == "circular",
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                Expanded(
                                  child: RadioListTile(
                                    value: "cuadrado",
                                    groupValue: _tipoDuctoInstalado,
                                    onChanged: (value) => setState((){
                                      _tipoDuctoInstalado = value.toString();
                                      _calcularCaudal();
                                    }),
                                    activeColor: const Color(0xFFB40404),
                                    title: Text(
                                      "Ducto Cuadrado",
                                      style: GoogleFonts.roboto(),
                                    ),
                                    selected: _tipoDuctoInstalado == "cuadrado",
                                  ),
                                )
                              ],
                            ),
                          ),
                        const SizedBox(
                          height: 16.0,
                        ),
                        if(_tipoInstalacion == "N")
                          Container(
                            margin: const EdgeInsets.symmetric(
                                horizontal: 32.0
                            ),
                            child: Row(
                              children: [
                                Text(
                                  "Velocidad Ducto: ",
                                  style: GoogleFonts.roboto(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 18.0,
                                  ),
                                ),
                                const SizedBox(width: 8.0,),
                                Expanded(
                                  child: Text(
                                    "$_velocidadAire fpm",
                                    style: GoogleFonts.roboto(fontSize: 18.0),
                                  ),
                                ),
                                const SizedBox(width: 8.0,),
                                IconButton(
                                  icon: const Icon(Icons.info_outline),
                                  onPressed: () => showDialog(
                                    context: context,
                                    barrierDismissible: true,
                                    builder: (context) => const AlertDialog(
                                      title: Text(
                                        "Velocidad Ducto",
                                      ),
                                      content: Text(
                                        "Es la velocidad del interior del ducto.",
                                      ),
                                    ),
                                  ),
                                )
                              ],
                            ),
                          ),
                        if(_tipoInstalacion == "E" && _tipoDuctoInstalado.isNotEmpty)
                          Container(
                            margin: const EdgeInsets.symmetric(
                              horizontal: 32.0,
                            ),
                            child: Row(
                              children: [
                                Text(
                                  _tipoDuctoInstalado == "cuadrado" ? "Medida de un Lado de la Sección Cuadrada:" : "Medida del Diámetro de la Sección Circular:",
                                  style: GoogleFonts.roboto(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 18.0,
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                Expanded(
                                  child: TextField(
                                    controller: _medidaDuctoController,
                                    decoration: InputDecoration(
                                      hintText: _hintTextUnidadDucto,
                                      hintStyle: GoogleFonts.roboto(
                                        fontSize: 18.0,
                                        fontStyle: FontStyle.italic,
                                        color: Colors.grey,
                                      ),
                                    ),
                                    keyboardType: TextInputType.number,
                                    inputFormatters: [
                                      FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
                                    ],
                                    onChanged: (value) => _calcularCaudal(),
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                DropdownButton<String>(
                                  value: _unidadDucto,
                                  onChanged: (value) => setState((){
                                    _unidadDucto = value!;
                                    _hintTextUnidadDucto = _unidadDucto == "cm" ? "Unidades en centimetros." : "Unidades en pulgadas.";
                                    _calcularCaudal();
                                  }),
                                  items: <String>["cm", "in"].map((e) => DropdownMenuItem<String>(
                                    child: Text(
                                      e,
                                      style: GoogleFonts.roboto(
                                          fontSize: 18.0
                                      ),
                                    ),
                                    value: e,
                                  )).toList(),
                                ),
                              ],
                            ),
                          ),
                        if(_tipoInstalacion == "N")
                          const SizedBox(
                            height: 16.0,
                          ),
                        if(_tipoInstalacion == "E" && _tipoDuctoInstalado.isNotEmpty)
                          const SizedBox(
                            height: 16.0,
                          ),
                        if(_tipoInstalacion == "N")
                          Container(
                            margin: const EdgeInsets.symmetric(
                                horizontal: 32.0
                            ),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.start,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Column(
                                  mainAxisSize: MainAxisSize.min,
                                  children: [
                                    Container(
                                      width: containerWidth*0.25,
                                      alignment: Alignment.topLeft,
                                      child: Text(
                                        "Dimensiones del Ducto:",
                                        textAlign: TextAlign.start,
                                        style: GoogleFonts.roboto(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 18.0,
                                        ),
                                        maxLines: 1,
                                      ),
                                    ),
                                    const SizedBox(
                                      height: 32.0,
                                    ),
                                    Radio(
                                      value: "cuadrado",
                                      groupValue: _tipoDucto.isEmpty ? null : _tipoDucto,
                                      activeColor: const Color.fromRGBO(180, 4, 4, 1),
                                      onChanged: (value) => setState((){
                                        _tipoDucto = value.toString();
                                        _calcularCaudal();
                                      }),
                                    )
                                  ],
                                ),
                                Expanded(
                                  child: Container(
                                    decoration: BoxDecoration(
                                      border: Border.all(
                                        color: Colors.black87,
                                        width: 2.0,
                                      ),
                                    ),
                                    padding: const EdgeInsets.all(8.0),
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      crossAxisAlignment: CrossAxisAlignment.center,
                                      children: [
                                        SizedBox(
                                          width: double.infinity,
                                          child: Text(
                                            "Sección Cuadrada",
                                            textAlign: TextAlign.center,
                                            style: GoogleFonts.roboto(
                                                fontSize: 18.0,
                                                fontStyle: FontStyle.italic
                                            ),
                                          ),
                                        ),
                                        Row(
                                          children: [
                                            Expanded(
                                              child: Column(
                                                mainAxisAlignment: MainAxisAlignment.center,
                                                crossAxisAlignment: CrossAxisAlignment.center,
                                                children: [
                                                  Text(
                                                    "a: $_ductoCuadradoCM cm",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                        fontSize: 18.0
                                                    ),
                                                  ),
                                                  Text(
                                                    "a: $_ductoCuadradoIN in",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                        fontSize: 18.0
                                                    ),
                                                  ),
                                                  Text(
                                                    "a",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                        fontSize: 28.0,
                                                        fontWeight: FontWeight.bold
                                                    ),
                                                  )
                                                ],
                                              ),
                                            ),
                                            Expanded(child: Container())
                                          ],
                                        ),
                                        Row(
                                          children: [
                                            Expanded(
                                              child: Container(
                                                margin: const EdgeInsets.all(4.0),
                                                alignment: Alignment.center,
                                                child: SizedBox(
                                                  width: 128.0,
                                                  height: 56.0,
                                                  child: Row(
                                                    children: [
                                                      Expanded(child: Container()),
                                                      const SizedBox(width: 8.0),
                                                      Container(
                                                        width: 56.0,
                                                        height: 56.0,
                                                        decoration: BoxDecoration(
                                                          border: Border.all(),
                                                        ),
                                                      ),
                                                      const SizedBox(width: 8.0),
                                                      Expanded(
                                                        child: Text(
                                                          "b",
                                                          maxLines: 1,
                                                          textAlign: TextAlign.center,
                                                          style: GoogleFonts.roboto(
                                                              fontWeight: FontWeight.bold,
                                                              fontSize: 28.0
                                                          ),
                                                        ),
                                                      )
                                                    ],
                                                  ),
                                                ),
                                              ),
                                            ),
                                            Expanded(
                                              child: Column(
                                                children: [
                                                  Text(
                                                    "b: $_ductoCuadradoCM cm",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                      fontSize: 18.0,
                                                    ),
                                                  ),
                                                  Text(
                                                    "b: $_ductoCuadradoIN in",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                      fontSize: 18.0,
                                                    ),
                                                  )
                                                ],
                                              ),
                                            )
                                          ],
                                        )
                                      ],
                                    ),
                                  ),
                                )
                              ],
                            ),
                          ),
                        if(_tipoInstalacion == "N")
                          const SizedBox(
                            height: 16.0,
                          ),
                        if(_tipoInstalacion == "N")
                          Container(
                            margin: const EdgeInsets.symmetric(
                                horizontal: 32.0
                            ),
                            child: Row(
                              children: [
                                Container(
                                  width: containerWidth*0.25,
                                  alignment: Alignment.topCenter,
                                  margin: const EdgeInsets.only(top: 32.0),
                                  child: Radio(
                                    value: "circular",
                                    groupValue: _tipoDucto.isEmpty ? null : _tipoDucto,
                                    activeColor: const Color(0xFFB40404),
                                    onChanged: (value) => setState((){
                                      _tipoDucto = value.toString();
                                      _calcularCaudal();
                                    }),
                                  ),
                                ),
                                Expanded(
                                  child: Container(
                                    decoration: BoxDecoration(
                                        border: Border.all(
                                            color: Colors.black87,
                                            width: 2.0
                                        )
                                    ),
                                    padding: const EdgeInsets.all(8.0),
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      crossAxisAlignment: CrossAxisAlignment.center,
                                      children: [
                                        SizedBox(
                                          width: double.infinity,
                                          child: Text(
                                            "Sección Circular",
                                            textAlign: TextAlign.center,
                                            style: GoogleFonts.roboto(
                                                fontSize: 18.0,
                                                fontStyle: FontStyle.italic
                                            ),
                                          ),
                                        ),
                                        Row(
                                          children: [
                                            Expanded(
                                              child: Column(
                                                mainAxisAlignment: MainAxisAlignment.center,
                                                crossAxisAlignment: CrossAxisAlignment.center,
                                                children: [
                                                  Text(
                                                    "d: $_ductoCircularCM cm",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                      fontSize: 18.0,
                                                    ),
                                                  ),
                                                  Text(
                                                    "d: $_ductoCircularIN in",
                                                    maxLines: 1,
                                                    textAlign: TextAlign.center,
                                                    overflow: TextOverflow.ellipsis,
                                                    style: GoogleFonts.roboto(
                                                      fontSize: 18.0,
                                                    ),
                                                  )
                                                ],
                                              ),
                                            ),
                                            Expanded(
                                              child: Container(
                                                height: 128.0,
                                                padding: const EdgeInsets.all(8.0),
                                                child: Row(
                                                  children: [
                                                    Expanded(child: Container()),
                                                    SizedBox(
                                                      width: 28.0,
                                                      child: Text(
                                                        "d",
                                                        textAlign: TextAlign.center,
                                                        style: GoogleFonts.roboto(
                                                          fontWeight: FontWeight.bold,
                                                          fontSize: 28.0,
                                                        ),
                                                      ),
                                                    ),
                                                    const SizedBox(width: 8.0),
                                                    const SizedBox(
                                                      width: 112.0,
                                                      height: 112.0,
                                                      child: CirculoDiametro(),
                                                    ),
                                                    const SizedBox(width: 8.0),
                                                    Container(
                                                      width: 28.0,
                                                    ),
                                                    Expanded(child: Container()),
                                                  ],
                                                ),
                                              ),
                                            )
                                          ],
                                        )
                                      ],
                                    ),
                                  ),
                                )
                              ],
                            ),
                          ),
                        if(_tipoInstalacion == "E" && _tipoDuctoInstalado.isNotEmpty && _medidaDuctoController.text.isNotEmpty)
                          Container(
                            margin: const EdgeInsets.symmetric(
                              horizontal: 32.0,
                            ),
                            child: Row(
                              children: [
                                Text(
                                  _velRec.length > 1 ? "Velocidades Ducto:" : "Velocidad Ducto:",
                                  style: GoogleFonts.roboto(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 18.0,
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                Expanded(
                                  child: Text(
                                    _msgVel,
                                    style: GoogleFonts.roboto(
                                      fontSize: 18.0,
                                      color: _errorVel ? const Color(0xFFB40404) : Colors.black,
                                      fontWeight: _errorVel ? FontWeight.bold : FontWeight.normal,
                                    ),
                                    maxLines: 1,
                                    overflow: TextOverflow.ellipsis,
                                  ),
                                ),
                                const SizedBox(width: 8.0),
                                IconButton(
                                  icon: const Icon(
                                    Icons.info_outline,
                                  ),
                                  onPressed: () => showDialog(
                                    context: context,
                                    barrierDismissible: true,
                                    builder: (context) => AlertDialog(
                                      title: const Text("Velocidad Ducto"),
                                      content: _errorVel ? Text(
                                        "$_msgVel El rango de velocidades permitido es de 600 a 3000 fpm.",
                                        style: GoogleFonts.roboto(
                                          fontSize: 18.0,
                                          color: _errorVel ? const Color(0xFFB40404) : Colors.black,
                                          fontWeight: _errorVel ? FontWeight.bold : FontWeight.normal,
                                        ),
                                      ) : const Text("Es la velocidad del interior del ducto."),
                                    ),
                                  ),
                                )
                              ],
                            ),
                          ),
                      ],
                    ),
                    crossFadeState: _caudalExtraccion == 0 ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                    duration: const Duration(
                      milliseconds: 250,
                    ),
                  ),
                  const SizedBox(height: 32.0),
                  TextButton(
                    child: RichText(
                      text: TextSpan(
                        children: const [
                          TextSpan(
                            text: "Si requiere el cálculo para una campana industrial contacte a su ",
                          ),
                          TextSpan(
                            text: "Asesor Técnico Comercial de S&P",
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          TextSpan(
                            text: " de click ",
                          ),
                          TextSpan(
                            text: "AQUÍ",
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ],
                        style: GoogleFonts.roboto(
                          fontSize: 14.0,
                          fontWeight: FontWeight.normal,
                          color: const Color.fromRGBO(104, 104, 104, 1),
                        ),
                      ),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                    ),
                    onPressed: () => html.window.open("https://solerpalau.mx/contacto.php", "_blank"),
                  ),
                  const SizedBox(
                    height: 8.0,
                  ),
                  Container(
                    margin: const EdgeInsets.symmetric(
                      horizontal: 32.0,
                    ),
                    child: Row(
                      children: [
                        Expanded(
                          child: MaterialButton(
                            elevation: 4,
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            minWidth: (containerWidth/2)-32,
                            color: const Color(0xFFFF0000),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Image.asset(
                                  "guardar.png",
                                  width: 32.0,
                                ),
                                const SizedBox(width: 8.0),
                                const Text(
                                  "Guardar y regresar",
                                  style: TextStyle(
                                    fontFamily: "Helvetica Neue Black Cond",
                                    color: Colors.white,
                                    fontSize: 28.0,
                                  ),
                                )
                              ],
                            ),
                            onPressed: () async{
                              Map<String, Map<String, String>> datos = {
                                "datos": {
                                  "tipoInstalacion" : _tipoInstalacion,
                                  "tipoCampana" : "Campana $_aplicacionCampana $_montajeCampana",
                                  "eqCocina" : _eqCocinaCampana,
                                  "longitud" : "$_valLongitud $_unidadLongitudes",
                                  "ancho" : "$_valAncho $_unidadLongitudes",
                                  "distCapt" : "$_valDistCap $_unidadLongitudes",
                                  "caudalEx" : "${(_caudalExtraccion * _factores[_eqCocinaCampana]!).round()} $_unidadCaudal",
                                  "cauInySug" : "${((_caudalExtraccion * _factores[_eqCocinaCampana]!) * 0.85).round()} $_unidadCaudal",
                                  "velAire" : _tipoInstalacion == "N" ? "$_velocidadAire" : "${_velRec.isEmpty ? 0 : _velRec.first}",
                                  "ductoCuadradoCM" : _tipoInstalacion == "N" ? "$_ductoCuadradoCM cm" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCuadradoIN" : _tipoInstalacion == "N" ? "$_ductoCuadradoIN in" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoCircularCM" : _tipoInstalacion == "N" ? "$_ductoCircularCM cm" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCircularIN" : _tipoInstalacion == "N" ? "$_ductoCircularIN in" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoSeleccion" : _tipoInstalacion == "N" ? _tipoDucto : _tipoDuctoInstalado,
                                  "unidadesInstalado" : _unidadDucto
                                },
                                if(_confCuad.isNotEmpty)
                                  "campana": _confCuad,
                                if(_cuadricula.isNotEmpty)
                                  "cuadricula": _cuadricula,
                                if(_jsonCalculos.isNotEmpty)
                                  "calculos": { "resultados": _jsonCalculos }
                              };
                              String datosStr = jsonEncode(datos);

                              final guardado = await _cambiarDatos(datosStr);
                              if(guardado){
                                Fluttertoast.showToast(
                                  msg: "El proyecto se guardó satisfactoriamente",
                                  toastLength: Toast.LENGTH_SHORT,
                                  timeInSecForIosWeb: 4,
                                  gravity: ToastGravity.CENTER,
                                  webBgColor: "linear-gradient(to right, #266B1F, #98F58F)",
                                );
                              }else{
                                Fluttertoast.showToast(
                                  msg: "Hubo un error al intentar guardar el proyecto, intentelo de nuevo más tarde.",
                                  toastLength: Toast.LENGTH_SHORT,
                                  timeInSecForIosWeb: 4,
                                  gravity: ToastGravity.CENTER,
                                  webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                );
                              }

                              Navigator.pop(context);
                            },
                          ),
                        ),
                        const SizedBox(width: 16.0),
                        Expanded(
                          child: MaterialButton(
                            elevation: 4,
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            minWidth: (containerWidth/2)-32,
                            color: const Color(0xFFFF0000),
                            disabledColor: Colors.grey,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Image.asset(
                                  "continuar.png",
                                  width: 32.0,
                                ),
                                const SizedBox(width: 8.0),
                                const Text(
                                  "Continuar",
                                  style: TextStyle(
                                    fontFamily: "Helvetica Neue Black Cond",
                                    color: Colors.white,
                                    fontSize: 28.0,
                                  ),
                                )
                              ],
                            ),
                            onPressed: _continuarHabilitado
                                ? () async{
                              Map<String, Map<String, String>> info = {
                                "datos": {
                                  "tipoInstalacion" : _tipoInstalacion,
                                  "tipoCampana" : "Campana $_aplicacionCampana $_montajeCampana",
                                  "eqCocina" : _eqCocinaCampana,
                                  "longitud" : "$_valLongitud $_unidadLongitudes",
                                  "ancho" : "$_valAncho $_unidadLongitudes",
                                  "distCapt" : "$_valDistCap $_unidadLongitudes",
                                  "caudalEx" : "${(_caudalExtraccion * _factores[_eqCocinaCampana]!).round()} $_unidadCaudal",
                                  "cauInySug" : "${((_caudalExtraccion * _factores[_eqCocinaCampana]!) * 0.85).round()} $_unidadCaudal",
                                  "velAire" : _tipoInstalacion == "N" ? "$_velocidadAire" : "${_velRec.first}",
                                  "ductoCuadradoCM" : _tipoInstalacion == "N" ? "$_ductoCuadradoCM cm" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCuadradoIN" : _tipoInstalacion == "N" ? "$_ductoCuadradoIN in" : _tipoDuctoInstalado == "cuadrado" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoCircularCM" : _tipoInstalacion == "N" ? "$_ductoCircularCM cm" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} cm" : "0 cm",
                                  "ductoCircularIN" : _tipoInstalacion == "N" ? "$_ductoCircularIN in" : _tipoDuctoInstalado == "circular" ? "${_medidaDuctoController.text} in" : "0 in",
                                  "ductoSeleccion" : _tipoInstalacion == "N" ? _tipoDucto : _tipoDuctoInstalado,
                                  "unidadesInstalado" : _unidadDucto
                                },
                                if(_confCuad.isNotEmpty)
                                  "campana": _confCuad,
                                if(_cuadricula.isNotEmpty)
                                  "cuadricula": _cuadricula,
                                if(_jsonCalculos.isNotEmpty)
                                  "calculos": { "resultados": _jsonCalculos }
                              };

                              String infoStr = jsonEncode(info);

                              final accion = await Navigator.push(context, MaterialPageRoute(
                                builder: (context) => InterfazCuadriculaPage(
                                  info: infoStr,
                                  token: widget.token,
                                  idUsuario: widget.idUsuario,
                                  idProyecto: widget.idProyecto,
                                  finalizado: _finalizado,
                                  archpdf: widget.archpdf,
                                  noProyecto: widget.noProyecto,
                                ),
                              ));
                              if(accion == "inicio") Navigator.pop(context);
                            } : null,
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(
                    height: 32.0,
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }

  void _calcularDucto(){
    int caudalExtraccion = _unidadCaudal == "CFM" ? (_caudalExtraccion * _factores[_eqCocinaCampana]!).round() : ((_caudalExtraccion * _factores[_eqCocinaCampana]!) / 1.7).round();

    int ductoCuadradoCM = ((math.sqrt(((caudalExtraccion * 1.7)/(_velocidadAire/196.85))/3600))*100).round();
    int ductoCuadradoIN = (ductoCuadradoCM/2.54).round();

    int ductoCircularCM = ((math.pow((math.pow((ductoCuadradoCM*ductoCuadradoCM), 3)/(ductoCuadradoCM+ductoCuadradoCM)), 0.2))*1.265).round();
    int ductoCircularIN = (ductoCircularCM/2.54).round();

    _ductoCuadradoCM = ductoCuadradoCM;
    _ductoCuadradoIN = ductoCuadradoIN;
    _ductoCircularCM = ductoCircularCM;
    _ductoCircularIN = ductoCircularIN;
    _continuarHabilitado = true && _tipoDucto.isNotEmpty;
  }

  void _calcularVelocidad(){
    _velRec.clear();
    int caudalExtraccion = _unidadCaudal == "CFM" ? (_caudalExtraccion * _factores[_eqCocinaCampana]!).round() : ((_caudalExtraccion * _factores[_eqCocinaCampana]!) / 1.7).round();

    if(_tipoDuctoInstalado == "cuadrado" && _medidaDuctoController.text.isNotEmpty){
      double ladoSecCuad = _unidadDucto == "cm" ? double.parse(_medidaDuctoController.text) : double.parse(_medidaDuctoController.text) * 2.54;
      int velCalculada;

      try{
        velCalculada = ((3346450 * caudalExtraccion) / (3600 * math.pow(ladoSecCuad, 2))).round();
      }catch(e){
        velCalculada = 0;
      }

      String msg = "";
      List<int> velRec = [];

      if(velCalculada < _velocidadesAire.first - 50){
        msg = "La velocidad calculada ($velCalculada fpm) con el tamaño de ducto ingresado es inferior a la mínima requerida.";
        _msgVel = msg;
        _errorVel = true;
        _continuarHabilitado = false;
      }else if(velCalculada > _velocidadesAire.last + 50){
        msg = "La velocidad calculada ($velCalculada fpm) con el tamaño de ducto ingresado, excede a la máxima permitida.";
        _msgVel = msg;
        _errorVel = true;
        _continuarHabilitado = false;
      }else{
        _velocidadesAire.forEach((element) {
          int max = element + 50;
          int min = element - 50;

          if(velCalculada >= min && velCalculada < max){
            velRec.add(element);
          }
        });
        msg = "";
        velRec.forEach((element) {
          _velRec.add(element);
          msg += element >= 600 && element < 1000
              ? "Residencial ($element)"
              : element >= 1000 && element < 1600
              ? "Comercial ($element)"
              : element >= 1600 && element < 1800
              ? "Industrial ($element)"
              : element >= 1800 && element < 2200
              ? "Ideal Aire Grasa ($element)"
              : element >= 2000 && element < 3000
              ? "Adecuado Aire Grasa ($element)"
              : "Límite Superior Manejo Aire Grasa ($element)";
        });

        _msgVel = msg;
        _errorVel = false;
        _continuarHabilitado = true;
      }
    }else if(_tipoDuctoInstalado == "circular" && _medidaDuctoController.text.isNotEmpty){
      double ladoSecCir = _unidadDucto == "cm" ? double.parse(_medidaDuctoController.text) : double.parse(_medidaDuctoController.text) * 2.54;

      int velCalculada;

      try{
        velCalculada = ((334.645 * caudalExtraccion) / ((math.pow(((ladoSecCir * math.pow(2, 0.2)) / 126.5), 2) * 3600))).round();
      }catch(e){
        velCalculada = 0;
      }

      String msg = "";
      List<int> velRec = [];

      if(velCalculada < _velocidadesAire.first - 50){
        msg = "La velocidad calculada ($velCalculada fpm) con el tamaño de ducto ingresado es inferior a la mínima requerida.";
        _msgVel = msg;
        _errorVel = true;
        _continuarHabilitado = false;
      }else if(velCalculada > _velocidadesAire.last + 50){
        msg = "La velocidad calculada ($velCalculada fpm) con el tamaño de ducto ingresado, excede a la máxima permitida.";
        _msgVel = msg;
        _errorVel = true;
        _continuarHabilitado = false;
      }else{
        _velocidadesAire.forEach((element) {
          int max = element + 50;
          int min = element - 50;

          if(velCalculada >= min && velCalculada < max){
            velRec.add(element);
          }
        });
        msg = "";
        velRec.forEach((element) {
          _velRec.add(element);
          msg += element >= 600 && element < 1000
              ? "Residencial ($element)"
              : element >= 1000 && element < 1600
              ? "Comercial ($element)"
              : element >= 1600 && element < 1800
              ? "Industrial ($element)"
              : element >= 1800 && element < 2200
              ? "Ideal Aire Grasa ($element)"
              : element >= 2000 && element < 3000
              ? "Adecuado Aire Grasa ($element)"
              : "Límite Superior Manejo Aire Grasa ($element)";
        });

        _msgVel = msg;
        _errorVel = false;
        _continuarHabilitado = true;
      }
    }
  }

  void _calcularCaudal() => setState((){
    _continuarHabilitado = false;
    if(_aplicacionCampana != "" && _montajeCampana != "" && _valLongitud > 0 && _valAncho > 0 && _valDistCap > 0){
      double longitud = _unidadLongitudes == "m" ? _valLongitud : _valLongitud / 3.281;
      double ancho = _unidadLongitudes == "m" ? _valAncho : _valAncho / 3.281;
      double velocidad =  _velocidades["Campana $_aplicacionCampana"]!;
      double distanciaCapt = _unidadLongitudes == "m" ? _valDistCap : _valDistCap / 3.281;

      double caudal = _montajeCampana == "Adosada 1 Pared"
          ? (longitud+ancho+ancho)*velocidad*distanciaCapt
          : _montajeCampana == "Adosada 2 Paredes"
          ? (longitud+ancho)*velocidad*distanciaCapt
          : _montajeCampana == "Adosada 3 Paredes"
          ? (longitud)*velocidad*distanciaCapt
          : (longitud+ancho+longitud+ancho)*velocidad*distanciaCapt;

      double caudalCFM = caudal/_conversion;

      _caudalExtraccion = _unidadCaudal == "m³/h" ? caudal : caudalCFM;
      _velocidadAire = 2000;

      if(_tipoInstalacion == "N")
        _calcularDucto();
      else
        _calcularVelocidad();
    }
  });
}
