/**
 * FieldSettingsModal — Modal for editing checkout field properties.
 *
 * @package ArraySubsPro
 */
import React, { useState, useEffect } from "react";
import { __ } from "@wordpress/i18n";
import Form from "rc-field-form";
import FormBuilder from "@libs/form-builder";
import { X } from "lucide-react";
import {
  isBuiltinField,
  isLockedField,
  isLayoutField,
  generateFieldKey,
  COLUMN_WIDTHS,
  ORDER_INFO_PAYMENT_TYPE,
  ORDER_INFO_PAYMENT_KEY,
  createOrderInfoPaymentElement,
} from "./utils";

const FieldSettingsModal = ({
  field,
  allFields = [],
  onSave,
  onClose,
  isNew = false,
}) => {
  const [form] = Form.useForm();
  const [fieldType, setFieldType] = useState(field?.type || "text");
  const locked = isLockedField(field?.key);
  const builtin = isBuiltinField(field);
  const layout = isLayoutField(fieldType);
  const isOrderInfoPaymentElement = fieldType === ORDER_INFO_PAYMENT_TYPE;

  useEffect(() => {
    if (field) {
      form.setFieldsValue({
        label: field.label || "",
        key: field.key || "",
        type: field.type || "text",
        placeholder: field.placeholder || "",
        is_required: field.is_required || false,
        help_text: field.help_text || "",
        default_value: field.default_value || "",
        column_width: field.column_width || "full",
        css_class: field.css_class || "",
        ...flattenTypeSettings(field.type_settings),
        ...flattenVisibilityRules(field.visibility_rules),
      });
    }
  }, [field, form]);

  const flattenTypeSettings = (settings) => {
    if (!settings) return {};
    const flat = {};
    Object.entries(settings).forEach(([k, v]) => {
      flat[`ts_${k}`] = v;
    });
    return flat;
  };

  const flattenVisibilityRules = (rules) => {
    if (!rules || !rules.length) return {};
    return { visibility_rules: rules };
  };

  const handleLabelChange = () => {
    if (!isNew || builtin || isOrderInfoPaymentElement) return;
    const label = form.getFieldValue("label");
    const currentKey = form.getFieldValue("key");
    if (!currentKey || currentKey === generateFieldKey(label)) {
      form.setFieldsValue({ key: generateFieldKey(label) });
    }
  };

  const handleFinish = (values) => {
    const typeSettings = {};
    const cleaned = {};

    Object.entries(values).forEach(([k, v]) => {
      if (k.startsWith("ts_")) {
        typeSettings[k.substring(3)] = v;
      } else {
        cleaned[k] = v;
      }
    });

    const normalizedTypeSettings = { ...typeSettings };
    const normalizedOptions = normalizedTypeSettings.options || field?.options;

    if (
      Object.prototype.hasOwnProperty.call(normalizedTypeSettings, "multiple")
    ) {
      normalizedTypeSettings.multi = normalizedTypeSettings.multiple;
      delete normalizedTypeSettings.multiple;
    }

    if (
      typeof normalizedTypeSettings.allowed_types === "string" &&
      normalizedTypeSettings.allowed_types.trim()
    ) {
      normalizedTypeSettings.allowed_types =
        normalizedTypeSettings.allowed_types
          .split(",")
          .map((item) => item.trim())
          .filter(Boolean);
    }

    const normalizedContent = normalizedTypeSettings.content;
    const normalizedHeadingLevel = normalizedTypeSettings.heading_level;
    const normalizedAlertType = normalizedTypeSettings.alert_type;
    const normalizedDefaultColor = normalizedTypeSettings.default_color;

    if (
      Object.prototype.hasOwnProperty.call(normalizedTypeSettings, "options")
    ) {
      delete normalizedTypeSettings.options;
    }

    if (
      Object.prototype.hasOwnProperty.call(normalizedTypeSettings, "content")
    ) {
      delete normalizedTypeSettings.content;
    }

    if (
      Object.prototype.hasOwnProperty.call(
        normalizedTypeSettings,
        "heading_level",
      )
    ) {
      delete normalizedTypeSettings.heading_level;
    }

    if (
      Object.prototype.hasOwnProperty.call(normalizedTypeSettings, "alert_type")
    ) {
      delete normalizedTypeSettings.alert_type;
    }

    if (
      Object.prototype.hasOwnProperty.call(
        normalizedTypeSettings,
        "default_color",
      )
    ) {
      delete normalizedTypeSettings.default_color;
    }

    // Build the updated field.
    const updated = {
      ...field,
      ...cleaned,
      type: fieldType,
      type_settings: normalizedTypeSettings,
      is_custom: !builtin,
      options: Array.isArray(normalizedOptions)
        ? normalizedOptions.map((option) => ({
            ...option,
            image: option?.image || option?.image_url || "",
          }))
        : undefined,
      content: normalizedContent ?? field?.content,
      heading_level: normalizedHeadingLevel ?? field?.heading_level,
      alert_type: normalizedAlertType ?? field?.alert_type,
      is_builtin: builtin || false,
    };

    if (isOrderInfoPaymentElement) {
      Object.assign(
        updated,
        createOrderInfoPaymentElement({
          column_width: cleaned.column_width || field?.column_width || "full",
          css_class: cleaned.css_class || field?.css_class || "",
        }),
      );
      updated.key = ORDER_INFO_PAYMENT_KEY;
      updated.type_settings = {};
      updated.placeholder = "";
      updated.help_text = "";
      updated.default_value = "";
      updated.is_required = false;
    }

    if (!updated.default_value && normalizedDefaultColor) {
      updated.default_value = normalizedDefaultColor;
    }

    // Prefix custom field keys.
    if (
      isNew &&
      !builtin &&
      !isOrderInfoPaymentElement &&
      !updated.key.startsWith("_arraysubs_cf_")
    ) {
      updated.key = `_arraysubs_cf_${updated.key}`;
    }

    onSave(updated);
  };

  const baseFields = [
    {
      field: "Text",
      name: "label",
      label: __("Element Label", "arraysubs"),
      rules: [
        { required: true, message: __("Label is required", "arraysubs") },
      ],
      help: isOrderInfoPaymentElement
        ? __(
            "This special element renders WooCommerce's native order summary and payment area.",
            "arraysubs",
          )
        : __("The label displayed to customers.", "arraysubs"),
      onChange: handleLabelChange,
      ...(isOrderInfoPaymentElement ? { disabled: true } : {}),
    },
    {
      field: "Text",
      name: "key",
      label: __("Element Key", "arraysubs"),
      rules: [
        { required: true, message: __("Key is required", "arraysubs") },
        {
          pattern: /^[a-z0-9_]+$/,
          message: __(
            "Only lowercase letters, numbers and underscores",
            "arraysubs",
          ),
        },
      ],
      help: isOrderInfoPaymentElement
        ? __("This reserved key is managed automatically.", "arraysubs")
        : isNew
        ? __("Auto-generated from label. Used as meta key.", "arraysubs")
        : __("Cannot change after creation.", "arraysubs"),
      ...(builtin || !isNew || isOrderInfoPaymentElement
        ? { disabled: true }
        : {}),
    },
  ];

  if (!layout) {
    baseFields.push(
      {
        field: "Text",
        name: "placeholder",
        label: __("Placeholder", "arraysubs"),
      },
      {
        field: "Switch",
        name: "is_required",
        label: __("Required", "arraysubs"),
        help: __("Make this field mandatory at checkout.", "arraysubs"),
        ...(locked ? { disabled: true } : {}),
      },
      {
        field: "Text",
        name: "help_text",
        label: __("Help Text", "arraysubs"),
        help: __("Displayed below the field.", "arraysubs"),
      },
      {
        field: "Text",
        name: "default_value",
        label: __("Default Value", "arraysubs"),
      },
    );
  }

  baseFields.push(
    {
      field: "Select",
      name: "column_width",
      label: __("Column Width", "arraysubs"),
      data: COLUMN_WIDTHS,
    },
    {
      field: "Text",
      name: "css_class",
      label: __("CSS Class", "arraysubs"),
      help: __("Additional CSS class for styling.", "arraysubs"),
    },
  );

  // Type-specific settings.
  const typeFields = getTypeSpecificFields(fieldType);
  const visibilityFields = getVisibilityFields(allFields, field?.key);

  const formItems = [
    {
      field: "Card",
      children: [
        {
          field: "Title",
          text: __("Element Properties", "arraysubs"),
          heading: 4,
        },
        ...baseFields,
      ],
    },
  ];

  if (typeFields.length > 0) {
    formItems.push({
      field: "Card",
      children: [
        {
          field: "Title",
          text: __("Type Settings", "arraysubs"),
          heading: 4,
        },
        ...typeFields,
      ],
    });
  }

  if (!layout && visibilityFields.length > 0) {
    formItems.push({
      field: "Card",
      children: [
        {
          field: "Title",
          text: __("Conditional Visibility", "arraysubs"),
          heading: 4,
        },
        ...visibilityFields,
      ],
    });
  }

  return (
    <div className="arraysubs-cb-modal-overlay" onClick={onClose}>
      <div
        className="arraysubs-cb-modal"
        onClick={(e) => e.stopPropagation()}
        role="dialog"
        aria-label={
          isNew
            ? __("Add Element", "arraysubs")
            : __("Edit Element", "arraysubs")
        }
      >
        <div className="arraysubs-cb-modal__header">
          <h3>
            {isNew
              ? __("Add Element", "arraysubs")
              : __("Edit Element", "arraysubs")}
          </h3>
          <button
            type="button"
            className="arraysubs-cb-modal__close"
            onClick={onClose}
          >
            <X size={18} />
          </button>
        </div>

        <div className="arraysubs-cb-modal__body">
          <Form
            form={form}
            onFinish={handleFinish}
            layout="vertical"
            initialValues={{
              column_width: "full",
              is_required: false,
              type: field?.type || "text",
            }}
          >
            {isNew && !builtin && (
              <div className="arraysubs-cb-modal__type-select">
                <label>{__("Element Type", "arraysubs")}</label>
                <select
                  value={fieldType}
                  onChange={(e) => {
                    const nextType = e.target.value;

                    setFieldType(nextType);

                    if (nextType === ORDER_INFO_PAYMENT_TYPE) {
                      form.setFieldsValue({
                        label: __("Order Info and Payment", "arraysubs"),
                        key: ORDER_INFO_PAYMENT_KEY,
                        column_width: "full",
                      });
                    }
                  }}
                  className="arraysubs-cb-modal__type-dropdown"
                >
                  <optgroup label={__("Standard", "arraysubs")}>
                    <option value="text">{__("Text", "arraysubs")}</option>
                    <option value="number">{__("Number", "arraysubs")}</option>
                    <option value="email">{__("Email", "arraysubs")}</option>
                    <option value="phone">{__("Phone", "arraysubs")}</option>
                    <option value="select">{__("Select", "arraysubs")}</option>
                    <option value="multi_select">
                      {__("Multi Select", "arraysubs")}
                    </option>
                    <option value="textarea">
                      {__("Textarea", "arraysubs")}
                    </option>
                    <option value="checkbox">
                      {__("Checkbox", "arraysubs")}
                    </option>
                    <option value="toggle">{__("Toggle", "arraysubs")}</option>
                  </optgroup>
                  <optgroup label={__("Advanced", "arraysubs")}>
                    <option value="upload">{__("Upload", "arraysubs")}</option>
                    <option value="image_select">
                      {__("Image Select", "arraysubs")}
                    </option>
                    <option value="grid_select">
                      {__("Grid Select", "arraysubs")}
                    </option>
                    <option value="color_picker">
                      {__("Color Picker", "arraysubs")}
                    </option>
                    <option value="calendar">
                      {__("Calendar", "arraysubs")}
                    </option>
                    <option value="date">{__("Date", "arraysubs")}</option>
                    <option value="datetime">
                      {__("DateTime", "arraysubs")}
                    </option>
                    <option value="time">{__("Time", "arraysubs")}</option>
                    <option value="date_range">
                      {__("Date Range", "arraysubs")}
                    </option>
                  </optgroup>
                  <optgroup label={__("Layout", "arraysubs")}>
                    <option value="heading">
                      {__("Heading", "arraysubs")}
                    </option>
                    <option value="section">
                      {__("Section", "arraysubs")}
                    </option>
                    <option value="paragraph">
                      {__("Paragraph", "arraysubs")}
                    </option>
                    <option value="alert">{__("Alert", "arraysubs")}</option>
                    <option value={ORDER_INFO_PAYMENT_TYPE}>
                      {__("Order Info and Payment", "arraysubs")}
                    </option>
                  </optgroup>
                </select>
              </div>
            )}

            <FormBuilder formItems={formItems} form={form} />

            <div className="arraysubs-cb-modal__footer">
              <button type="button" className="button" onClick={onClose}>
                {__("Cancel", "arraysubs")}
              </button>
              <button type="submit" className="button button-primary">
                {isNew
                  ? __("Add Element", "arraysubs")
                  : __("Save Changes", "arraysubs")}
              </button>
            </div>
          </Form>
        </div>
      </div>
    </div>
  );
};

