import React, { CSSProperties, useCallback, useRef, useState } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { useSiteDesign } from '../../state/SiteDesignContext';

/* ---------- Types ---------- */

interface LogoProps {
  type?: 'text' | 'image';
  text?: string;
  imageSrc?: string;
  imageWidth?: string;
  href?: string;
  fontFamily?: string;
  fontSize?: string;
  fontWeight?: string;
  color?: string;
  style?: CSSProperties;
}

/* ---------- Image upload helper ---------- */

async function uploadToWhp(file: File): Promise<string | null> {
  const cfg = (window as any).WHP_CONFIG;
  if (!cfg) return URL.createObjectURL(file);
  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; }
}

/* ---------- Helper: escape HTML ---------- */
function esc(str: any): string {
  str = String(str ?? "");
  return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

/* ---------- Component ---------- */

export const Logo: UserComponent<LogoProps> = ({
  type = 'text',
  text = 'MySite',
  imageSrc = '',
  imageWidth = '120px',
  href = '/',
  fontFamily = 'Inter, sans-serif',
  fontSize = '20px',
  fontWeight = '700',
  color,
  style = {},
}) => {
  const {
    connectors: { connect, drag },
  } = useNode();

  const { design } = useSiteDesign();
  const resolvedColor = color || design.textColor;

  return (
    <a
      ref={(ref: HTMLElement | null): void => { if (ref) connect(drag(ref)); }}
      href={href}
      onClick={(e) => e.preventDefault()}
      style={{
        textDecoration: 'none',
        display: 'inline-flex',
        alignItems: 'center',
        flexShrink: 0,
        ...style,
      }}
    >
      {type === 'image' && imageSrc ? (
        <img
          src={imageSrc}
          alt={text || 'Logo'}
          style={{ width: imageWidth, height: 'auto', display: 'block' }}
        />
      ) : (
        <span style={{
          fontWeight,
          fontSize,
          fontFamily,
          color: resolvedColor,
        }}>
          {text}
        </span>
      )}
    </a>
  );
};

/* ---------- Settings panel ---------- */

const LogoSettings: React.FC = () => {
  const { actions: { setProp }, props } = useNode((node) => ({
    props: node.data.props as LogoProps,
  }));

  const { design } = useSiteDesign();
  const logoType = props.type || 'text';

  const fileInputRef = useRef<HTMLInputElement>(null);
  const [showBrowser, setShowBrowser] = useState(false);
  const [browserAssets, setBrowserAssets] = useState<any[]>([]);
  const [browserLoading, setBrowserLoading] = useState(false);

  const fontFamilies = [
    { label: 'Inter', value: 'Inter, sans-serif' },
    { label: 'Roboto', value: 'Roboto, sans-serif' },
    { label: 'Poppins', value: 'Poppins, sans-serif' },
    { label: 'Montserrat', value: 'Montserrat, sans-serif' },
    { label: 'Playfair', value: 'Playfair Display, serif' },
    { label: 'Merriweather', value: 'Merriweather, serif' },
    { label: 'Source Code', value: 'Source Code Pro, monospace' },
    { label: 'Open Sans', value: 'Open Sans, sans-serif' },
  ];

  const handleLogoUpload = useCallback(async (file: File) => {
    const url = await uploadToWhp(file);
    if (url) setProp((p: LogoProps) => { p.imageSrc = url; });
  }, [setProp]);

  const handleBrowse = useCallback(async () => {
    if (showBrowser) { setShowBrowser(false); return; }
    const cfg = (window as any).WHP_CONFIG;
    if (!cfg) return;
    setBrowserLoading(true);
    try {
      const resp = await fetch(`${cfg.apiUrl}?action=list_assets&site_id=${cfg.siteId}`);
      const data = await resp.json();
      if (data.success && Array.isArray(data.assets)) {
        const images = data.assets.filter((a: any) => (a.type || '').startsWith('image'));
        setBrowserAssets(images);
        setShowBrowser(true);
      }
    } catch (e) {
      console.error('Browse failed:', e);
    } finally {
      setBrowserLoading(false);
    }
  }, [showBrowser]);

  /* ---- Shared styles ---- */
  const labelStyle: CSSProperties = { fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 4 };
  const inputStyle: CSSProperties = {
    width: '100%', padding: '3px 6px', background: '#27272a', color: '#e4e4e7',
    border: '1px solid #3f3f46', borderRadius: 4, fontSize: 11,
  };
  const btnSmall: CSSProperties = {
    padding: '2px 6px', fontSize: 11, background: '#27272a', color: '#a1a1aa',
    border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer',
  };
  const btnActive: CSSProperties = {
    ...btnSmall, background: '#3b82f6', color: '#fff', borderColor: '#3b82f6',
  };

  return (
    <div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: '14px' }}>
      {/* Type toggle */}
      <div>
        <label style={{ ...labelStyle, fontWeight: 600, fontSize: 12, marginBottom: 8 }}>Logo Type</label>
        <div style={{ display: 'flex', gap: 4 }}>
          <button
            onClick={() => setProp((p: LogoProps) => { p.type = 'text'; })}
            style={logoType === 'text' ? btnActive : btnSmall}
          >
            <i className="fa fa-font" style={{ marginRight: 3 }} />Text
          </button>
          <button
            onClick={() => setProp((p: LogoProps) => { p.type = 'image'; })}
            style={logoType === 'image' ? btnActive : btnSmall}
          >
            <i className="fa fa-image" style={{ marginRight: 3 }} />Image
          </button>
        </div>
      </div>

      {logoType === 'text' ? (
        <>
          <div>
            <label style={labelStyle}>Logo Text</label>
            <input
              type="text"
              value={props.text || ''}
              onChange={(e) => setProp((p: LogoProps) => { p.text = e.target.value; })}
              style={inputStyle}
            />
          </div>
          <div>
            <label style={labelStyle}>Font Family</label>
            <select
              value={props.fontFamily || 'Inter, sans-serif'}
              onChange={(e) => setProp((p: LogoProps) => { p.fontFamily = e.target.value; })}
              style={{ ...inputStyle, cursor: 'pointer' }}
            >
              {fontFamilies.map((f) => (
                <option key={f.value} value={f.value}>{f.label}</option>
              ))}
            </select>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <div style={{ flex: 1 }}>
              <label style={labelStyle}>Size</label>
              <input
                type="text"
                value={props.fontSize || '20px'}
                onChange={(e) => setProp((p: LogoProps) => { p.fontSize = e.target.value; })}
                placeholder="20px"
                style={inputStyle}
              />
            </div>
            <div style={{ flex: 1 }}>
              <label style={labelStyle}>Weight</label>
              <select
                value={props.fontWeight || '700'}
                onChange={(e) => setProp((p: LogoProps) => { p.fontWeight = e.target.value; })}
                style={{ ...inputStyle, cursor: 'pointer' }}
              >
                <option value="300">Light</option>
                <option value="400">Normal</option>
                <option value="500">Medium</option>
                <option value="600">Semi</option>
                <option value="700">Bold</option>
                <option value="800">Extra Bold</option>
              </select>
            </div>
          </div>
          <div>
            <label style={labelStyle}>Color</label>
            <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <input
                type="color"
                value={props.color || design.textColor}
                onChange={(e) => setProp((p: LogoProps) => { p.color = e.target.value; })}
                style={{ width: 28, height: 24, padding: 0, border: '1px solid #3f3f46', borderRadius: 3, cursor: 'pointer', background: 'none' }}
              />
              <span style={{ fontSize: 10, color: '#71717a' }}>{props.color || 'Auto'}</span>
              <button
                onClick={() => setProp((p: LogoProps) => { p.color = undefined; })}
                style={{ ...btnSmall, fontSize: 9, padding: '2px 4px' }}
                title="Reset to auto"
              >Auto</button>
            </div>
          </div>
        </>
      ) : (
        <>
          {/* Image logo controls */}
          {props.imageSrc ? (
            <div style={{ borderRadius: 6, overflow: 'hidden', border: '1px solid #3f3f46', position: 'relative' }}>
              <img src={props.imageSrc} alt="" style={{ width: '100%', height: 'auto', display: 'block', maxHeight: 80, objectFit: 'contain', background: '#18181b' }} />
              <button
                onClick={() => setProp((p: LogoProps) => { p.imageSrc = ''; })}
                style={{ position: 'absolute', top: 4, right: 4, width: 20, height: 20, borderRadius: '50%', background: 'rgba(0,0,0,0.7)', border: 'none', color: '#fff', cursor: 'pointer', fontSize: 10, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
                title="Remove image"
              >
                <i className="fa fa-times" />
              </button>
            </div>
          ) : (
            <div
              style={{ padding: '14px 12px', border: '2px dashed #3f3f46', borderRadius: 6, textAlign: 'center', color: '#71717a', fontSize: 11, cursor: 'pointer' }}
              onClick={() => fileInputRef.current?.click()}
              onDragOver={(e) => { e.preventDefault(); e.currentTarget.style.borderColor = '#3b82f6'; }}
              onDragLeave={(e) => { e.currentTarget.style.borderColor = '#3f3f46'; }}
              onDrop={async (e) => {
                e.preventDefault();
                e.currentTarget.style.borderColor = '#3f3f46';
                const file = e.dataTransfer.files?.[0];
                if (file && file.type.startsWith('image/')) await handleLogoUpload(file);
              }}
            >
              <i className="fa fa-cloud-upload" style={{ fontSize: 18, display: 'block', marginBottom: 4, color: '#3b82f6' }} />
              Drop logo or click to upload
            </div>
          )}

          <div style={{ display: 'flex', gap: 4 }}>
            <button
              onClick={() => fileInputRef.current?.click()}
              style={{ flex: 1, padding: '6px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer', border: '1px solid #3f3f46', background: '#3b82f6', color: '#fff', fontWeight: 500 }}
            >
              <i className="fa fa-upload" style={{ marginRight: 3 }} /> Upload
            </button>
            <button
              onClick={handleBrowse}
              style={{ flex: 1, padding: '6px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer', border: '1px solid #3f3f46', background: showBrowser ? '#3b82f6' : '#27272a', color: showBrowser ? '#fff' : '#e4e4e7' }}
            >
              <i className={`fa ${browserLoading ? 'fa-spinner fa-spin' : 'fa-folder-open'}`} style={{ marginRight: 3 }} /> Browse
            </button>
          </div>

          {/* Browse grid */}
          {showBrowser && (
            <div style={{ maxHeight: 150, overflowY: 'auto', display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 4, background: '#18181b', borderRadius: 6, padding: 4 }}>
              {browserAssets.map(asset => (
                <div
                  key={asset.name}
                  onClick={() => { setProp((p: LogoProps) => { p.imageSrc = asset.url; }); setShowBrowser(false); }}
                  style={{ cursor: 'pointer', borderRadius: 4, overflow: 'hidden', border: '2px solid transparent', aspectRatio: '1' }}
                  onMouseEnter={(e) => { e.currentTarget.style.borderColor = '#3b82f6'; }}
                  onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'transparent'; }}
                >
                  <img src={asset.url} alt={asset.name} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
                </div>
              ))}
              {browserAssets.length === 0 && (
                <p style={{ gridColumn: '1 / -1', textAlign: 'center', color: '#71717a', fontSize: 11, padding: '8px 0', margin: 0 }}>No images uploaded yet.</p>
              )}
            </div>
          )}

          <input ref={fileInputRef} type="file" accept="image/*" style={{ display: 'none' }}
            onChange={(e) => { const file = e.target.files?.[0]; if (file) handleLogoUpload(file); e.target.value = ''; }} />

          {/* URL paste input */}
          <div>
            <input
              type="text"
              value={props.imageSrc || ''}
              onChange={(e) => setProp((p: LogoProps) => { p.imageSrc = e.target.value; })}
              placeholder="Or paste image URL..."
              style={{ ...inputStyle, fontSize: 10, color: '#71717a' }}
            />
          </div>

          <div>
            <label style={labelStyle}>Logo Width</label>
            <input
              type="text"
              value={props.imageWidth || '120px'}
              onChange={(e) => setProp((p: LogoProps) => { p.imageWidth = e.target.value; })}
              placeholder="120px"
              style={inputStyle}
            />
          </div>
        </>
      )}

      {/* Link URL */}
      <div>
        <label style={labelStyle}>Link URL</label>
        <input
          type="text"
          value={props.href || '/'}
          onChange={(e) => setProp((p: LogoProps) => { p.href = e.target.value; })}
          placeholder="/"
          style={inputStyle}
        />
      </div>
    </div>
  );
};

