import React, { useContext, useRef, useCallback, useEffect } from 'react';
import appDebug from "../utils/appDebug";
import { AppConfig } from "../config/AppConfig";
import { StoreContext } from '../utils/store';
import { updateItem } from '../utils/utils';
import md5 from "md5";

const Fieldsets = {
  main: 'Main',
  advanced: 'Advanced'
}

const MenuItemEditorForm = (props) => {

  const store = useContext(StoreContext);
  
  const { forItemType, item, origItem, fieldEditEventHandler } = props;

  const editableFields = useRef([
    { 'name': 'object_id', 'key': 'post_object_id', 'label': 'Page/Post ID', 'input_type': 'none', 'show_for_item_type': ['post_type'], fieldset: Fieldsets.main },
    { 'name': 'object_title', 'key': 'post_object_title', 'label': 'Page/Post Title', 'input_type': 'none', 'show_for_item_type':['post_type'], fieldset: Fieldsets.main },
    { 'name': 'object_id', 'key': 'taxonomy_object_id', 'label': 'Category ID', 'input_type': 'none', 'show_for_item_type': ['taxonomy'], fieldset: Fieldsets.main },
    { 'name': 'object_title', 'key': 'taxonomy_object_title', 'label': 'Category Title', 'input_type': 'none', 'show_for_item_type':['taxonomy'], fieldset: Fieldsets.main },
    { 'name': 'title', 'key': 'title', 'label': 'Menu Item Title', 'input_type': 'text', fieldset: Fieldsets.main },
    { 'name': 'description', 'key': 'description', 'label': 'Description', 'input_type': 'text', fieldset: Fieldsets.advanced  },
    { 'name': 'title_attr', 'key': 'title_attr', 'label': 'Title Attribute', 'input_type': 'text', fieldset: Fieldsets.advanced },
    { 'name': 'target', 'key': 'target', 'label': 'Open in New Window', 'input_type': 'checkbox', 'value_unset': "", 'value': '_blank', fieldset: Fieldsets.advanced },
    { 'name': 'classes', 'key': 'classes', 'label': 'CSS Classes', 'input_type': 'text', 'editable_data_type': 'string', fieldset: Fieldsets.advanced },
    { 'name': 'url', 'key': 'url', 'label': 'URL', 'input_type': 'text', 'editable_data_type': 'string', fieldset: Fieldsets.main, 'show_for_item_type': ['custom'] }
  ]);

  useEffect(
    () => {
      if (!store.isSaving) {
        checkEditsAgainstOriginalItem();
      }
    }, [store.menuItems, origItem, item]
  );

  const collectItemFieldValues = (item) => {

    let ret = {};

    for(const fieldData of editableFields.current) {
      ret[fieldData.key] = getItemFieldValue(item, fieldData);
    }
    
    return ret;

  }

  const checkEditsAgainstOriginalItem = () => {

    if (origItem && origItem.current != null) {

      const origValues = collectItemFieldValues(origItem.current);
      const curValues = collectItemFieldValues(item);

      const origHash = md5(JSON.stringify(origValues));
      const curHash = md5(JSON.stringify(curValues));
      
      if (origHash == curHash) {
        appDebug(AppConfig.debugCategoryDefault, "item fully reverted");
        store.unMarkChangedItem(item, store.menuItemChangeTypes.edit);
      }
      else {
        store.markChangedItem(item, store.menuItemChangeTypes.edit);
      }
    }
  }

  const getFieldsetFields = useCallback((fieldset) => {

    const fields = editableFields.current.filter(
      fieldData => (fieldData.fieldset == Fieldsets[fieldset]) && (!fieldData?.show_for_item_type || fieldData?.show_for_item_type.includes(item.type))
    );

    return fields;
  }, [editableFields.current, item.type]);
  
  const getEditableFieldValue = (item, fieldData) => {

    if (origItem && origItem.current != null) {
      if (fieldData.show_for_item_type && (origItem.current.type != fieldData.show_for_item_type) && !store.itemWasChanged(item)) {
        return null;
      }
    }

    let retValue = getItemFieldValue(item, fieldData);

    if (fieldData.editable_data_type == 'string' && Array.isArray(retValue)) {
      retValue = retValue.join(" ");
    }
    else if (fieldData.input_type == 'checkbox') {
      retValue = fieldData.value;
    }
    
    return retValue;

  }

  const getItemFieldValue = (item, fieldData) => {

    const fieldName = fieldData.name;

    if (fieldName) {
      const ret = typeof(item[fieldName]) != 'undefined' ? item[fieldName] : null;
      appDebug(AppConfig.debugCategoryDefault, "Item field value for ", fieldName, ret);
      return ret;
    }

    return null;

  }

  const handleEditableFieldKeyDown = (e) => {
    
    return fieldEditEventHandler(e);
  }

  const handleEditableFieldChange = (e) => {
    
    const fieldKey = e.target?.getAttribute('data-field-key') ?? null;

    if (!fieldKey) {
      appDebug(AppConfig.debugCategoryDefault, "Invalid or missing field key when editing");
    }
    else {
      const fieldDataIndex = editableFields.current.findIndex(fieldData => fieldData.key == fieldKey);
      
      if (fieldDataIndex <= -1) {
        appDebug(AppConfig.debugCategoryDefault, `Could not find key ${fieldKey} in editableFields`);
      }
      else {
        const fieldData = editableFields.current[fieldDataIndex];

        if (fieldData.storage_type == 'array') {
          const newValues = e.target?.value?.toString().split(" "); 
          item[fieldKey] = newValues;
        }
        else {
          let value;
          
          if (fieldData.input_type == 'checkbox') {
            if (!e.target.checked) {
              value = typeof(fieldData.value_unset) != 'undefined' ? fieldData.value_unset : null;
            }
            else {
              value = fieldData.value;
            }
          }
          else {
            value = e.target.value;
          }
          
          item[fieldKey] = value;
        }
  
        store.setMenuItems((updateItem(store.menuItems, item)));
        store.markChangedItem(item, store.menuItemChangeTypes.edit);
        appDebug(AppConfig.debugCategoryDefault, 'updated items after field change', store.menuItems);
      }
    }
  }

  return (
  <div className="mmu-editor-form">
    <div className="mmu-editor-form-fields">
      {Object.keys(Fieldsets).map (
        (fieldsetKey) => {

          let retVal = [];
          
          if (fieldsetKey != 'main') retVal.push();
          
          retVal.push(
            getFieldsetFields(fieldsetKey).map(
              (fieldData) => {

                let itemFieldValue = getItemFieldValue(item, fieldData);
                let editableFieldValue = getEditableFieldValue(item, fieldData);
                let checked = (fieldData.input_type == 'checkbox' && itemFieldValue == editableFieldValue) ? true : false;
                let label = fieldData.label;

                {/* if (item.type != forItemType) {
                  editableFieldValue = "";
                  checked = false;
                } */}

                return (
                  <div key={fieldData.key} className="mmu-editor-field">
                    <label htmlFor={"mmu-input-" + forItemType + '-' + fieldData.key}>{fieldData.label}</label>
                    {fieldData.input_type != 'none'
                    ?
                    <input data-field-key={fieldData.key} id={"mmu-input-" + forItemType + '-' + fieldData.key} type={fieldData.input_type} name={fieldData.name} defaultChecked={checked} onKeyDown={handleEditableFieldKeyDown} onChange={handleEditableFieldChange} defaultValue={editableFieldValue} />
                    : 
                    <span className="mmu-editor-field-value-static">{editableFieldValue}</span>
                    }
                  </div>
                )
              }
            )
          );

          return fieldsetKey != 'main' ? (<details><summary>{Fieldsets[fieldsetKey]}</summary><div className="mmu-editor-form-fields">{retVal}</div></details>) : retVal;
        }
      )}
    </div>
  </div>
  );
}

export default MenuItemEditorForm;