import React from 'react';
import { useReportData } from './DataContext';
import { useBandContext } from './BandContext';
import { resolveDBTextValue } from './utils/dataResolver';
import { evaluateExpression } from './utils/expressionEvaluator';
import ResizeHandles from './ResizeHandles';
import { useElementDrag } from './hooks/useElementDrag';
import { useElementSelection } from './hooks/useElementSelection';
import { getElementStyle, isTextMultiLine, getTextWhiteSpace } from './utils/elementUtils';
import './elements.css';

function formatValue(raw, dataType) {
  if (raw === '' || raw === null || raw === undefined) return '';
  switch (dataType) {
    case 'number': {
      const n = Number(raw);
      return isNaN(n) ? '' : String(n);
    }
    case 'date': {
      const d = new Date(raw);
      return isNaN(d.getTime()) ? '' : d.toLocaleDateString();
    }
    case 'time': {
      const d = new Date(raw);
      return isNaN(d.getTime()) ? '' : d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }
    case 'datetime': {
      const d = new Date(raw);
      return isNaN(d.getTime()) ? '' : d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }
    default:
      return String(raw);
  }
}

function ExpressionField({
  element,
  isSelected,
  isSingleSelection,
  onSelect,
  onUpdate,
  onDelete,
  onDragStart,
  onDrag,
  charWidth,
  charHeight,
  previewMode = false,
  toolMode,
  parentBandId = null
}) {
  const { reportData } = useReportData();
  const { currentBandData } = useBandContext();

  const { isDragging, handleMouseDown: handleDragMouseDown } = useElementDrag({
    isSelected,
    onDragStart,
    onDrag,
    toolMode
  });

  const { handleClick } = useElementSelection({
    isSelected,
    onSelect,
    onDelete,
    toolMode
  });

  const handleMouseDown = (e) => {
    onSelect();
    handleDragMouseDown(e, element.id);
  };

  const handleResize = (updates) => {
    onUpdate(updates);
  };

  let displayContent;
  if (previewMode) {
    const resolveField = (ref) => {
      const inner = ref.slice(1, ref.length - 1);
      const dotIndex = inner.indexOf('.');
      if (dotIndex === -1) {
        return resolveDBTextValue(reportData, '', inner, parentBandId, { currentBandData });
      }
      const objectKey = inner.slice(0, dotIndex);
      const fieldPath = inner.slice(dotIndex + 1);
      return resolveDBTextValue(reportData, objectKey, fieldPath, parentBandId, { currentBandData });
    };
    const raw = evaluateExpression(element.expression, resolveField);
    displayContent = formatValue(raw, element.dataType || 'general');
  } else {
    displayContent = element.expression || '(expr)';
  }

  const isUnresolved = !element.expression;

  const multiLine = isTextMultiLine(element);
  const whiteSpace = getTextWhiteSpace(element);

  const style = {
    ...getElementStyle(element, charWidth, charHeight),
    minWidth: `${charWidth}px`,
    minHeight: `${charHeight}px`,
    whiteSpace,
    textAlign: element.alignment || 'left',
  };

  return (
    <div
      className={`expr-field ${isSelected ? 'selected' : ''} ${isDragging ? 'dragging' : ''} ${isUnresolved ? 'unresolved' : ''}`}
      style={style}
      onClick={handleClick}
      onMouseDown={handleMouseDown}
    >
      <span className="expr-field-content" style={{ whiteSpace }}>
        {displayContent || '(No Expr)'}
      </span>
      {isSingleSelection && (
        <ResizeHandles
          element={element}
          onResize={handleResize}
          charWidth={charWidth}
          charHeight={charHeight}
        />
      )}
    </div>
  );
}

export default ExpressionField;
