/**
 * LayoutEngine
 * Grid-based layout management system for CMS content assembly
 */

import React, { useState, useCallback, useMemo } from "react";
import {
  LayoutConfig,
  ContentZone,
  CMSComponent,
  RenderContext,
  GridConfig,
  ResponsiveConfig,
} from "../types/components.js";

// ========================================
// Types & Interfaces
// ========================================

export interface LayoutEngineProps {
  layout: LayoutConfig;
  zones: ContentZone[];
  context: RenderContext;
  editable?: boolean;
  onLayoutChange?: (layout: LayoutConfig) => void;
  onZoneUpdate?: (zoneId: string, updates: Partial<ContentZone>) => void;
  onComponentAdd?: (
    zoneId: string,
    component: CMSComponent,
    index?: number
  ) => void;
  onComponentRemove?: (zoneId: string, componentId: string) => void;
  _onComponentMove?: (
    fromZone: string,
    toZone: string,
    componentId: string,
    index?: number
  ) => void;
  className?: string;
  style?: React.CSSProperties;
}

export interface GridLayoutProps {
  config: GridConfig;
  zones: ContentZone[];
  _context: RenderContext;
  editable: boolean;
  _onZoneUpdate: (zoneId: string, updates: Partial<ContentZone>) => void;
  _onComponentAdd: (
    zoneId: string,
    component: CMSComponent,
    index?: number
  ) => void;
  _onComponentRemove: (zoneId: string, componentId: string) => void;
}

export interface ResponsiveLayoutProps {
  config: ResponsiveConfig;
  zones: ContentZone[];
  _context: RenderContext;
  editable: boolean;
  _onZoneUpdate: (zoneId: string, updates: Partial<ContentZone>) => void;
  _onComponentAdd: (
    zoneId: string,
    component: CMSComponent,
    index?: number
  ) => void;
  _onComponentRemove: (zoneId: string, componentId: string) => void;
}

export interface LayoutControlsProps {
  layout: LayoutConfig;
  onLayoutChange: (layout: LayoutConfig) => void;
  editable: boolean;
}

// ========================================
// Utility Functions
// ========================================

const generateLayoutStyles = (layout: LayoutConfig): React.CSSProperties => {
  const styles: React.CSSProperties = {
    display: layout.display || "block",
    position: layout.position || "static",
  };

  // Grid layout
  if (layout.display === "grid") {
    if (layout.gridTemplateColumns) {
      styles.gridTemplateColumns = layout.gridTemplateColumns;
    }
    if (layout.gridTemplateRows) {
      styles.gridTemplateRows = layout.gridTemplateRows;
    }
    if (layout.gridGap) {
      styles.gap = layout.gridGap;
    }
    if (layout.gridTemplate) {
      styles.gridTemplate = layout.gridTemplate;
    }
  }

  // Flexbox layout
  if (layout.display === "flex") {
    if (layout.flexDirection) {
      styles.flexDirection = layout.flexDirection;
    }
    if (layout.justifyContent) {
      styles.justifyContent = layout.justifyContent;
    }
    if (layout.alignItems) {
      styles.alignItems = layout.alignItems;
    }
    if (layout.flexWrap) {
      styles.flexWrap = layout.flexWrap;
    }
    if (layout.gap) {
      styles.gap = layout.gap;
    }
  }

  // Dimensions
  if (layout.width) styles.width = layout.width;
  if (layout.height) styles.height = layout.height;
  if (layout.maxWidth) styles.maxWidth = layout.maxWidth;
  if (layout.maxHeight) styles.maxHeight = layout.maxHeight;
  if (layout.minWidth) styles.minWidth = layout.minWidth;
  if (layout.minHeight) styles.minHeight = layout.minHeight;

  // Spacing
  if (layout.margin) {
    if (typeof layout.margin === "object") {
      if (layout.margin.all) styles.margin = layout.margin.all;
      if (layout.margin.x) {
        styles.marginLeft = layout.margin.x;
        styles.marginRight = layout.margin.x;
      }
      if (layout.margin.y) {
        styles.marginTop = layout.margin.y;
        styles.marginBottom = layout.margin.y;
      }
      if (layout.margin.top) styles.marginTop = layout.margin.top;
      if (layout.margin.right) styles.marginRight = layout.margin.right;
      if (layout.margin.bottom) styles.marginBottom = layout.margin.bottom;
      if (layout.margin.left) styles.marginLeft = layout.margin.left;
    } else {
      styles.margin = layout.margin;
    }
  }

  if (layout.padding) {
    if (typeof layout.padding === "object") {
      if (layout.padding.all) styles.padding = layout.padding.all;
      if (layout.padding.x) {
        styles.paddingLeft = layout.padding.x;
        styles.paddingRight = layout.padding.x;
      }
      if (layout.padding.y) {
        styles.paddingTop = layout.padding.y;
        styles.paddingBottom = layout.padding.y;
      }
      if (layout.padding.top) styles.paddingTop = layout.padding.top;
      if (layout.padding.right) styles.paddingRight = layout.padding.right;
      if (layout.padding.bottom) styles.paddingBottom = layout.padding.bottom;
      if (layout.padding.left) styles.paddingLeft = layout.padding.left;
    } else {
      styles.padding = layout.padding;
    }
  }

  return styles;
};

