import { useEffect, useRef, useImperativeHandle, forwardRef, useState } from 'react';
import grapesjs, { Editor } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
import blocksBasicPlugin from 'grapesjs-blocks-basic';
import presetWebpagePlugin from 'grapesjs-preset-webpage';
import formsPlugin from 'grapesjs-plugin-forms';
import navbarPlugin from 'grapesjs-navbar';
import countdownPlugin from 'grapesjs-component-countdown';
import tabsPlugin from 'grapesjs-tabs';
import typedPlugin from 'grapesjs-typed';
import customCodePlugin from 'grapesjs-custom-code';
import exportPlugin from 'grapesjs-plugin-export';
import styleGradientPlugin from 'grapesjs-style-gradient';
import touchPlugin from 'grapesjs-touch';
import type { PageBlock } from '@/types/api';
import { generateVideoCardHtml } from '@/utils/videoCardHtml';
import { generatePhotoCardHtml } from '@/utils/photoCardHtml';

interface GrapesJSEditorProps {
  initialData?: Record<string, unknown>;
  onSave: (data: { projectData: Record<string, unknown>; html: string; css: string }) => void;
  customBlocks?: PageBlock[];
}

export interface GrapesJSEditorHandle {
  triggerSave: () => void;
}

const GrapesJSEditor = forwardRef<GrapesJSEditorHandle, GrapesJSEditorProps>(
  function GrapesJSEditor({ initialData, onSave, customBlocks }, ref) {
  const editorRef = useRef<Editor | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const onSaveRef = useRef(onSave);
  const [error, setError] = useState<string | null>(null);
  onSaveRef.current = onSave;

  useImperativeHandle(ref, () => ({
    triggerSave() {
      editorRef.current?.runCommand('save-page');
    },
  }));

  useEffect(() => {
    if (!containerRef.current) return;

    let editor: Editor;
    try {
      editor = grapesjs.init({
        container: containerRef.current,
        height: '100%',
        width: 'auto',
        storageManager: false,
        plugins: [
          blocksBasicPlugin,
          presetWebpagePlugin,
          formsPlugin,
          navbarPlugin,
          countdownPlugin,
          tabsPlugin,
          typedPlugin,
          customCodePlugin,
          exportPlugin,
          styleGradientPlugin,
          touchPlugin,
        ],
        pluginsOpts: {
          [blocksBasicPlugin as unknown as string]: {
            flexGrid: true,
          },
          [presetWebpagePlugin as unknown as string]: {},
          [formsPlugin as unknown as string]: {},
          [navbarPlugin as unknown as string]: {},
          [countdownPlugin as unknown as string]: {},
          [tabsPlugin as unknown as string]: {},
          [typedPlugin as unknown as string]: {},
          [customCodePlugin as unknown as string]: {},
          [exportPlugin as unknown as string]: {},
          [styleGradientPlugin as unknown as string]: {},
          [touchPlugin as unknown as string]: {},
        },
        canvas: {
          styles: [
            'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap',
          ],
        },
      });
    } catch (err) {
      console.error('GrapesJS init error:', err);
      setError('Failed to initialize the page editor. Please refresh the page.');
      return;
    }

    // Register custom blocks from PageBlock library
    if (customBlocks && customBlocks.length > 0) {
      const blockManager = editor.Blocks;
      for (const block of customBlocks) {
        const defaults = block.defaults as Record<string, unknown>;
        const html = generateBlockHtml(block.type, defaults);
        blockManager.add(`custom-${block.type}`, {
          label: block.label,
          category: block.category || 'Campaign',
          content: html,
        });
      }
    }

    // Register ad blocks
    {
      const bm = editor.Blocks;
      bm.add('ad-specific', {
        label: 'Specific Ad',
        category: 'Ads',
        content: generateBlockHtml('ad-specific', { adId: 0 }),
      });
      bm.add('ad-slot', {
        label: 'Ad Slot (Dynamic)',
        category: 'Ads',
        content: generateBlockHtml('ad-slot', { variant: 'standard' }),
      });
    }

    // Register save command
    editor.Commands.add('save-page', {
      run(ed: Editor) {
        const projectData = ed.getProjectData() as Record<string, unknown>;
        const html = ed.getHtml();
        const css = ed.getCss() || '';
        onSaveRef.current({ projectData, html, css });
      },
    });

    // Keyboard shortcut: Ctrl+S / Cmd+S
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        editor.runCommand('save-page');
      }
    };
    document.addEventListener('keydown', handleKeyDown);

    // Load initial project data
    if (initialData && Object.keys(initialData).length > 0) {
      editor.loadProjectData(initialData);
    }

    editorRef.current = editor;

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      editor.destroy();
      editorRef.current = null;
    };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  if (error) {
    return (
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#ff4d4f' }}>
        {error}
      </div>
    );
  }

  return (
    <div
      ref={containerRef}
      role="application"
      aria-label="Page builder editor"
      style={{ flex: 1, overflow: 'hidden' }}
    />
  );
});