/**
 * Get FormBuilder fields for the current field type.
 */
function getTypeSpecificFields(type) {
  switch (type) {
    case "number":
      return [
        { field: "Number", name: "ts_min", label: __("Min", "arraysubs") },
        { field: "Number", name: "ts_max", label: __("Max", "arraysubs") },
        {
          field: "Number",
          name: "ts_step",
          label: __("Step", "arraysubs"),
          min: 0.01,
        },
      ];

    case "select":
    case "multi_select":
      return [
        {
          field: "Repeater",
          name: "ts_options",
          label: __("Options", "arraysubs"),
          addButtonText: __("Add Option", "arraysubs"),
          collapsible: false,
          items: [
            {
              field: "Text",
              name: "value",
              label: __("Value", "arraysubs"),
              rules: [{ required: true }],
            },
            {
              field: "Text",
              name: "label",
              label: __("Label", "arraysubs"),
              rules: [{ required: true }],
            },
          ],
        },
      ];

    case "image_select":
      return [
        {
          field: "Switch",
          name: "ts_multiple",
          label: __("Allow Multiple", "arraysubs"),
        },
        {
          field: "Repeater",
          name: "ts_options",
          label: __("Options", "arraysubs"),
          addButtonText: __("Add Option", "arraysubs"),
          items: [
            {
              field: "Text",
              name: "value",
              label: __("Value", "arraysubs"),
              rules: [{ required: true }],
            },
            {
              field: "Text",
              name: "label",
              label: __("Label", "arraysubs"),
              rules: [{ required: true }],
            },
            {
              field: "Text",
              name: "image_url",
              label: __("Image URL", "arraysubs"),
              rules: [{ required: true }],
            },
          ],
        },
      ];

    case "grid_select":
      return [
        {
          field: "Switch",
          name: "ts_multiple",
          label: __("Allow Multiple", "arraysubs"),
        },
        {
          field: "Select",
          name: "ts_columns",
          label: __("Columns", "arraysubs"),
          data: [
            { value: 2, label: "2" },
            { value: 3, label: "3" },
            { value: 4, label: "4" },
          ],
        },
        {
          field: "Repeater",
          name: "ts_options",
          label: __("Options", "arraysubs"),
          addButtonText: __("Add Option", "arraysubs"),
          items: [
            {
              field: "Text",
              name: "value",
              label: __("Value", "arraysubs"),
              rules: [{ required: true }],
            },
            {
              field: "Text",
              name: "label",
              label: __("Label", "arraysubs"),
              rules: [{ required: true }],
            },
            {
              field: "Text",
              name: "description",
              label: __("Description", "arraysubs"),
            },
          ],
        },
      ];

    case "upload":
      return [
        {
          field: "Number",
          name: "ts_max_file_size",
          label: __("Max File Size (MB)", "arraysubs"),
          min: 1,
          max: 100,
        },
        {
          field: "Number",
          name: "ts_max_file_count",
          label: __("Max Files", "arraysubs"),
          min: 1,
          max: 20,
        },
        {
          field: "Text",
          name: "ts_allowed_types",
          label: __("Allowed Types", "arraysubs"),
          help: __("Comma-separated, e.g. jpg,png,pdf", "arraysubs"),
        },
      ];

    case "date":
    case "calendar":
      return [
        {
          field: "Text",
          name: "ts_min_date",
          label: __("Min Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
        {
          field: "Text",
          name: "ts_max_date",
          label: __("Max Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
      ];

    case "datetime":
      return [
        {
          field: "Text",
          name: "ts_min_date",
          label: __("Min Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
        {
          field: "Text",
          name: "ts_max_date",
          label: __("Max Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
        {
          field: "Number",
          name: "ts_time_step",
          label: __("Time Step (minutes)", "arraysubs"),
          min: 1,
          max: 60,
        },
      ];

    case "time":
      return [
        {
          field: "Select",
          name: "ts_format",
          label: __("Format", "arraysubs"),
          data: [
            { value: "12h", label: __("12 Hour", "arraysubs") },
            { value: "24h", label: __("24 Hour", "arraysubs") },
          ],
        },
      ];

    case "date_range":
      return [
        {
          field: "Text",
          name: "ts_min_date",
          label: __("Min Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
        {
          field: "Text",
          name: "ts_max_date",
          label: __("Max Date", "arraysubs"),
          placeholder: "YYYY-MM-DD",
        },
        {
          field: "Number",
          name: "ts_max_span",
          label: __("Max Range (days)", "arraysubs"),
          min: 1,
        },
      ];

    case "heading":
      return [
        {
          field: "Select",
          name: "ts_heading_level",
          label: __("Heading Level", "arraysubs"),
          data: [
            { value: "h2", label: "H2" },
            { value: "h3", label: "H3" },
            { value: "h4", label: "H4" },
          ],
        },
      ];

    case "paragraph":
      return [
        {
          field: "TextArea",
          name: "ts_content",
          label: __("Content", "arraysubs"),
          rows: 4,
        },
      ];

    case "alert":
      return [
        {
          field: "Select",
          name: "ts_alert_type",
          label: __("Alert Type", "arraysubs"),
          data: [
            { value: "info", label: __("Info", "arraysubs") },
            { value: "success", label: __("Success", "arraysubs") },
            { value: "warning", label: __("Warning", "arraysubs") },
            { value: "error", label: __("Error", "arraysubs") },
          ],
        },
        {
          field: "TextArea",
          name: "ts_content",
          label: __("Message", "arraysubs"),
          rows: 3,
        },
      ];

    case "color_picker":
      return [
        {
          field: "Text",
          name: "ts_default_color",
          label: __("Default Color", "arraysubs"),
          placeholder: "#000000",
        },
      ];

    case "textarea":
      return [
        {
          field: "Number",
          name: "ts_rows",
          label: __("Rows", "arraysubs"),
          min: 2,
          max: 20,
        },
        {
          field: "Number",
          name: "ts_max_length",
          label: __("Max Length", "arraysubs"),
          min: 0,
        },
      ];

    case ORDER_INFO_PAYMENT_TYPE:
      return [];

    default:
      return [];
  }
}

/**
 * Get visibility rule fields for conditional display.
 */
function getVisibilityFields(allFields, currentKey) {
  const otherFields = allFields.filter(
    (f) => f.key !== currentKey && !isLayoutField(f.type),
  );

  if (!otherFields.length) return [];

  const fieldOptions = otherFields.map((f) => ({
    value: f.key,
    label: f.label || f.key,
  }));

  return [
    {
      field: "Repeater",
      name: "visibility_rules",
      label: __("Show When", "arraysubs"),
      addButtonText: __("Add Condition", "arraysubs"),
      collapsible: false,
      items: [
        {
          field: "Select",
          name: "field",
          label: __("Field", "arraysubs"),
          data: fieldOptions,
          rules: [{ required: true }],
        },
        {
          field: "Select",
          name: "operator",
          label: __("Operator", "arraysubs"),
          data: [
            { value: "is", label: __("Is", "arraysubs") },
            { value: "is_not", label: __("Is Not", "arraysubs") },
            { value: "contains", label: __("Contains", "arraysubs") },
            { value: "is_empty", label: __("Is Empty", "arraysubs") },
            { value: "is_not_empty", label: __("Is Not Empty", "arraysubs") },
          ],
        },
        {
          field: "Text",
          name: "value",
          label: __("Value", "arraysubs"),
        },
        {
          field: "Select",
          name: "logic",
          label: __("Logic", "arraysubs"),
          data: [
            { value: "AND", label: __("AND", "arraysubs") },
            { value: "OR", label: __("OR", "arraysubs") },
          ],
        },
      ],
    },
  ];
}

export default FieldSettingsModal;