const getResponsiveStyles = (
  config: ResponsiveConfig,
  currentBreakpoint: string
): React.CSSProperties => {
  const breakpointConfig = config.breakpoints[currentBreakpoint];
  if (!breakpointConfig) return {};

  return generateLayoutStyles(breakpointConfig);
};

// ========================================
// Layout Controls Component
// ========================================

const LayoutControls: React.FC<LayoutControlsProps> = ({
  layout,
  onLayoutChange,
  editable,
}) => {
  const [showControls, setShowControls] = useState(false);

  const handleDisplayChange = useCallback(
    (display: string) => {
      onLayoutChange({
        ...layout,
        display: display as LayoutConfig["display"],
      });
    },
    [layout, onLayoutChange]
  );

  const handleGridColumnsChange = useCallback(
    (columns: string) => {
      onLayoutChange({
        ...layout,
        gridTemplateColumns: columns,
      });
    },
    [layout, onLayoutChange]
  );

  const handleGridRowsChange = useCallback(
    (rows: string) => {
      onLayoutChange({
        ...layout,
        gridTemplateRows: rows,
      });
    },
    [layout, onLayoutChange]
  );

  const handleGapChange = useCallback(
    (gap: string) => {
      onLayoutChange({
        ...layout,
        gap,
        gridGap: gap,
      });
    },
    [layout, onLayoutChange]
  );

  if (!editable) return null;

  return (
    <div style={{ position: "relative" }}>
      <button
        onClick={() => setShowControls(!showControls)}
        style={{
          position: "absolute",
          top: "8px",
          right: "8px",
          background: "#3b82f6",
          color: "white",
          border: "none",
          borderRadius: "4px",
          padding: "4px 8px",
          fontSize: "12px",
          cursor: "pointer",
          zIndex: 10,
        }}
      >
        ⚙️ Layout
      </button>

      {showControls && (
        <div
          style={{
            position: "absolute",
            top: "40px",
            right: "8px",
            background: "white",
            border: "1px solid #e5e7eb",
            borderRadius: "8px",
            padding: "16px",
            boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
            zIndex: 20,
            minWidth: "250px",
          }}
        >
          <h4
            style={{
              margin: "0 0 12px 0",
              fontSize: "14px",
              fontWeight: "bold",
            }}
          >
            Layout Settings
          </h4>

          <div style={{ marginBottom: "12px" }}>
            <label
              style={{
                display: "block",
                fontSize: "12px",
                marginBottom: "4px",
              }}
            >
              Display:
            </label>
            <select
              value={layout.display || "block"}
              onChange={(e) => handleDisplayChange(e.target.value)}
              style={{
                width: "100%",
                padding: "4px 8px",
                border: "1px solid #d1d5db",
                borderRadius: "4px",
                fontSize: "12px",
              }}
            >
              <option value="block">Block</option>
              <option value="flex">Flex</option>
              <option value="grid">Grid</option>
              <option value="inline">Inline</option>
              <option value="inline-block">Inline Block</option>
            </select>
          </div>

          {layout.display === "grid" && (
            <>
              <div style={{ marginBottom: "12px" }}>
                <label
                  style={{
                    display: "block",
                    fontSize: "12px",
                    marginBottom: "4px",
                  }}
                >
                  Grid Columns:
                </label>
                <input
                  type="text"
                  value={layout.gridTemplateColumns || ""}
                  onChange={(e) => handleGridColumnsChange(e.target.value)}
                  placeholder="repeat(3, 1fr)"
                  style={{
                    width: "100%",
                    padding: "4px 8px",
                    border: "1px solid #d1d5db",
                    borderRadius: "4px",
                    fontSize: "12px",
                  }}
                />
              </div>

              <div style={{ marginBottom: "12px" }}>
                <label
                  style={{
                    display: "block",
                    fontSize: "12px",
                    marginBottom: "4px",
                  }}
                >
                  Grid Rows:
                </label>
                <input
                  type="text"
                  value={layout.gridTemplateRows || ""}
                  onChange={(e) => handleGridRowsChange(e.target.value)}
                  placeholder="auto"
                  style={{
                    width: "100%",
                    padding: "4px 8px",
                    border: "1px solid #d1d5db",
                    borderRadius: "4px",
                    fontSize: "12px",
                  }}
                />
              </div>
            </>
          )}

          <div style={{ marginBottom: "12px" }}>
            <label
              style={{
                display: "block",
                fontSize: "12px",
                marginBottom: "4px",
              }}
            >
              Gap:
            </label>
            <input
              type="text"
              value={layout.gap || layout.gridGap || ""}
              onChange={(e) => handleGapChange(e.target.value)}
              placeholder="1rem"
              style={{
                width: "100%",
                padding: "4px 8px",
                border: "1px solid #d1d5db",
                borderRadius: "4px",
                fontSize: "12px",
              }}
            />
          </div>

          <button
            onClick={() => setShowControls(false)}
            style={{
              width: "100%",
              padding: "6px 12px",
              background: "#6b7280",
              color: "white",
              border: "none",
              borderRadius: "4px",
              fontSize: "12px",
              cursor: "pointer",
            }}
          >
            Close
          </button>
        </div>
      )}
    </div>
  );
};