/* ---------- Craft config ---------- */

Logo.craft = {
  displayName: 'Logo',
  props: {
    type: 'text',
    text: 'MySite',
    imageSrc: '',
    imageWidth: '120px',
    href: '/',
    fontFamily: 'Inter, sans-serif',
    fontSize: '20px',
    fontWeight: '700',
    color: undefined,
    style: {},
  } as LogoProps,
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
  related: {
    settings: LogoSettings,
  },
};

/* ---------- HTML export ---------- */

(Logo as any).toHtml = (props: LogoProps, _childrenHtml: string) => {
  const href = props.href || '/';

  let innerHtml: string;
  if (props.type === 'image' && props.imageSrc) {
    const imgStyle = cssPropsToString({ width: props.imageWidth || '120px', height: 'auto', display: 'block' });
    innerHtml = `<img src="${esc(props.imageSrc)}" alt="${esc(props.text || 'Logo')}"${imgStyle ? ` style="${imgStyle}"` : ''} />`;
  } else {
    const spanStyle = cssPropsToString({
      fontWeight: props.fontWeight || '700',
      fontSize: props.fontSize || '20px',
      fontFamily: props.fontFamily || 'Inter, sans-serif',
      color: props.color || '#1f2937',
    });
    innerHtml = `<span${spanStyle ? ` style="${spanStyle}"` : ''}>${esc(props.text || 'MySite')}</span>`;
  }

  const aStyle = cssPropsToString({
    textDecoration: 'none',
    display: 'inline-flex',
    alignItems: 'center',
    flexShrink: '0',
    ...props.style,
  });

  return {
    html: `<a href="${esc(href)}"${aStyle ? ` style="${aStyle}"` : ''}>${innerHtml}</a>`,
  };
};
