import React, { CSSProperties, useCallback, useRef } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { escapeAttr, safeImageUrl } from '../../utils/escape';

export const PLACEHOLDER_SRC = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0%25' stop-color='%23f1f5f9'/%3E%3Cstop offset='100%25' stop-color='%23e2e8f0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect fill='url(%23bg)' width='400' height='300' rx='12'/%3E%3Crect x='2' y='2' width='396' height='296' rx='10' fill='none' stroke='%23cbd5e1' stroke-width='2' stroke-dasharray='8 4'/%3E%3Cg transform='translate(200,110)'%3E%3Crect x='-28' y='-28' width='56' height='56' rx='12' fill='%23cbd5e1' opacity='0.5'/%3E%3Cpath d='M-12 8 L-4 -2 L2 4 L8 -6 L16 8Z' fill='%2394a3b8'/%3E%3Ccircle cx='-6' cy='-10' r='5' fill='%2394a3b8'/%3E%3C/g%3E%3Ctext x='200' y='160' text-anchor='middle' fill='%2364748b' font-family='Inter,sans-serif' font-size='15' font-weight='500'%3EDrop image here%3C/text%3E%3Ctext x='200' y='182' text-anchor='middle' fill='%2394a3b8' font-family='Inter,sans-serif' font-size='12'%3Eor click to upload%3C/text%3E%3C/svg%3E";

interface ImageBlockProps {
  src?: string;
  alt?: string;
  style?: CSSProperties;
  animation?: string;
  animationDelay?: string;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
}

/** Extracts the numeric portion of a plain "<n>px" CSS length string, for
 *  emitting real `width`/`height` HTML attributes on the exported `<img>`
 *  (helps the browser reserve layout space before the image loads --
 *  avoiding CLS -- something a CSS-only width/height can't do on its own).
 *  Returns undefined for any other unit ('%', 'auto', '', etc.) so the
 *  attribute is simply omitted when the pixel size isn't known. */
export function pxAttr(v: unknown): string | undefined {
  if (typeof v !== 'string') return undefined;
  const m = v.trim().match(/^(\d+(?:\.\d+)?)px$/);
  return m ? m[1] : undefined;
}

// Helper: upload a file to the WHP API and return the proxy URL
async function uploadToWhp(file: File): Promise<string | null> {
  const cfg = (window as any).WHP_CONFIG;
  if (!cfg) return URL.createObjectURL(file); // Standalone fallback

  const formData = new FormData();
  formData.append('file', file);
  try {
    const resp = await fetch(`${cfg.apiUrl}?action=upload_asset&site_id=${cfg.siteId}`, {
      method: 'POST',
      headers: { 'X-CSRF-Token': cfg.csrfToken },
      body: formData,
    });
    const data = await resp.json();
    if (data.success && data.url) return data.url;
    return null;
  } catch { return null; }
}

export const ImageBlock: UserComponent<ImageBlockProps> = ({
  src = PLACEHOLDER_SRC,
  alt = '',
  style = {},
}) => {
  const {
    connectors: { connect, drag },
    selected,
    actions: { setProp },
  } = useNode((node) => ({ selected: node.events.selected }));

  const imgRef = useRef<HTMLImageElement | null>(null);
  const isPlaceholder = !src || src === PLACEHOLDER_SRC || src.startsWith('data:image/svg');

  // Handle drag-and-drop of files directly onto the image
  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    const file = e.dataTransfer.files?.[0];
    if (file && file.type.startsWith('image/')) {
      const url = await uploadToWhp(file);
      if (url) setProp((p: ImageBlockProps) => { p.src = url; });
    }
  }, [setProp]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
  }, []);

  return (
    <img
      ref={(ref: HTMLImageElement | null) => {
        imgRef.current = ref;
        if (ref) connect(drag(ref));
      }}
      src={src || PLACEHOLDER_SRC}
      alt={alt || 'Image'}
      onDrop={handleDrop}
      onDragOver={handleDragOver}
      style={{
        display: 'block',
        maxWidth: '100%',
        outline: 'none',
        cursor: selected ? 'move' : 'pointer',
        ...style,
      }}
    />
  );
};

ImageBlock.craft = {
  displayName: 'Image',
  props: {
    src: PLACEHOLDER_SRC,
    alt: '',
    style: {
      width: '100%',
      height: 'auto',
      aspectRatio: '',
      objectFit: '' as CSSProperties['objectFit'],
      objectPosition: '',
      marginTop: '', marginRight: '', marginBottom: '', marginLeft: '',
      paddingTop: '', paddingRight: '', paddingBottom: '', paddingLeft: '',
      border: 'none',
      boxShadow: 'none',
      opacity: '1',
    },
    animation: '',
    animationDelay: '0',
    hideOnDesktop: false,
    hideOnTablet: false,
    hideOnMobile: false,
  },
  rules: { canDrag: () => true, canMoveIn: () => false, canMoveOut: () => true },
};

(ImageBlock as any).toHtml = (props: ImageBlockProps, _c: string) => {
  // Skip placeholder/empty images in export
  const src = props.src || '';
  if (!src || src.startsWith('data:image/svg') || src === PLACEHOLDER_SRC) {
    return { html: '' };
  }
  const s = cssPropsToString({ display: 'block', maxWidth: '100%', ...props.style });
  const alt = props.alt ? ` alt="${escapeAttr(props.alt)}"` : ' alt=""';
  const widthAttr = pxAttr((props.style as any)?.width);
  const heightAttr = pxAttr((props.style as any)?.height);
  const dims = `${widthAttr ? ` width="${widthAttr}"` : ''}${heightAttr ? ` height="${heightAttr}"` : ''}`;
  return { html: `<img src="${escapeAttr(safeImageUrl(src))}"${alt}${dims} loading="lazy" decoding="async"${s ? ` style="${s}"` : ''} />` };
};