// ========================================
// Grid Layout Component
// ========================================

const GridLayout: React.FC<GridLayoutProps> = ({
  config,
  zones,
  _context,
  editable,
  _onZoneUpdate,
  _onComponentAdd,
  _onComponentRemove,
}) => {
  const gridStyles = useMemo(
    () => ({
      display: "grid",
      gridTemplateColumns:
        config.columns || "repeat(auto-fit, minmax(250px, 1fr))",
      gridTemplateRows: config.rows || "auto",
      gap: config.gap || "1rem",
      gridTemplateAreas: config.areas
        ? `"${config.areas.join('" "')}"`
        : undefined,
    }),
    [config]
  );

  return (
    <div style={gridStyles}>
      {zones.map((zone) => (
        <div
          key={zone.id}
          style={{
            gridArea: zone.gridArea,
            minHeight: "100px",
            border: editable ? "2px dashed #e5e7eb" : "none",
            borderRadius: "8px",
            padding: "8px",
          }}
        >
          {/* ContentZone would be rendered here */}
          <div
            style={{
              background: "#f9fafb",
              padding: "1rem",
              borderRadius: "4px",
              textAlign: "center",
              color: "#6b7280",
            }}
          >
            Zone: {zone.name}
            <br />
            <small>{zone.components.length} components</small>
          </div>
        </div>
      ))}
    </div>
  );
};

// ========================================
// Responsive Layout Component
// ========================================

