/*
 * Copyright 2023 Adobe. All rights reserved.
 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
 * OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

import { JSDOM } from 'jsdom';
import HtmlFormToEDForm from './transform/HtmlFormToEDForm.js';
import getFormStats, { santizieName } from './support/util.js';
import { FormType } from './support/type.js';
import EDFormToAF2 from './transform/EDFormToAF2.js';

const tranformer = new HtmlFormToEDForm();
const edToAF = new EDFormToAF2();

async function getAFDef(path, options) {
  let formDef = null;
  const { url, reqHeaders } = options;
  if (path && url) {
    try {
      const resp = await fetch(new URL(`${path}.model.json`, url), {
        headers: {
          ...reqHeaders,
          'content-type': 'application/json',
        },
      });
      if (resp.ok) {
        formDef = await resp.json();
      }
    } catch (e) {
      console.warn(`Error fetching form def for ${path}`, e);
    }
  }
  return formDef;
}

function isAF(formElement) {
  return formElement?.parentElement?.className.includes('cmp-adaptiveform-container')
  && formElement?.dataset.cmpPath;
}

export function getFormDef(formElement, options = {}, output = FormType.HEADLESS_FORM, name = '') {
  const fields = tranformer.getFormDefFromHTMLForm(formElement, options);
  const formName = name || formElement?.id || formElement?.name;
  if (output === FormType.HEADLESS_FORM) {
    const af = edToAF.transform({ data: fields }, { name: formName });
    return af;
  } else {
    return { name: formName, data: fields };
  }
}

export async function getAllForms(content, options = {}, output = FormType.HEADLESS_FORM) {
  const { includeStats = false } = options;
  const dom = new JSDOM(content);
  const document = dom?.window?.document;
  const forms = [];
  if (document) {
    const formElements = document.querySelectorAll('form');
    for (let index = 0; index < formElements.length; index += 1) {
      let formDef;
      const formElement = formElements[index];
      const name = formElement?.id || formElement?.name || `Form_${index + 1}`;
      if (isAF(formElement)) {
        const path = formElement?.dataset?.cmpPath;
        formDef = await getAFDef(path, options);
      }
      // in case form def is not found generate from HTML.
      if (!formDef) {
        formDef = getFormDef(formElement, options, output, name);
      }
      const stats = includeStats ? getFormStats(name, formDef.data, formElement.dataset) : null;
      const result = includeStats ? { ...formDef, stats } : formDef;
      forms.push(result);
    }
  }
  return forms;
}
