import React, { useCallback } from 'react';
import { useEditor } from '@craftjs/core';
import {
  TEXT_COLORS,
  BG_COLORS,
  SPACING_PRESETS,
  RADIUS_PRESETS,
} from '../../../constants/presets';
import {
  SectionLabel,
  ColorSwatchGrid,
  PresetButtonGrid,
  CollapsibleSection,
  ColorPickerField,
  ArrayPropEditor,
  labelStyle,
  inputStyle,
  smallInputStyle,
  sectionGap,
} from './shared';

/* ---------- SMART GENERIC PROPS EDITOR (Fallback) ---------- */
export const GenericPropsEditor: React.FC<{ selectedId: string; nodeProps: Record<string, any>; typeName: string }> = ({
  selectedId, nodeProps, typeName,
}) => {
  const { actions } = useEditor();

  const SKIP_PROPS = new Set(['style', 'children', 'cssId', 'cssClass']);

  const setPropValue = useCallback((key: string, value: any) => {
    actions.setProp(selectedId, (props: any) => { props[key] = value; });
  }, [actions, selectedId]);

  const setStyleValue = useCallback((key: string, value: string) => {
    actions.setProp(selectedId, (props: any) => {
      props.style = { ...props.style, [key]: value };
    });
  }, [actions, selectedId]);

  // Categorize all props
  const allProps = Object.entries(nodeProps).filter(([key]) => !SKIP_PROPS.has(key));
  const colorProps = allProps.filter(([key, val]) => typeof val === 'string' && /color/i.test(key));
  const boolProps = allProps.filter(([_, val]) => typeof val === 'boolean');
  const numberProps = allProps.filter(([key, val]) => typeof val === 'number' && !/color/i.test(key));
  const stringProps = allProps.filter(([key, val]) => typeof val === 'string' && !/color/i.test(key));
  const arrayProps = allProps.filter(([_, val]) => Array.isArray(val));

  const style = nodeProps.style || {};

  return (
    <>
      {/* String props */}
      {stringProps.length > 0 && (
        <CollapsibleSection title="Properties">
          {stringProps.map(([key, val]) => {
            const humanLabel = key.replace(/([A-Z])/g, ' $1').trim();
            const isLong = String(val).length > 60 || key === 'description' || key === 'text' || key === 'content';
            return (
              <div key={key} style={sectionGap}>
                <label style={labelStyle}>{humanLabel}</label>
                {isLong ? (
                  <textarea value={String(val)} onChange={(e) => setPropValue(key, e.target.value)} rows={3} style={{ ...inputStyle, resize: 'vertical' }} />
                ) : (
                  <input type="text" value={String(val)} onChange={(e) => setPropValue(key, e.target.value)} style={inputStyle} />
                )}
              </div>
            );
          })}
        </CollapsibleSection>
      )}

      {/* Number props */}
      {numberProps.length > 0 && (
        <CollapsibleSection title="Numbers" defaultOpen={true}>
          {numberProps.map(([key, val]) => (
            <div key={key} style={sectionGap}>
              <label style={labelStyle}>{key.replace(/([A-Z])/g, ' $1').trim()}</label>
              <input type="number" value={val as number} onChange={(e) => setPropValue(key, parseFloat(e.target.value) || 0)} style={inputStyle} />
            </div>
          ))}
        </CollapsibleSection>
      )}

      {/* Boolean props */}
      {boolProps.length > 0 && (
        <CollapsibleSection title="Options" defaultOpen={true}>
          {boolProps.map(([key, val]) => (
            <div key={key} style={sectionGap}>
              <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
                <input type="checkbox" checked={val as boolean} onChange={(e) => setPropValue(key, e.target.checked)} />
                {key.replace(/([A-Z])/g, ' $1').trim()}
              </label>
            </div>
          ))}
        </CollapsibleSection>
      )}

      {/* Color props */}
      {colorProps.length > 0 && (
        <CollapsibleSection title="Colors">
          {colorProps.map(([key, val]) => (
            <ColorPickerField key={key} label={key.replace(/([A-Z])/g, ' $1').trim()} value={String(val)} onChange={(v) => setPropValue(key, v)} />
          ))}
        </CollapsibleSection>
      )}

      {/* Array props */}
      {arrayProps.map(([key, items]) => {
        const arrayItems = items as any[];
        const sampleItem = arrayItems[0] || {};
        const itemFields = typeof sampleItem === 'object' && sampleItem !== null ? Object.keys(sampleItem) : [];

        return (
          <CollapsibleSection key={key} title={key.replace(/([A-Z])/g, ' $1').trim()}>
            <ArrayPropEditor
              selectedId={selectedId}
              propKey={key}
              items={arrayItems}
              renderItem={(item: any, index: number) => {
                if (typeof item !== 'object' || item === null) {
                  return (
                    <input
                      type="text"
                      value={String(item)}
                      onChange={(e) => {
                        actions.setProp(selectedId, (props: any) => {
                          const updated = [...(props[key] || [])];
                          updated[index] = e.target.value;
                          props[key] = updated;
                        });
                      }}
                      style={smallInputStyle}
                    />
                  );
                }
                return (
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                    {itemFields.map((field) => {
                      const fieldVal = item[field];
                      if (typeof fieldVal === 'boolean') {
                        return (
                          <label key={field} style={{ fontSize: 10, color: '#71717a', display: 'flex', alignItems: 'center', gap: 4, cursor: 'pointer' }}>
                            <input type="checkbox" checked={fieldVal} onChange={(e) => {
                              actions.setProp(selectedId, (props: any) => {
                                const updated = [...(props[key] || [])];
                                updated[index] = { ...updated[index], [field]: e.target.checked };
                                props[key] = updated;
                              });
                            }} />
                            {field}
                          </label>
                        );
                      }
                      if (typeof fieldVal === 'number') {
                        return (
                          <div key={field}>
                            <label style={{ fontSize: 9, color: '#52525b', textTransform: 'capitalize' }}>{field}</label>
                            <input type="number" value={fieldVal} onChange={(e) => {
                              actions.setProp(selectedId, (props: any) => {
                                const updated = [...(props[key] || [])];
                                updated[index] = { ...updated[index], [field]: parseFloat(e.target.value) || 0 };
                                props[key] = updated;
                              });
                            }} style={smallInputStyle} />
                          </div>
                        );
                      }
                      if (/color/i.test(field) && typeof fieldVal === 'string') {
                        return (
                          <div key={field} style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                            <label style={{ fontSize: 9, color: '#52525b', textTransform: 'capitalize', width: 50 }}>{field}</label>
                            <input type="color" value={fieldVal || '#000000'} onChange={(e) => {
                              actions.setProp(selectedId, (props: any) => {
                                const updated = [...(props[key] || [])];
                                updated[index] = { ...updated[index], [field]: e.target.value };
                                props[key] = updated;
                              });
                            }} style={{ width: 24, height: 20, border: 'none', cursor: 'pointer', background: 'none', padding: 0 }} />
                          </div>
                        );
                      }
                      const strVal = String(fieldVal ?? '');
                      const isLongField = strVal.length > 50 || field === 'description' || field === 'text' || field === 'content';
                      return (
                        <div key={field}>
                          <label style={{ fontSize: 9, color: '#52525b', textTransform: 'capitalize' }}>{field}</label>
                          {isLongField ? (
                            <textarea value={strVal} onChange={(e) => {
                              actions.setProp(selectedId, (props: any) => {
                                const updated = [...(props[key] || [])];
                                updated[index] = { ...updated[index], [field]: e.target.value };
                                props[key] = updated;
                              });
                            }} rows={2} style={{ ...smallInputStyle, resize: 'vertical' }} />
                          ) : (
                            <input type="text" value={strVal} onChange={(e) => {
                              actions.setProp(selectedId, (props: any) => {
                                const updated = [...(props[key] || [])];
                                updated[index] = { ...updated[index], [field]: e.target.value };
                                props[key] = updated;
                              });
                            }} style={smallInputStyle} />
                          )}
                        </div>
                      );
                    })}
                  </div>
                );
              }}
              emptyItem={typeof sampleItem === 'object' && sampleItem !== null
                ? Object.fromEntries(itemFields.map((f) => [f, typeof sampleItem[f] === 'number' ? 0 : typeof sampleItem[f] === 'boolean' ? false : '']))
                : ''
              }
            />
          </CollapsibleSection>
        );
      })}

      {/* Style controls */}
      <CollapsibleSection title="Style">
        <div className="guided-section">
          <SectionLabel>Background</SectionLabel>
          <ColorSwatchGrid colors={BG_COLORS} activeValue={style.backgroundColor} onSelect={(v: string) => setStyleValue('backgroundColor', v)} />
        </div>
        {/* Text color in style */}
        <div className="guided-section">
          <SectionLabel>Text Color</SectionLabel>
          <ColorSwatchGrid colors={TEXT_COLORS} activeValue={style.color as string} onSelect={(v: string) => setStyleValue('color', v)} />
        </div>
        <div className="guided-section">
          <SectionLabel>Padding</SectionLabel>
          <PresetButtonGrid presets={SPACING_PRESETS} activeValue={style.padding as string} onSelect={(v) => setStyleValue('padding', v)} />
        </div>
        <div className="guided-section">
          <SectionLabel>Text Alignment</SectionLabel>
          <div className="preset-grid align-grid">
            {(['left', 'center', 'right'] as const).map((a) => (
              <button key={a} className={`preset-btn ${style.textAlign === a ? 'active' : ''}`} onClick={() => setStyleValue('textAlign', a)} title={a}>
                <i className={`fa fa-align-${a}`} />
              </button>
            ))}
          </div>
        </div>
        <div className="guided-section">
          <SectionLabel>Border Radius</SectionLabel>
          <PresetButtonGrid presets={RADIUS_PRESETS} activeValue={style.borderRadius as string} onSelect={(v) => setStyleValue('borderRadius', v)} />
        </div>
      </CollapsibleSection>
    </>
  );
};