const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
  config,
  zones,
  _context,
  editable,
  _onZoneUpdate,
  _onComponentAdd,
  _onComponentRemove,
}) => {
  const [currentBreakpoint, setCurrentBreakpoint] = useState("desktop");

  const responsiveStyles = useMemo(() => {
    return getResponsiveStyles(config, currentBreakpoint);
  }, [config, currentBreakpoint]);

  const breakpointControls = useMemo(() => {
    if (!editable) return null;

    return (
      <div
        style={{
          marginBottom: "1rem",
          display: "flex",
          gap: "0.5rem",
          justifyContent: "center",
        }}
      >
        {Object.keys(config.breakpoints).map((breakpoint) => (
          <button
            key={breakpoint}
            onClick={() => setCurrentBreakpoint(breakpoint)}
            style={{
              padding: "0.5rem 1rem",
              border: "1px solid #d1d5db",
              borderRadius: "0.25rem",
              background:
                currentBreakpoint === breakpoint ? "#3b82f6" : "#ffffff",
              color: currentBreakpoint === breakpoint ? "#ffffff" : "#374151",
              cursor: "pointer",
              fontSize: "0.875rem",
            }}
          >
            {breakpoint}
          </button>
        ))}
      </div>
    );
  }, [config.breakpoints, currentBreakpoint, editable]);

  return (
    <div>
      {breakpointControls}
      <div style={responsiveStyles}>
        {zones.map((zone) => (
          <div
            key={zone.id}
            style={{
              minHeight: "100px",
              border: editable ? "2px dashed #e5e7eb" : "none",
              borderRadius: "8px",
              padding: "8px",
            }}
          >
            {/* ContentZone would be rendered here */}
            <div
              style={{
                background: "#f9fafb",
                padding: "1rem",
                borderRadius: "4px",
                textAlign: "center",
                color: "#6b7280",
              }}
            >
              Zone: {zone.name}
              <br />
              <small>{zone.components.length} components</small>
              <br />
              <small>Breakpoint: {currentBreakpoint}</small>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// ========================================
// Main LayoutEngine Component
// ========================================

export const LayoutEngine: React.FC<LayoutEngineProps> = ({
  layout,
  zones,
  context,
  editable = false,
  onLayoutChange,
  onZoneUpdate,
  onComponentAdd,
  onComponentRemove,
  _onComponentMove,
  className = "",
  style = {},
}) => {
  const handleZoneUpdate = useCallback(
    (zoneId: string, updates: Partial<ContentZone>) => {
      if (onZoneUpdate) {
        onZoneUpdate(zoneId, updates);
      }
    },
    [onZoneUpdate]
  );

  const handleComponentAdd = useCallback(
    (zoneId: string, component: CMSComponent, index?: number) => {
      if (onComponentAdd) {
        onComponentAdd(zoneId, component, index);
      }
    },
    [onComponentAdd]
  );

  const handleComponentRemove = useCallback(
    (zoneId: string, componentId: string) => {
      if (onComponentRemove) {
        onComponentRemove(zoneId, componentId);
      }
    },
    [onComponentRemove]
  );

  const handleLayoutChange = useCallback(
    (newLayout: LayoutConfig) => {
      if (onLayoutChange) {
        onLayoutChange(newLayout);
      }
    },
    [onLayoutChange]
  );

  const layoutStyles = useMemo(() => {
    return {
      ...generateLayoutStyles(layout),
      ...style,
    };
  }, [layout, style]);

  const renderLayout = useMemo(() => {
    // Grid-based layout
    if (layout.display === "grid" && layout.gridConfig) {
      return (
        <GridLayout
          config={layout.gridConfig}
          zones={zones}
          _context={context}
          editable={editable}
          _onZoneUpdate={handleZoneUpdate}
          _onComponentAdd={handleComponentAdd}
          _onComponentRemove={handleComponentRemove}
        />
      );
    }

    // Responsive layout
    if (layout.responsive) {
      return (
        <ResponsiveLayout
          config={layout.responsive}
          zones={zones}
          _context={context}
          editable={editable}
          _onZoneUpdate={handleZoneUpdate}
          _onComponentAdd={handleComponentAdd}
          _onComponentRemove={handleComponentRemove}
        />
      );
    }

    // Default layout
    return (
      <div style={layoutStyles}>
        {zones.map((zone) => (
          <div
            key={zone.id}
            style={{
              minHeight: "100px",
              border: editable ? "2px dashed #e5e7eb" : "none",
              borderRadius: "8px",
              padding: "8px",
              marginBottom: "1rem",
            }}
          >
            {/* ContentZone would be rendered here */}
            <div
              style={{
                background: "#f9fafb",
                padding: "1rem",
                borderRadius: "4px",
                textAlign: "center",
                color: "#6b7280",
              }}
            >
              Zone: {zone.name}
              <br />
              <small>{zone.components.length} components</small>
            </div>
          </div>
        ))}
      </div>
    );
  }, [
    layout,
    zones,
    context,
    editable,
    layoutStyles,
    handleZoneUpdate,
    handleComponentAdd,
    handleComponentRemove,
  ]);

  return (
    <div
      className={`cms-layout-engine ${className}`}
      style={{ position: "relative" }}
    >
      {editable && onLayoutChange && (
        <LayoutControls
          layout={layout}
          onLayoutChange={handleLayoutChange}
          editable={editable}
        />
      )}
      {renderLayout}
    </div>
  );
};

// ========================================
// Export Default
// ========================================

export default LayoutEngine;