function generateBlockHtml(type: string, defaults: Record<string, unknown>): string {
  switch (type) {
    case 'hero':
      return `
        <section style="padding: 80px 40px; text-align: center; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: #fff;">
          <h1 style="font-size: 2.5rem; margin-bottom: 16px;">${defaults.title || 'Hero Title'}</h1>
          <p style="font-size: 1.25rem; opacity: 0.85; margin-bottom: 32px;">${defaults.subtitle || 'Subtitle text here'}</p>
          <a href="${defaults.ctaUrl || '#'}" style="display: inline-block; padding: 12px 32px; background: #9d4edd; color: #fff; text-decoration: none; border-radius: 6px; font-weight: 600;">${defaults.ctaText || 'Get Started'}</a>
        </section>`;
    case 'text':
      return `
        <section style="padding: 60px 40px; max-width: 800px; margin: 0 auto;">
          <h2 style="font-size: 1.75rem; margin-bottom: 16px;">${defaults.heading || 'Heading'}</h2>
          <p style="font-size: 1rem; line-height: 1.7; opacity: 0.85;">${defaults.body || 'Body text goes here.'}</p>
        </section>`;
    case 'features': {
      const features = (defaults.features as Array<{ title: string; description: string }>) || [];
      const featureHtml = features.map(f => `
        <div style="flex: 1; min-width: 250px; padding: 24px; text-align: center;">
          <h3 style="font-size: 1.25rem; margin-bottom: 8px;">${f.title}</h3>
          <p style="opacity: 0.8;">${f.description}</p>
        </div>`).join('');
      return `
        <section style="padding: 60px 40px;">
          <div style="display: flex; flex-wrap: wrap; gap: 24px; justify-content: center;">
            ${featureHtml}
          </div>
        </section>`;
    }
    case 'cta':
      return `
        <section style="padding: 60px 40px; text-align: center; background: linear-gradient(135deg, #9d4edd 0%, #7b2cbf 100%); color: #fff;">
          <h2 style="font-size: 2rem; margin-bottom: 12px;">${defaults.heading || 'Call to Action'}</h2>
          <p style="font-size: 1.1rem; margin-bottom: 24px; opacity: 0.9;">${defaults.description || 'Description here'}</p>
          <a href="${defaults.buttonUrl || '#'}" style="display: inline-block; padding: 12px 32px; background: #fff; color: #9d4edd; text-decoration: none; border-radius: 6px; font-weight: 600;">${defaults.buttonText || 'Click Here'}</a>
        </section>`;
    case 'testimonials': {
      const quotes = (defaults.quotes as Array<{ text: string; author: string; role: string }>) || [];
      const quoteHtml = quotes.map(q => `
        <div style="flex: 1; min-width: 280px; padding: 24px; background: rgba(255,255,255,0.05); border-radius: 8px;">
          <p style="font-style: italic; margin-bottom: 12px;">"${q.text}"</p>
          <p style="font-weight: 600; margin-bottom: 2px;">${q.author}</p>
          <p style="font-size: 0.85rem; opacity: 0.7;">${q.role}</p>
        </div>`).join('');
      return `
        <section style="padding: 60px 40px;">
          <div style="display: flex; flex-wrap: wrap; gap: 24px; justify-content: center;">
            ${quoteHtml}
          </div>
        </section>`;
    }
    case 'contact-form':
      return `
        <section style="padding: 60px 40px; max-width: 600px; margin: 0 auto;">
          <h2 style="text-align: center; margin-bottom: 24px;">${defaults.heading || 'Contact Us'}</h2>
          <form style="display: flex; flex-direction: column; gap: 16px;">
            <input type="text" placeholder="Name" style="padding: 10px 14px; border: 1px solid rgba(255,255,255,0.2); border-radius: 6px; background: rgba(255,255,255,0.05); color: inherit;" />
            <input type="email" placeholder="Email" style="padding: 10px 14px; border: 1px solid rgba(255,255,255,0.2); border-radius: 6px; background: rgba(255,255,255,0.05); color: inherit;" />
            <textarea placeholder="Message" rows="4" style="padding: 10px 14px; border: 1px solid rgba(255,255,255,0.2); border-radius: 6px; background: rgba(255,255,255,0.05); color: inherit; resize: vertical;"></textarea>
            <button type="submit" style="padding: 12px 24px; background: #9d4edd; color: #fff; border: none; border-radius: 6px; font-weight: 600; cursor: pointer;">Send Message</button>
          </form>
        </section>`;
    case 'video': {
      const videoId = defaults.videoId || 'PLACEHOLDER';
      const playerType = defaults.playerType || 'standard';
      const width = defaults.width || '100%';
      const height = defaults.height || 'auto';

      // Generate placeholder with data attributes for hydration
      return `
        <section style="padding: 60px 40px;">
          <div class="video-block"
               data-video-id="${videoId}"
               data-player-type="${playerType}"
               data-width="${width}"
               data-height="${height}"
               data-autoplay="${defaults.autoplay || false}"
               data-controls="${defaults.controls !== false}"
               data-show-reactions="${defaults.showReactions !== false}"
               style="max-width: ${width}; margin: 0 auto;">
            <div class="video-placeholder" style="aspect-ratio: 16/9; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 12px; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden;">
              <div style="text-align: center; color: #fff; padding: 24px;">
                <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="currentColor" viewBox="0 0 20 20">
                  <path d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" />
                </svg>
                <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">Video Player</p>
                <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.8;">ID: ${videoId}</p>
                <p style="margin: 4px 0 0; font-size: 0.85rem; opacity: 0.7;">${playerType === 'advanced' ? 'Advanced Player (with reactions)' : 'Standard HTML5 Player'}</p>
                <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Video will render on published page</p>
              </div>
            </div>
          </div>
        </section>`;
    }
    case 'video-card': {
      const videoId = defaults.videoId;
      const title = (defaults.title as string) || 'Video Title';
      const durationSeconds = (defaults.durationSeconds as number) || 0;
      const quality = (defaults.quality as string) || '';
      const viewCount = (defaults.viewCount as number) || 0;
      const mediaApiUrl = 'http://localhost:4100';

      if (!videoId || videoId === 'PLACEHOLDER') {
        return `
        <section style="padding: 40px 20px;">
          <div class="video-card-block" style="max-width: 480px; margin: 0 auto; border-radius: 12px; overflow: hidden; background: #1b2838; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
            <div style="padding-bottom: 56.25%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); position: relative;">
              <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #fff;">
                <svg style="width: 48px; height: 48px; margin-bottom: 8px; opacity: 0.9;" fill="currentColor" viewBox="0 0 20 20"><path d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z"/></svg>
                <p style="margin: 0; font-size: 14px; font-weight: 600;">Video Card</p>
                <p style="margin: 4px 0 0; font-size: 12px; opacity: 0.7;">Select a video to display</p>
              </div>
            </div>
            <div style="padding: 12px 16px;">
              <div style="color: #fff; font-size: 15px; font-weight: 600;">Video Title</div>
              <div style="color: #8899aa; font-size: 13px; margin-top: 6px;">Card will render on published page</div>
            </div>
          </div>
        </section>`;
      }

      const cardHtml = generateVideoCardHtml({
        id: videoId as number,
        title,
        durationSeconds,
        quality,
        viewCount,
        thumbnailUrl: `${mediaApiUrl}/api/videos/${videoId}/thumbnail`,
      });

      return `<section style="padding: 40px 20px;">${cardHtml}</section>`;
    }
    case 'donate-button': {
      const heading = (defaults.heading as string) || 'Support Our Cause';
      const description = (defaults.description as string) || 'Your contribution helps us create lasting change in our community.';
      const buttonText = (defaults.buttonText as string) || 'Donate Now';
      const showAmounts = defaults.showAmounts !== false;
      return `
        <section class="payment-block" data-payment-type="donate" data-button-text="${buttonText}" data-show-amounts="${showAmounts}" style="padding: 60px 40px; text-align: center; background: linear-gradient(135deg, #2d1b69 0%, #1a1a2e 100%); color: #fff;">
          <div style="max-width: 600px; margin: 0 auto;">
            <div style="font-size: 48px; margin-bottom: 16px;">&#x2764;</div>
            <h2 style="font-size: 2rem; margin-bottom: 12px;">${heading}</h2>
            <p style="font-size: 1.1rem; margin-bottom: 24px; opacity: 0.85;">${description}</p>
            <a href="/donate" style="display: inline-block; padding: 14px 36px; background: #eb2f96; color: #fff; text-decoration: none; border-radius: 8px; font-weight: 600; font-size: 1.1rem;">${buttonText}</a>
          </div>
        </section>`;
    }
    case 'pricing-table': {
      const heading = (defaults.heading as string) || 'Choose Your Plan';
      const description = (defaults.description as string) || 'Get access to exclusive content and features.';
      const showYearly = defaults.showYearly !== false;
      return `
        <section class="payment-block" data-payment-type="pricing" data-show-yearly="${showYearly}" style="padding: 60px 40px; text-align: center; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: #fff;">
          <div style="max-width: 900px; margin: 0 auto;">
            <div style="font-size: 48px; margin-bottom: 16px;">&#x1F451;</div>
            <h2 style="font-size: 2rem; margin-bottom: 12px;">${heading}</h2>
            <p style="font-size: 1.1rem; margin-bottom: 32px; opacity: 0.85;">${description}</p>
            <div style="display: flex; gap: 24px; justify-content: center; flex-wrap: wrap;">
              <div style="flex: 1; min-width: 220px; max-width: 280px; padding: 24px; background: rgba(255,255,255,0.08); border-radius: 12px;">
                <h3 style="font-size: 1.25rem; margin-bottom: 8px;">Free</h3>
                <p style="font-size: 2rem; font-weight: 700; margin: 8px 0;">$0</p>
                <p style="opacity: 0.7; font-size: 0.9rem;">Access public content</p>
              </div>
              <div style="flex: 1; min-width: 220px; max-width: 280px; padding: 24px; background: rgba(114,46,209,0.2); border: 2px solid #722ed1; border-radius: 12px;">
                <h3 style="font-size: 1.25rem; margin-bottom: 8px;">Premium</h3>
                <p style="font-size: 2rem; font-weight: 700; margin: 8px 0;">$XX/mo</p>
                <p style="opacity: 0.7; font-size: 0.9rem;">Plans load from API</p>
              </div>
            </div>
            <p style="margin-top: 16px; font-size: 0.8rem; opacity: 0.5; font-style: italic;">Plans will load dynamically on published page</p>
          </div>
        </section>`;
    }
    case 'product-card': {
      const productSlug = (defaults.productSlug as string) || '';
      const buttonText = (defaults.buttonText as string) || 'Buy Now';
      return `
        <section class="payment-block" data-payment-type="product" data-product-slug="${productSlug}" data-button-text="${buttonText}" style="padding: 40px 20px;">
          <div style="max-width: 380px; margin: 0 auto; border-radius: 12px; overflow: hidden; background: #1b2838; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
            <div style="padding-bottom: 56.25%; background: linear-gradient(135deg, #9d4edd 0%, #722ed1 100%); position: relative;">
              <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #fff;">
                <div style="font-size: 48px; margin-bottom: 8px;">&#x1F6D2;</div>
                <p style="margin: 0; font-size: 14px; font-weight: 600;">Product Card</p>
                <p style="margin: 4px 0 0; font-size: 12px; opacity: 0.7;">${productSlug || 'Set product slug'}</p>
              </div>
            </div>
            <div style="padding: 16px;">
              <div style="color: #fff; font-size: 15px; font-weight: 600;">${productSlug || 'Product Name'}</div>
              <div style="color: #8899aa; font-size: 13px; margin-top: 6px;">Product details load on published page</div>
              <a href="/shop" style="display: inline-block; margin-top: 12px; padding: 8px 20px; background: #9d4edd; color: #fff; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 0.9rem;">${buttonText}</a>
            </div>
          </div>
        </section>`;
    }
    case 'campaign-form': {
      const campaignSlug = (defaults.campaignSlug as string) || '';
      const compact = defaults.compact === true;
      return `
        <section class="campaign-form-block"
                 data-campaign-slug="${campaignSlug}"
                 data-compact="${compact}"
                 style="padding: 60px 40px;">
          <div style="max-width: 600px; margin: 0 auto; border-radius: 12px; overflow: hidden; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
            <div style="padding: 32px; text-align: center; color: #fff;">
              <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="currentColor" viewBox="0 0 1024 1024">
                <path d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 356.9 277.7c11.7 9.1 28.4 9.1 40.1 0L889.7 270.8l27.6-21.5-39.3-50.5-44.4 33.2z"/>
              </svg>
              <p style="margin: 0; font-size: 1.2rem; font-weight: 600;">Campaign Email Form</p>
              <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.8;">${campaignSlug || 'Set campaign slug in block properties'}</p>
              <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Interactive form will render on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'gancio-events': {
      const maxlength = defaults.maxlength || 10;
      const evTheme = (defaults.theme as string) || 'dark';
      const tags = (defaults.tags as string) || '';
      const title = (defaults.title as string) || 'Upcoming Events';
      return `
        <section style="padding: 60px 40px;">
          <div class="gancio-events-block"
               data-maxlength="${maxlength}"
               data-theme="${evTheme}"
               data-tags="${tags}"
               data-title="${title}"
               style="max-width: 800px; margin: 0 auto;">
            <div style="aspect-ratio: 16/9; background: linear-gradient(135deg, #1a472a 0%, #2d5a27 100%); border-radius: 12px; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden;">
              <div style="text-align: center; color: #fff; padding: 24px;">
                <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="currentColor" viewBox="0 0 1024 1024">
                  <path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32z"/>
                </svg>
                <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">${title}</p>
                <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.8;">Theme: ${evTheme} | Max: ${maxlength} events</p>
                ${tags ? `<p style="margin: 4px 0 0; font-size: 0.85rem; opacity: 0.7;">Tags: ${tags}</p>` : ''}
                <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Events will render on published page</p>
              </div>
            </div>
          </div>
        </section>`;
    }
    case 'photo': {
      const photoId = defaults.photoId || 'PLACEHOLDER';
      const size = defaults.size || 'large';
      const caption = (defaults.caption as string) || '';
      const linkToGallery = defaults.linkToGallery !== false;
      const alignment = (defaults.alignment as string) || 'center';
      const maxWidth = (defaults.maxWidth as string) || '100%';

      return `
        <section style="padding: 60px 40px;">
          <div class="photo-block"
               data-photo-id="${photoId}"
               data-size="${size}"
               data-caption="${caption}"
               data-link-to-gallery="${linkToGallery}"
               data-alignment="${alignment}"
               style="max-width: ${maxWidth}; margin: 0 ${{ left: 'auto 0 0', center: 'auto', right: '0 0 auto' }[alignment as string] || 'auto'}; text-align: ${alignment};">
            <div class="photo-placeholder" style="aspect-ratio: 3/2; background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%); border-radius: 12px; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden;">
              <div style="text-align: center; color: #fff; padding: 24px;">
                <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
                  <rect x="3" y="3" width="18" height="18" rx="2"/>
                  <circle cx="8.5" cy="8.5" r="1.5"/>
                  <path d="m21 15-5-5L5 21"/>
                </svg>
                <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">Photo</p>
                <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.8;">ID: ${photoId}</p>
                <p style="margin: 4px 0 0; font-size: 0.85rem; opacity: 0.7;">Size: ${size}</p>
                <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Photo will render on published page</p>
              </div>
            </div>
          </div>
        </section>`;
    }
    case 'photo-card': {
      const photoId = defaults.photoId;
      const title = (defaults.title as string) || 'Photo Title';
      const description = (defaults.description as string) || '';
      const showMetadata = defaults.showMetadata !== false;
      const mediaApiUrl = 'http://localhost:4100';

      if (!photoId || photoId === 'PLACEHOLDER') {
        return `
        <section style="padding: 40px 20px;">
          <div class="photo-card-block" style="max-width: 480px; margin: 0 auto; border-radius: 12px; overflow: hidden; background: #1b2838; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
            <div style="padding-bottom: 66.67%; background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%); position: relative;">
              <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #fff;">
                <svg style="width: 48px; height: 48px; margin-bottom: 8px; opacity: 0.9;" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
                <p style="margin: 0; font-size: 14px; font-weight: 600;">Photo Card</p>
                <p style="margin: 4px 0 0; font-size: 12px; opacity: 0.7;">Select a photo to display</p>
              </div>
            </div>
            <div style="padding: 12px 16px;">
              <div style="color: #fff; font-size: 15px; font-weight: 600;">Photo Title</div>
              <div style="color: #8899aa; font-size: 13px; margin-top: 6px;">Card will render on published page</div>
            </div>
          </div>
        </section>`;
      }

      const cardHtml = generatePhotoCardHtml({
        id: photoId as number,
        title,
        description,
        showMetadata,
        viewCount: 0,
        thumbnailUrl: `${mediaApiUrl}/api/public/photos/${photoId}/thumbnail`,
      });

      return `<section style="padding: 40px 20px;">${cardHtml}</section>`;
    }
    case 'photo-album': {
      const albumId = defaults.albumId || 'PLACEHOLDER';
      const columns = defaults.columns || '3';
      const maxPhotos = defaults.maxPhotos || 12;
      const showTitle = defaults.showTitle !== false;

      return `
        <section style="padding: 60px 40px;">
          <div class="photo-album-block"
               data-album-id="${albumId}"
               data-columns="${columns}"
               data-max-photos="${maxPhotos}"
               data-show-title="${showTitle}"
               style="max-width: 900px; margin: 0 auto;">
            <div style="background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%); border-radius: 12px; padding: 32px; position: relative; overflow: hidden;">
              <div style="text-align: center; color: #fff; margin-bottom: 24px;">
                <svg style="width: 48px; height: 48px; margin-bottom: 12px; opacity: 0.9;" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
                  <rect x="2" y="2" width="20" height="20" rx="2"/>
                  <rect x="6" y="6" width="12" height="12" rx="1" opacity="0.6"/>
                  <rect x="9" y="9" width="6" height="6" rx="0.5" opacity="0.4"/>
                </svg>
                <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">Photo Album</p>
                <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.8;">Album ID: ${albumId} | ${columns} columns | Max ${maxPhotos} photos</p>
              </div>
              <div style="display: grid; grid-template-columns: repeat(${columns}, 1fr); gap: 8px;">
                ${Array.from({ length: Math.min(Number(columns) * 2, 6) }, () => `
                  <div style="aspect-ratio: 1; background: rgba(255,255,255,0.15); border-radius: 6px; display: flex; align-items: center; justify-content: center;">
                    <svg style="width: 24px; height: 24px; opacity: 0.5;" fill="none" stroke="#fff" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
                  </div>`).join('')}
              </div>
              <p style="text-align: center; margin: 16px 0 0; font-size: 0.75rem; opacity: 0.6; color: #fff; font-style: italic;">Album will render on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'ad-specific': {
      const adId = defaults.adId || 0;
      return `
        <section style="padding: 40px 20px;">
          <div class="ad-specific-block"
               data-ad-id="${adId}"
               style="max-width: 400px; margin: 0 auto;">
            <div style="border-radius: 12px; overflow: hidden; background: linear-gradient(135deg, #e65100 0%, #bf360c 100%); padding: 32px; text-align: center; color: #fff;">
              <div style="font-size: 36px; margin-bottom: 12px;">&#x1F4E2;</div>
              <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">Specific Ad</p>
              <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.85;">ID: ${adId || 'Not set'}</p>
              <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Ad will render on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'ad-slot': {
      const variant = (defaults.variant as string) || 'standard';
      return `
        <section style="padding: 40px 20px;">
          <div class="ad-slot-block"
               data-placement="landing_page"
               data-variant="${variant}"
               style="max-width: 400px; margin: 0 auto;">
            <div style="border-radius: 12px; overflow: hidden; background: linear-gradient(135deg, #2e7d32 0%, #1b5e20 100%); padding: 32px; text-align: center; color: #fff;">
              <div style="font-size: 36px; margin-bottom: 12px;">&#x1F500;</div>
              <p style="margin: 0; font-size: 1.1rem; font-weight: 600;">Ad Slot (Dynamic)</p>
              <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.85;">Variant: ${variant}</p>
              <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Rotating ad will render on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'scheduling-poll': {
      const pollSlug = (defaults.pollSlug as string) || '';
      const showComments = defaults.showComments !== false;
      const title = (defaults.title as string) || 'Vote on a Meeting Time';
      return `
        <section style="padding: 60px 40px;">
          <div class="scheduling-poll-block"
               data-poll-slug="${pollSlug}"
               data-show-comments="${showComments}"
               data-title="${title}"
               style="max-width: 700px; margin: 0 auto;">
            <div style="background: linear-gradient(135deg, #fa8c16 0%, #d46b08 100%); border-radius: 12px; padding: 32px; text-align: center; color: #fff;">
              <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="currentColor" viewBox="0 0 1024 1024">
                <path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32z"/>
              </svg>
              <p style="margin: 0; font-size: 1.2rem; font-weight: 600;">${title}</p>
              <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.85;">${pollSlug || 'Set poll slug in block properties'}</p>
              <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Poll will render on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'straw-poll-inline': {
      const pollSlug = (defaults.pollSlug as string) || '';
      return `
        <section style="padding: 60px 40px;">
          <div class="straw-poll-inline"
               data-poll-slug="${pollSlug}"
               data-show-results="true"
               style="max-width: 500px; margin: 0 auto;">
            <div style="background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%); border-radius: 12px; padding: 32px; text-align: center; color: #fff;">
              <svg style="width: 64px; height: 64px; margin-bottom: 16px; opacity: 0.9;" fill="currentColor" viewBox="0 0 1024 1024">
                <path d="M160 960h128V480H160v480zm256 0h128V320H416v640zm256 0h128V160H672v800z"/>
              </svg>
              <p style="margin: 0; font-size: 1.2rem; font-weight: 600;">Straw Poll (Inline)</p>
              <p style="margin: 8px 0 0; font-size: 0.9rem; opacity: 0.85;">${pollSlug || 'Set poll slug in block properties'}</p>
              <p style="margin: 12px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Inline voting widget renders on published page</p>
            </div>
          </div>
        </section>`;
    }
    case 'straw-poll-card': {
      const pollSlug = (defaults.pollSlug as string) || '';
      return `
        <section style="padding: 40px;">
          <div class="straw-poll-card"
               data-poll-slug="${pollSlug}"
               style="max-width: 400px; margin: 0 auto;">
            <div style="background: linear-gradient(135deg, #722ed1 0%, #531dab 100%); border-radius: 12px; padding: 24px; text-align: center; color: #fff;">
              <p style="margin: 0; font-size: 1rem; font-weight: 600;">Straw Poll (Card Link)</p>
              <p style="margin: 8px 0 0; font-size: 0.85rem; opacity: 0.85;">${pollSlug || 'Set poll slug in block properties'}</p>
              <p style="margin: 8px 0 0; font-size: 0.75rem; opacity: 0.6; font-style: italic;">Preview card with vote link renders on published page</p>
            </div>
          </div>
        </section>`;
    }
    default:
      return `<section style="padding: 40px; text-align: center;"><p>Custom block: ${type}</p></section>`;
  }
}

export default GrapesJSEditor;
