/**
 * Dropdown population methods for MenuUtils.
 * Handles populating and cascading dropdown menus for assets, suppliers, models, units, etc.
 */

const dropdownPopulation = {
  populateSmoothingMethods(configUrls, elements, node) {
    this.fetchData(configUrls.cloud.config, configUrls.local.config)
      .then((configData) => {
        const smoothingMethods =
          configData.smoothing?.smoothMethod?.rules?.values?.map(
            (o) => o.value
          ) || [];
        this.populateDropdown(
          elements.smoothMethod,
          smoothingMethods,
          node,
          "smooth_method"
        );
      })
      .catch((err) => {
        console.error("Error loading smoothing methods", err);
      });
  },

  populateInterpolationMethods(configUrls, elements, node) {
    this.fetchData(configUrls.cloud.config, configUrls.local.config)
      .then((configData) => {
        const interpolationMethods =
          configData?.interpolation?.type?.rules?.values.map((m) => m.value) ||
          [];
        this.populateDropdown(
          elements.interpolationMethodInput,
          interpolationMethods,
          node,
          "interpolationMethod"
        );

        // Find the selected method and use it to spawn 1 more field to fill in tension
        //const selectedMethod = interpolationMethods.find(m => m === node.interpolationMethod);
        this.initTensionToggles(elements, node);
      })
      .catch((err) => {
        console.error("Error loading interpolation methods", err);
      });
  },

  populateLogLevelOptions(logLevelSelect, configData, node) {
    // debug log level
    //console.log("Displaying configData => ", configData) ;

    const logLevels =
      configData?.general?.logging?.logLevel?.rules?.values?.map(
        (l) => l.value
      ) || [];

    //console.log("Displaying logLevels => ", logLevels);

    // Reuse your existing generic populateDropdown helper
    this.populateDropdown(logLevelSelect, logLevels, node.logLevel);
  },

  //cascade dropdowns for asset type, supplier, subType, model, unit
  fetchAndPopulateDropdowns(configUrls, elements, node) {
    this.fetchData(configUrls.cloud.config, configUrls.local.config)
      .then((configData) => {
        const assetType = configData.asset?.type?.default;
        const localSuppliersUrl = this.constructUrl(configUrls.local.taggcodeAPI,`${assetType}s`,"suppliers.json");
        const cloudSuppliersUrl = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/vendor/get_vendors.php");

        return this.fetchData(cloudSuppliersUrl, localSuppliersUrl)
          .then((supplierData) => {

            const suppliers = supplierData.map((supplier) => supplier.name);

            // Populate suppliers dropdown and set up its change handler
            return this.populateDropdown(
              elements.supplier,
              suppliers,
              node,
              "supplier",
              function (selectedSupplier) {
                if (selectedSupplier) {
                  this.populateSubTypes(configUrls, elements, node, selectedSupplier);
                }
              }
            );
          })
          .then(() => {
            // If we have a saved supplier, trigger subTypes population
            if (node.supplier) {
              this.populateSubTypes(configUrls, elements, node, node.supplier);
            }
          });
      })
      .catch((error) => {
        console.error("Error in initial dropdown population:", error);
      });
  },

  populateSubTypes(configUrls, elements, node, selectedSupplier) {

    this.fetchData(configUrls.cloud.config, configUrls.local.config)
      .then((configData) => {
        const assetType = configData.asset?.type?.default;
        const supplierFolder = this.constructUrl( configUrls.local.taggcodeAPI, `${assetType}s`, selectedSupplier );

        const localSubTypesUrl = this.constructUrl(supplierFolder, "subtypes.json");
        const cloudSubTypesUrl = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/product/get_subtypesFromVendor.php?vendor_name=" + selectedSupplier);

        return this.fetchData(cloudSubTypesUrl, localSubTypesUrl)
          .then((subTypeData) => {
            const subTypes = subTypeData.map((subType) => subType.name);

            return this.populateDropdown(
              elements.subType,
              subTypes,
              node,
              "subType",
              function (selectedSubType) {
                if (selectedSubType) {
                  // When subType changes, update both models and units
                  this.populateModels(
                    configUrls,
                    elements,
                    node,
                    selectedSupplier,
                    selectedSubType
                  );
                  this.populateUnitsForSubType(
                    configUrls,
                    elements,
                    node,
                    selectedSubType
                  );
                }
              }
            );
          })
          .then(() => {
            // If we have a saved subType, trigger both models and units population
            if (node.subType) {
              this.populateModels(
                configUrls,
                elements,
                node,
                selectedSupplier,
                node.subType
              );
              this.populateUnitsForSubType(configUrls, elements, node, node.subType);
            }
            //console.log("In fetch part of subtypes ");
            // Store all data from selected model
  /*           node["modelMetadata"] = modelData.find(
              (model) => model.name === node.model
            );
            console.log("Model Metadata: ", node["modelMetadata"]); */
          });
      })
      .catch((error) => {
        console.error("Error populating subtypes:", error);
      });
  },

  populateUnitsForSubType(configUrls, elements, node, selectedSubType) {
    // Fetch the units data
    this.fetchData(configUrls.cloud.units, configUrls.local.units)
      .then((unitsData) => {
        // Find the category that matches the subType name
        const categoryData = unitsData.units.find(
          (category) =>
            category.category.toLowerCase() === selectedSubType.toLowerCase()
        );

        if (categoryData) {
          // Extract just the unit values and descriptions
          const units = categoryData.values.map((unit) => ({
            value: unit.value,
            description: unit.description,
          }));

          // Create the options array with descriptions as labels
          const options = units.map((unit) => ({
            value: unit.value,
            label: `${unit.value} - ${unit.description}`,
          }));

          // Populate the units dropdown
          this.populateDropdown(
            elements.unit,
            options.map((opt) => opt.value),
            node,
            "unit"
          );

          // If there's no currently selected unit but we have options, select the first one
          if (!node.unit && options.length > 0) {
            node.unit = options[0].value;
            elements.unit.value = options[0].value;
          }
        } else {
          // If no matching category is found, provide a default % option
          const defaultUnits = [{ value: "%", description: "Percentage" }];
          this.populateDropdown(
            elements.unit,
            defaultUnits.map((unit) => unit.value),
            node,
            "unit"
          );
          console.warn(
            `No matching unit category found for subType: ${selectedSubType}`
          );
        }
      })
      .catch((error) => {
        console.error("Error fetching units:", error);
      });
  },

  populateModels(
    configUrls,
    elements,
    node,
    selectedSupplier,
    selectedSubType
  ) {

    this.fetchData(configUrls.cloud.config, configUrls.local.config)
      .then((configData) => {
        const assetType = configData.asset?.type?.default;
        // save assetType to fetch later
        node.assetType = assetType;

        const supplierFolder = this.constructUrl( configUrls.local.taggcodeAPI,`${assetType}s`,selectedSupplier);
        const subTypeFolder = this.constructUrl(supplierFolder, selectedSubType);
        const localModelsUrl = this.constructUrl(subTypeFolder, "models.json");
        const cloudModelsUrl  = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/product/get_product_models.php?vendor_name=" + selectedSupplier + "&product_subtype_name=" + selectedSubType);

        return this.fetchData(cloudModelsUrl, localModelsUrl).then((modelData) => {
          const models = modelData.map((model) => model.name); // use this to populate the dropdown

          // If a model is already selected, store its metadata immediately
          if (node.model) {
            node["modelMetadata"] = modelData.find((model) => model.name === node.model);
          }

          this.populateDropdown(elements.model, models, node, "model", (selectedModel) => {
            // Store only the metadata for the selected model
            node["modelMetadata"] = modelData.find((model) => model.name === selectedModel);
          });
          /*
          console.log('hello here I am:');
          console.log(node["modelMetadata"]);
  */
        });

      })
      .catch((error) => {
        console.error("Error populating models:", error);
      });
  },

  async populateDropdown(
    htmlElement,
    options,
    node,
    property,
    callback
  ) {
    this.generateHtml(htmlElement, options, node[property]);

    htmlElement.addEventListener("change", async (e) => {
      const newValue = e.target.value;
      console.log(`Dropdown changed: ${property} = ${newValue}`);
      node[property] = newValue;

      RED.nodes.dirty(true);
      if (callback) await callback(newValue); // Ensure async callback completion
    });
  },
};

module.exports = dropdownPopulation;
