import { RangeControl, SelectControl } from "@wordpress/components";
import { __ } from "@wordpress/i18n";
import ResponsiveControlV2 from "../../ResponsiveControlV2";
import StyledToggle from "../../StyledToggle";
import PanelBodyWithSync from "../../PanelBodyWithSync";
import { getEnabledBreakpoints } from "../../../../../core/breakpoints";

const getDefaultMargin = () => ({
  pc: { bulk: 0, bulkUnit: "px", top: 0, topUnit: "px", right: 0, rightUnit: "px", bottom: 0, bottomUnit: "px", left: 0, leftUnit: "px", useIndividual: false },
  md: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
  tb: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
  sp: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false }
});

const SpacingMarginSettingV8 = ({ 
  attributes, 
  setAttributes, 
  title, 
  initialOpen = false, 
  opened, 
  onToggle, 
  onSync,
  attrName = "marginV2",
  responsiveAttrName: customResponsiveAttrName,
  defaultValues,
  level = 2
}) => {
  const baseAttrName = attrName.replace(/V2$/, "");
  const responsiveAttrName = customResponsiveAttrName || `useResponsive${baseAttrName.charAt(0).toUpperCase() + baseAttrName.slice(1)}`;
  const responsiveEnabled = attributes[responsiveAttrName] !== undefined ? attributes[responsiveAttrName] : false;
  const enabledBreakpoints = getEnabledBreakpoints();

  const getDefault = () => defaultValues || getDefaultMargin();
  const marginData = attributes[attrName] || getDefault();

  const unitOptions = [
    { label: "px", value: "px" },
    { label: "%", value: "%" },
    { label: "vw", value: "vw" },
    { label: "vh", value: "vh" },
    { label: "auto", value: "auto" },
  ];

  const getStepForUnit = (unit) => {
    switch (unit) {
      case "%":
      case "vw":
      case "vh":
        return 0.5;
      default:
        return 1;
    }
  };

  const getMinMaxForUnit = (unit) => {
    switch (unit) {
      case "%":
      case "vw":
      case "vh":
        return { min: -100, max: 100 };
      default:
        return { min: -500, max: 500 };
    }
  };

  const positions = ["top", "right", "bottom", "left"];

  const handleMarginChange = (value, position = "bulk", currentTab = "pc") => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    if (responsiveEnabled) {
      newMargin[currentTab][position] = value;
    } else {
      enabledBreakpoints.forEach((bp) => {
        newMargin[bp][position] = value;
      });
    }
    setAttributes({ [attrName]: newMargin });
  };

  const handleUnitChange = (unit, position = "bulk", currentTab = "pc") => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    const unitKey = `${position}Unit`;
    if (responsiveEnabled) {
      newMargin[currentTab][unitKey] = unit;
      if (unit === "auto") {
        newMargin[currentTab][position] = 0;
      }
    } else {
      enabledBreakpoints.forEach((bp) => {
        newMargin[bp][unitKey] = unit;
        if (unit === "auto") {
          newMargin[bp][position] = 0;
        }
      });
    }
    setAttributes({ [attrName]: newMargin });
  };

  const handleBulkMarginChange = (value, currentTab = "pc") => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    if (responsiveEnabled) {
      newMargin[currentTab].bulk = value;
      positions.forEach((pos) => {
        newMargin[currentTab][pos] = value;
      });
    } else {
      enabledBreakpoints.forEach((bp) => {
        newMargin[bp].bulk = value;
        positions.forEach((pos) => {
          newMargin[bp][pos] = value;
        });
      });
    }
    setAttributes({ [attrName]: newMargin });
  };

  const handleBulkUnitChange = (unit, currentTab = "pc") => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    if (responsiveEnabled) {
      newMargin[currentTab].bulkUnit = unit;
      positions.forEach((pos) => {
        newMargin[currentTab][`${pos}Unit`] = unit;
      });
      if (unit === "auto") {
        newMargin[currentTab].bulk = 0;
        positions.forEach((pos) => {
          newMargin[currentTab][pos] = 0;
        });
      }
    } else {
      enabledBreakpoints.forEach((bp) => {
        newMargin[bp].bulkUnit = unit;
        positions.forEach((pos) => {
          newMargin[bp][`${pos}Unit`] = unit;
        });
        if (unit === "auto") {
          newMargin[bp].bulk = 0;
          positions.forEach((pos) => {
            newMargin[bp][pos] = 0;
          });
        }
      });
    }
    setAttributes({ [attrName]: newMargin });
  };

  const handleIndividualToggle = (value, currentTab = "pc") => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    if (responsiveEnabled) {
      newMargin[currentTab].useIndividual = value;
      if (value) {
        const bulkValue = marginData[currentTab].bulk;
        const bulkUnit = marginData[currentTab].bulkUnit || "px";
        positions.forEach((pos) => {
          newMargin[currentTab][pos] = bulkValue;
          newMargin[currentTab][`${pos}Unit`] = bulkUnit;
        });
      } else {
        const bulkValue = marginData[currentTab].bulk;
        const bulkUnit = marginData[currentTab].bulkUnit || "px";
        positions.forEach((pos) => {
          newMargin[currentTab][pos] = bulkValue;
          newMargin[currentTab][`${pos}Unit`] = bulkUnit;
        });
      }
    } else {
      enabledBreakpoints.forEach((bp) => {
        newMargin[bp].useIndividual = value;
      });
      const bulkValue = marginData.pc.bulk;
      const bulkUnit = marginData.pc.bulkUnit || "px";
      enabledBreakpoints.forEach((bp) => {
        positions.forEach((pos) => {
          newMargin[bp][pos] = bulkValue;
          newMargin[bp][`${pos}Unit`] = bulkUnit;
        });
      });
    }
    setAttributes({ [attrName]: newMargin });
  };

  const handleResponsiveToggle = (value) => {
    const newMargin = JSON.parse(JSON.stringify(marginData));
    const pcData = newMargin.pc || {};
    enabledBreakpoints.forEach((bp) => {
      if (bp !== "pc") {
        Object.keys(pcData).forEach((key) => {
          newMargin[bp][key] = pcData[key];
        });
      }
    });
    setAttributes({ [attrName]: newMargin, [responsiveAttrName]: value });
  };

  const renderMarginControls = (tabName) => {
    const tabData = marginData[tabName] || getDefault().pc;
    const useIndividual = tabData.useIndividual;
    const getUnit = (position = "bulk") => tabData[`${position}Unit`] || "px";

    return (
      <>
        <div style={{ marginBottom: "16px", padding: "0 " }}>
          <StyledToggle label={__("Use Individual Settings", "zenblocks")} checked={useIndividual} onChange={(value) => handleIndividualToggle(value, tabName)} />
        </div>

        <div style={{ padding: "0 " }}>
          {useIndividual ? (
            positions.map((pos) => (
              <div key={pos} className="spacing-margin-control">
                <div className="spacing-margin-label">{`${__("Margin", "zenblocks")} ${pos.charAt(0).toUpperCase() + pos.slice(1)}`}</div>
                <div className="spacing-margin-controls">
                  {getUnit(pos) !== "auto" ? (
                    <RangeControl value={tabData[pos] === "" ? 0 : tabData[pos]} onChange={(value) => handleMarginChange(value, pos, tabName)} min={getMinMaxForUnit(getUnit(pos)).min} max={getMinMaxForUnit(getUnit(pos)).max} step={getStepForUnit(getUnit(pos))} />
                  ) : (
                    <div className="auto-margin-indicator">
                      <p>{__("Auto margin enabled", "zenblocks")}</p>
                    </div>
                  )}
                  <SelectControl value={getUnit(pos)} options={unitOptions} onChange={(unit) => handleUnitChange(unit, pos, tabName)} className="unit-select" />
                </div>
              </div>
            ))
          ) : (
            <div className="spacing-margin-control">
              <div className="spacing-margin-label">{__("Margin", "zenblocks")}</div>
              <div className="spacing-margin-controls">
                {getUnit() !== "auto" ? (
                  <RangeControl value={tabData.bulk === "" ? 0 : tabData.bulk} onChange={(value) => handleBulkMarginChange(value, tabName)} min={getMinMaxForUnit(getUnit()).min} max={getMinMaxForUnit(getUnit()).max} step={getStepForUnit(getUnit())} />
                ) : (
                  <div className="auto-margin-indicator">
                    <p>{__("Auto margin enabled", "zenblocks")}</p>
                  </div>
                )}
                <SelectControl value={getUnit()} options={unitOptions} onChange={(unit) => handleBulkUnitChange(unit, tabName)} className="unit-select" />
              </div>
            </div>
          )}
        </div>

        <style>
          {`
          .spacing-margin-control .components-base-control {
            padding-top: 0 !important;
            margin-bottom: 0.5em !important;
          }
          .spacing-margin-control .components-base-control .components-base-control {
            padding-left: 0 !important;
            padding-right: 0 !important;
          }
          .spacing-margin-label {
            margin-bottom: 8px;
          }
          .spacing-margin-controls {
            display: flex;
            align-items: flex-start;
          }
          .spacing-margin-controls .unit-select {
            flex: 0 0 70px;
            margin-left: 8px;
          }
          .spacing-margin-controls .components-range-control {
            flex: 1;
          }
          .auto-margin-indicator {
            background-color: #f0f0f0;
            padding: 8px 12px;
            border-radius: 4px;
            margin-right: 10px;
            flex: 1;
          }
          .auto-margin-indicator p {
            margin: 0;
            font-style: italic;
          }
          `}
        </style>
      </>
    );
  };

  return (
    <PanelBodyWithSync title={title || __("Margin", "zenblocks")} initialOpen={initialOpen} opened={opened} onToggle={onToggle} onSync={onSync} className="zenblocks-nested-panel" level={level} panelType="settings" panelName="spacing-margin">
      <div className="zenblocks-inspector-spacing-margin">
        <ResponsiveControlV2
          initialOpen={true}
          enableResponsiveToggle={true}
          responsiveEnabled={responsiveEnabled}
          onResponsiveToggle={handleResponsiveToggle}
          attributes={attributes}
          setAttributes={setAttributes}
          syncAttributeName={responsiveAttrName}
        >
          {(tabName) => renderMarginControls(tabName)}
        </ResponsiveControlV2>
      </div>
    </PanelBodyWithSync>
  );
};

export const getMarginValueV8 = (attributes, attrName = "marginV2", device = "pc", position = "bulk") => {
  const marginData = attributes[attrName];
  if (!marginData) return "0px";

  const enabledBreakpoints = getEnabledBreakpoints();
  const currentIndex = enabledBreakpoints.indexOf(device);

  for (let i = currentIndex; i >= 0; i--) {
    const bp = enabledBreakpoints[i];
    const bpData = marginData[bp];
    if (bpData) {
      const unit = bpData[`${position}Unit`] || "px";
      if (unit === "auto") return "auto";
      
      const value = bpData[position];
      if (value !== "" && value !== undefined && value !== null) {
        return `${value}${unit}`;
      }
    }
  }

  return "0px";
};

export const getDirectMarginV8 = (attributes, attrName = "marginV2", device = "pc", position = "bulk") => {
  const marginData = attributes[attrName];
  if (!marginData || !marginData[device]) return undefined;

  const unit = marginData[device][`${position}Unit`] || "px";
  if (unit === "auto") return "auto";

  const value = marginData[device][position];

  if (value !== "" && value !== undefined && value !== null) {
    return `${value}${unit}`;
  }

  return undefined;
};

export default SpacingMarginSettingV8;
