'use client';

import { useEffect, useState, useCallback, useRef, Component, type ReactNode } from 'react';
import { useParams } from 'next/navigation';
import { useSession } from 'next-auth/react';
import Link from 'next/link';
import dynamic from 'next/dynamic';
import Image from 'next/image';
import type { Data } from '@measured/puck';
import { Card, CardBody } from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import { puckConfig } from '@/lib/cms/puck-config';
import {
  META_TITLE_MAX,
  META_DESCRIPTION_MAX,
  EXCERPT_MAX,
  AUTHOR_MAX,
} from '@/lib/cms/validation';
import { buildDomainSlug } from '@/lib/domain-slug';
import styles from '../../../../dashboard.module.css';
import '@measured/puck/puck.css';

// Dealer info interface for header/footer preview
interface DealerInfo {
  id: string;
  status:
    | 'pending'
    | 'registration_pending'
    | 'registration_complete'
    | 'active'
    | 'suspended'
    | 'cancelled'
    | 'payment_failed';
  subdomain: string;
  domain: string;
  domainPrefix: string; // e.g., 'myamsoil' or 'shopamsoil' - required for correct View Page URLs
  businessName: string | null;
  contactName: string | null;
  phone: string;
  address: string;
  city: string;
  state: string;
  zip: string;
  contactEmail: string | null;
}

// Navigation item from API
interface NavigationItem {
  id: string;
  label: string;
  pageId: string | null;
  externalUrl: string | null;
  parentId: string | null;
  sortOrder: number;
  openInNewTab: boolean;
  page: { slug: string; title: string; type?: string } | null;
}

// Tree structure for rendering
interface NavTreeItem {
  id: string;
  label: string;
  href: string | null;
  openInNewTab: boolean;
  children: NavTreeItem[];
}

// Error boundary for Puck editor
interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
}

class PuckErrorBoundary extends Component<
  { children: ReactNode; onReset: () => void },
  ErrorBoundaryState
> {
  constructor(props: { children: ReactNode; onReset: () => void }) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }

  render() {
    if (this.state.hasError) {
      return (
        <div
          style={{
            padding: '2rem',
            textAlign: 'center',
            backgroundColor: '#fef2f2',
            borderRadius: '8px',
            margin: '1rem',
          }}
        >
          <h3 style={{ color: '#dc2626', marginBottom: '1rem' }}>Editor failed to load</h3>
          <p style={{ color: '#374151', marginBottom: '1rem' }}>
            {this.state.error?.message || 'An unexpected error occurred'}
          </p>
          <button
            onClick={() => {
              this.setState({ hasError: false, error: null });
              this.props.onReset();
            }}
            style={{
              padding: '0.5rem 1rem',
              backgroundColor: '#38bdf8',
              color: '#0f172a',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer',
            }}
          >
            Try Again
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}

// Dynamically import Puck to avoid SSR issues
const Puck = dynamic(() => import('@measured/puck').then((mod) => mod.Puck), {
  ssr: false,
  loading: () => (
    <div style={{ padding: '2rem', textAlign: 'center' }}>
      <p>Loading editor...</p>
      <p style={{ fontSize: '0.875rem', color: '#64748b', marginTop: '0.5rem' }}>
        This may take a moment on first load
      </p>
    </div>
  ),
});

interface PageData {
  id: string;
  title: string;
  slug: string;
  type: 'page' | 'blog';
  status: 'draft' | 'published';
  puckData: Data | null;
  metaTitle: string | null;
  metaDescription: string | null;
  excerpt: string | null;
  author: string | null;
  publishedAt: string | null;
  updatedAt: string;
}

// Field character budgets come straight from lib/cms/validation.ts (the server
// Zod schema) so the UI counters can never silently drift from what the server
// accepts. Surfacing them prevents the confusing save-time "N characters" error
// a dealer hits when a (often migrated) page already carries an over-limit value.

// Fields that live in the Settings panel. A failed-save `fieldErrors` response
// only auto-opens that panel when one of its keys is here — so an error on a
// non-panel field (featuredImage, puckData, …) doesn't pop the panel open with
// nothing visibly wrong in it.
const SETTINGS_PANEL_FIELDS = new Set([
  'title',
  'slug',
  'metaTitle',
  'metaDescription',
  'author',
  'excerpt',
]);

/**
 * Live character counter for length-limited fields. Turns red and prompts the
 * dealer to shorten once the value exceeds the limit (a too-long value can be
 * typed fresh or arrive pre-existing from the database).
 *
 * The counter — not a browser `maxLength` — is the single source of truth for
 * the limit: `maxLength` is enforced against the RAW value, but the editor sends
 * `value.trim()` and the server validates the trimmed value, so a `maxLength`
 * cap would diverge from this counter (and silently block typing) for a value
 * padded with whitespace. `count` must therefore be the TRIMMED length so it
 * matches exactly what the server accepts.
 *
 * A11y: the visible <p> is the field's `aria-describedby` target (read on
 * focus). Announcements use a SEPARATE, always-present polite live region whose
 * text is populated only in the over-limit state. This avoids per-keystroke
 * chatter while typing under the limit AND the unreliable behavior (across some
 * AT/browser pairs) of toggling a live region's `aria-live` on a rendered node.
 */
function CharCounter({ id, count, max }: { id?: string; count: number; max: number }) {
  const over = count > max;
  return (
    <>
      <p
        id={id}
        style={{
          margin: '0.25rem 0 0',
          fontSize: '0.75rem',
          color: over ? '#dc2626' : '#6b7280',
          fontWeight: over ? 600 : 400,
        }}
      >
        {count}/{max} characters{over ? ' — please shorten to save' : ''}
      </p>
      <span aria-live="polite" aria-atomic="true" className="sr-only">
        {over ? `Character limit exceeded: ${count} of ${max} characters.` : ''}
      </span>
    </>
  );
}

export default function PageEditorPage() {
  const params = useParams();
  const pageId = params.id as string;
  const { status: sessionStatus } = useSession();

  const [page, setPage] = useState<PageData | null>(null);
  const [dealer, setDealer] = useState<DealerInfo | null>(null);
  const [navigation, setNavigation] = useState<NavTreeItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [publishing, setPublishing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);
  const [showSettings, setShowSettings] = useState(false);
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const currentPuckDataRef = useRef<Data | null>(null);

  // Settings form state
  const [title, setTitle] = useState('');
  const [slug, setSlug] = useState('');
  const [metaTitle, setMetaTitle] = useState('');
  const [metaDescription, setMetaDescription] = useState('');
  const [excerpt, setExcerpt] = useState('');
  const [author, setAuthor] = useState('');

  // Warn about unsaved changes when leaving page
  useEffect(() => {
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      if (hasUnsavedChanges) {
        e.preventDefault();
        e.returnValue = 'You have unsaved changes. Are you sure you want to leave?';
        return e.returnValue;
      }
    };

    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => window.removeEventListener('beforeunload', handleBeforeUnload);
  }, [hasUnsavedChanges]);

  // Fix space key not working in Puck input fields (Puck intercepts space for drag-drop)
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement;
      // If typing in an input, textarea, or contenteditable (Lexical), stop propagation
      // so Puck doesn't intercept the keypress for drag-drop
      if (
        target.tagName === 'INPUT' ||
        target.tagName === 'TEXTAREA' ||
        target.isContentEditable ||
        target.closest('.lexical-editor-root') ||
        target.closest('.lexical-content-editable')
      ) {
        e.stopPropagation();
      }
    };

    document.addEventListener('keydown', handleKeyDown, true);
    return () => document.removeEventListener('keydown', handleKeyDown, true);
  }, []);

  // Track settings changes
  const handleSettingChange = <T,>(setter: (value: T) => void, value: T) => {
    setter(value);
    setHasUnsavedChanges(true);
  };

  const fetchPage = useCallback(async () => {
    try {
      const response = await fetch(`/api/cms/pages/${pageId}`);
      if (!response.ok) {
        const data = await response.json();
        throw new Error(data.error || 'Failed to fetch page');
      }
      const data = await response.json();
      setPage(data.page);
      setTitle(data.page.title);
      setSlug(data.page.slug);
      setMetaTitle(data.page.metaTitle || '');
      setMetaDescription(data.page.metaDescription || '');
      setExcerpt(data.page.excerpt || '');
      setAuthor(data.page.author || '');
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load page');
    } finally {
      setLoading(false);
    }
  }, [pageId]);

  const fetchDealer = useCallback(async () => {
    try {
      const response = await fetch('/api/dealer');
      if (response.ok) {
        const data = await response.json();
        setDealer(data); // API returns dealer object directly, not { dealer: ... }
      }
    } catch {
      // Silently fail - dealer info is optional for preview
    }
  }, []);

  // Helper to get page path from page data
  const getPagePath = (page: { slug: string; type?: string }): string => {
    return page.type === 'blog' ? `/blog/${page.slug}` : `/${page.slug}`;
  };

  // Transform flat navigation items to tree structure
  const buildNavTree = useCallback((items: NavigationItem[]): NavTreeItem[] => {
    // Filter visible items (all items from API should be visible)
    const parents = items.filter((item) => !item.parentId);
    const childrenByParent = new Map<string, NavigationItem[]>();

    items
      .filter((item) => item.parentId)
      .forEach((item) => {
        const existing = childrenByParent.get(item.parentId!) || [];
        existing.push(item);
        childrenByParent.set(item.parentId!, existing);
      });

    // Sort parents by sortOrder
    parents.sort((a, b) => a.sortOrder - b.sortOrder);

    // Build tree
    return parents.map((parent) => {
      const children = (childrenByParent.get(parent.id) || [])
        .sort((a, b) => a.sortOrder - b.sortOrder)
        .map((child) => ({
          id: child.id,
          label: child.label,
          href: child.externalUrl || (child.page ? getPagePath(child.page) : null),
          openInNewTab: child.openInNewTab,
          children: [], // Max 2 levels
        }));

      return {
        id: parent.id,
        label: parent.label,
        href: parent.externalUrl || (parent.page ? getPagePath(parent.page) : null),
        openInNewTab: parent.openInNewTab,
        children,
      };
    });
  }, []);

  const fetchNavigation = useCallback(async () => {
    try {
      const response = await fetch('/api/cms/navigation');
      if (response.ok) {
        const data = await response.json();
        if (data.items) {
          const tree = buildNavTree(data.items);
          setNavigation(tree);
        }
      }
    } catch {
      // Silently fail - navigation is optional for preview
    }
  }, [buildNavTree]);

  useEffect(() => {
    if (sessionStatus === 'loading') return;
    fetchPage();
    fetchDealer();
    fetchNavigation();
  }, [sessionStatus, fetchPage, fetchDealer, fetchNavigation]);

  // Handle a failed save/publish response: when the failure is field-level
  // validation, open Settings so the dealer can see the offending field and its
  // counter (instead of a cryptic banner over a collapsed panel). Returns the
  // message to throw. Shared by both save paths (handleSave + handlePublish).
  const reportSaveFailure = useCallback(
    (data: { fieldErrors?: Record<string, string[]>; error?: string }): string => {
      if (data.fieldErrors) {
        // Only open Settings when a failing field actually lives in that panel.
        if (Object.keys(data.fieldErrors).some((key) => SETTINGS_PANEL_FIELDS.has(key))) {
          setShowSettings(true);
        }
        // Fall back to a generic message so an empty/unkeyed fieldErrors object
        // can't surface as an empty banner (error="" is falsy → silently hidden).
        return Object.values(data.fieldErrors).flat().join(', ') || 'Validation failed';
      }
      return data.error || 'Failed to save page';
    },
    []
  );

  const handleSave = async (puckData: Data) => {
    if (!page) return;

    setPublishing(true);
    setError(null);
    setSuccessMessage(null);

    try {
      const response = await fetch(`/api/cms/pages/${pageId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          title: title.trim(),
          slug: slug.trim(),
          puckData,
          metaTitle: metaTitle.trim() || null,
          metaDescription: metaDescription.trim() || null,
          excerpt: excerpt.trim() || null,
          author: author.trim() || null,
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(reportSaveFailure(data));
      }

      setPage(data.page);
      setHasUnsavedChanges(false);
      setSuccessMessage('Page saved successfully!');
      setTimeout(() => setSuccessMessage(null), 3000);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save page');
    } finally {
      setPublishing(false);
    }
  };

  const handlePublish = async () => {
    if (!page) return;
    if (publishing) return; // Guard against double-clicks

    setPublishing(true);
    setError(null);
    setSuccessMessage(null);

    try {
      // Step 1: Save page content + set status to published
      const puckData = currentPuckDataRef.current || page.puckData;
      const response = await fetch(`/api/cms/pages/${pageId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          title: title.trim(),
          slug: slug.trim(),
          puckData,
          metaTitle: metaTitle.trim() || null,
          metaDescription: metaDescription.trim() || null,
          excerpt: excerpt.trim() || null,
          author: author.trim() || null,
          status: 'published',
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(reportSaveFailure(data));
      }

      // Step 2: Publish the dealer site
      if (!dealer?.id) {
        throw new Error('Dealer ID not found. Please refresh and try again.');
      }

      const publishResponse = await fetch(`/api/dealers/${dealer.id}/publish`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({}),
      });

      if (!publishResponse.ok) {
        const publishData = await publishResponse.json();
        throw new Error(publishData.error || 'Failed to publish site');
      }

      setPage(data.page);
      setHasUnsavedChanges(false);
      setSuccessMessage('Published successfully!');
      setTimeout(() => setSuccessMessage(null), 3000);
    } catch (err) {
      console.error('Failed to publish:', err);
      setError(err instanceof Error ? err.message : 'Failed to publish');
    } finally {
      setPublishing(false);
    }
  };

  if (loading || sessionStatus === 'loading') {
    return (
      <section className={styles.section}>
        <div className={styles.content}>
          <Card variant="surface">
            <CardBody>
              <div className={styles.emptyState}>
                <p>Loading page...</p>
              </div>
            </CardBody>
          </Card>
        </div>
      </section>
    );
  }

  // Only a *load* failure (no page to edit) replaces the whole screen. A save or
  // publish error must NOT tear down the editor — that would discard the
  // dealer's unsaved Puck edits and strand them on a dead-end page. Those errors
  // surface in the inline banner below (and open Settings via setShowSettings).
  if (!page) {
    return (
      <section className={styles.section}>
        <div className={styles.content}>
          <Card variant="surface">
            <CardBody>
              <div className={styles.emptyState}>
                <h2 className={styles.emptyState__title}>Error</h2>
                <p className={styles.emptyState__description}>{error || 'Page not found'}</p>
                <div style={{ marginTop: '1.5rem' }}>
                  <Link href="/dashboard/cms/pages">
                    <Button variant="primary" size="md">
                      Back to Pages
                    </Button>
                  </Link>
                </div>
              </div>
            </CardBody>
          </Card>
        </div>
      </section>
    );
  }

  // Build initial data with page title prefilled in root
  const initialData: Data = page.puckData
    ? {
        ...page.puckData,
        root: {
          ...page.puckData.root,
          props: {
            ...page.puckData.root?.props,
            title: page.puckData.root?.props?.title || page.title,
          },
        },
      }
    : {
        content: [],
        root: { props: { title: page.title } },
      };

  return (
    <div
      style={{
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
        minHeight: 0,
      }}
    >
      {/* Top Bar */}
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          padding: '0.75rem 1rem',
          borderBottom: '1px solid rgba(148, 163, 184, 0.25)',
          backgroundColor: '#1e293b',
        }}
      >
        <Link
          href="/dashboard/cms/pages"
          style={{ color: '#38bdf8', textDecoration: 'none', fontSize: '0.875rem' }}
        >
          ← Back
        </Link>

        <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
          {/* View Page link - only for active dealers */}
          {dealer?.status === 'active' && page.status === 'published' && (
            <a
              href={(() => {
                const pagePath = page.type === 'blog' ? `blog/${slug}` : slug;
                // Dev path requires the domainSlug segment (the single-segment
                // form /sites/[subdomain] 404s). Prod path must use
                // dealer.domainPrefix (never hardcoded 'myamsoil') so shopamsoil
                // dealers don't get URLs pointing at their sibling's site.
                return process.env.NODE_ENV === 'development'
                  ? `/sites/${dealer.subdomain}/${buildDomainSlug(dealer.domainPrefix, dealer.domain)}/${pagePath}`
                  : `https://${dealer.subdomain}.${dealer.domainPrefix}.${dealer.domain}/${pagePath}`;
              })()}
              target="_blank"
              rel="noopener noreferrer"
              style={{
                color: '#38bdf8',
                textDecoration: 'none',
                fontSize: '0.875rem',
                marginRight: '0.5rem',
              }}
            >
              View Page →
            </a>
          )}
          <Button variant="secondary" size="sm" onClick={() => setShowSettings(!showSettings)}>
            Settings
          </Button>
          <Button variant="primary" size="sm" onClick={handlePublish} disabled={publishing}>
            {publishing ? 'Publishing...' : 'Publish'}
          </Button>
        </div>
      </div>

      {/* Settings Panel */}
      {showSettings && (
        <div
          style={{
            padding: '1rem',
            borderBottom: '1px solid #e5e7eb',
            backgroundColor: '#f9fafb',
          }}
        >
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
              gap: '1rem',
            }}
          >
            <div>
              <label
                style={{
                  display: 'block',
                  fontWeight: 500,
                  marginBottom: '0.25rem',
                  fontSize: '0.875rem',
                  color: '#000',
                }}
              >
                Title
              </label>
              <input
                type="text"
                value={title}
                onChange={(e) => handleSettingChange(setTitle, e.target.value)}
                style={{
                  width: '100%',
                  padding: '0.5rem',
                  border: '1px solid #ddd',
                  borderRadius: '4px',
                  fontSize: '0.875rem',
                  color: '#000',
                  backgroundColor: '#fff',
                }}
              />
            </div>
            <div>
              <label
                style={{
                  display: 'block',
                  fontWeight: 500,
                  marginBottom: '0.25rem',
                  fontSize: '0.875rem',
                  color: '#000',
                }}
              >
                Slug
              </label>
              <input
                type="text"
                value={slug}
                onChange={(e) => {
                  const sanitizedSlug = e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, '');
                  handleSettingChange(setSlug, sanitizedSlug);
                }}
                style={{
                  width: '100%',
                  padding: '0.5rem',
                  border: '1px solid #ddd',
                  borderRadius: '4px',
                  fontSize: '0.875rem',
                  color: '#000',
                  backgroundColor: '#fff',
                }}
              />
            </div>
            <div>
              <label
                style={{
                  display: 'block',
                  fontWeight: 500,
                  marginBottom: '0.25rem',
                  fontSize: '0.875rem',
                  color: '#000',
                }}
              >
                Meta Title (SEO)
              </label>
              <input
                type="text"
                value={metaTitle}
                onChange={(e) => handleSettingChange(setMetaTitle, e.target.value)}
                placeholder="Override page title for SEO"
                aria-describedby="meta-title-count"
                style={{
                  width: '100%',
                  padding: '0.5rem',
                  border: '1px solid #ddd',
                  borderRadius: '4px',
                  fontSize: '0.875rem',
                  color: '#000',
                  backgroundColor: '#fff',
                }}
              />
              <CharCounter
                id="meta-title-count"
                count={metaTitle.trim().length}
                max={META_TITLE_MAX}
              />
            </div>
            <div>
              <label
                style={{
                  display: 'block',
                  fontWeight: 500,
                  marginBottom: '0.25rem',
                  fontSize: '0.875rem',
                  color: '#000',
                }}
              >
                Meta Description
              </label>
              <textarea
                value={metaDescription}
                onChange={(e) => handleSettingChange(setMetaDescription, e.target.value)}
                placeholder="Description for search engines"
                rows={3}
                aria-describedby="meta-description-count"
                style={{
                  width: '100%',
                  padding: '0.5rem',
                  border: '1px solid #ddd',
                  borderRadius: '4px',
                  fontSize: '0.875rem',
                  color: '#000',
                  backgroundColor: '#fff',
                  fontFamily: 'inherit',
                  resize: 'vertical',
                }}
              />
              <CharCounter
                id="meta-description-count"
                count={metaDescription.trim().length}
                max={META_DESCRIPTION_MAX}
              />
            </div>
            {page.type === 'blog' && (
              <>
                <div>
                  <label
                    style={{
                      display: 'block',
                      fontWeight: 500,
                      marginBottom: '0.25rem',
                      fontSize: '0.875rem',
                      color: '#000',
                    }}
                  >
                    Author
                  </label>
                  <input
                    type="text"
                    value={author}
                    onChange={(e) => handleSettingChange(setAuthor, e.target.value)}
                    placeholder="Author name"
                    aria-describedby="author-count"
                    style={{
                      width: '100%',
                      padding: '0.5rem',
                      border: '1px solid #ddd',
                      borderRadius: '4px',
                      fontSize: '0.875rem',
                      color: '#000',
                      backgroundColor: '#fff',
                    }}
                  />
                  <CharCounter id="author-count" count={author.trim().length} max={AUTHOR_MAX} />
                </div>
                <div>
                  <label
                    style={{
                      display: 'block',
                      fontWeight: 500,
                      marginBottom: '0.25rem',
                      fontSize: '0.875rem',
                      color: '#000',
                    }}
                  >
                    Excerpt
                  </label>
                  <textarea
                    value={excerpt}
                    onChange={(e) => handleSettingChange(setExcerpt, e.target.value)}
                    placeholder="Short summary for blog listing"
                    aria-describedby="excerpt-count"
                    rows={3}
                    style={{
                      width: '100%',
                      padding: '0.5rem',
                      border: '1px solid #ddd',
                      borderRadius: '4px',
                      fontSize: '0.875rem',
                      color: '#000',
                      backgroundColor: '#fff',
                      fontFamily: 'inherit',
                      resize: 'vertical',
                    }}
                  />
                  <CharCounter id="excerpt-count" count={excerpt.trim().length} max={EXCERPT_MAX} />
                </div>
              </>
            )}
          </div>
        </div>
      )}

      {/* Success Banner */}
      {successMessage && (
        <div
          style={{
            padding: '0.75rem 1rem',
            backgroundColor: 'rgba(52, 211, 153, 0.1)',
            borderBottom: '1px solid rgba(52, 211, 153, 0.35)',
            borderLeft: '4px solid #34d399',
            color: '#d1fae5',
            fontSize: '0.875rem',
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          {successMessage}
          <button
            onClick={() => setSuccessMessage(null)}
            style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#34d399' }}
          >
            ✕
          </button>
        </div>
      )}

      {/* Error Banner */}
      {error && (
        <div
          style={{
            padding: '0.75rem 1rem',
            backgroundColor: 'rgba(248, 113, 113, 0.1)',
            borderBottom: '1px solid rgba(248, 113, 113, 0.35)',
            borderLeft: '4px solid #f87171',
            color: '#fee2e2',
            fontSize: '0.875rem',
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          {error}
          <button
            onClick={() => setError(null)}
            style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#f87171' }}
          >
            ✕
          </button>
        </div>
      )}

      {/* Puck Editor */}
      <style>{`
        /* Preview canvas white background */
        [class*="Puck-canvas"],
        [class*="PuckCanvas"],
        [class*="_Puck-canvas"],
        [class*="_PuckCanvas"] {
          background-color: #ffffff !important;
        }
        /* Remove padding from root dropzone - handled by preview wrapper */
        [data-puck-dropzone="root:default-zone"] {
          padding: 0;
          background-color: #ffffff;
        }
        /* Fix white-on-white inputs and labels in Puck sidebar */
        [class*="Puck"] input,
        [class*="Puck"] textarea,
        [class*="Puck"] select {
          color: #000 !important;
          background-color: #fff !important;
        }
        [class*="Puck"] input::placeholder,
        [class*="Puck"] textarea::placeholder {
          color: #6b7280 !important;
        }
        [class*="Puck"] label {
          color: #000 !important;
        }
        /* Fix viewport controls - default accessible color on white */
        [class*="ViewportButton"]:not([class*="--isActive"]) svg {
          stroke: #6b7280 !important;
          color: #6b7280 !important;
        }
        /* Active viewport button gets dark color */
        [class*="--isActive"] svg {
          stroke: #000 !important;
          color: #000 !important;
        }
        /* Hover states for accordion buttons */
        .cms-accordion button:hover {
          background-color: #f0f0f0 !important;
        }
        /* Hover states for tab buttons */
        .cms-tabs button:hover {
          color: #093b66 !important;
          background-color: #f5f5f5;
        }
        /* Two-column dropzone styling - matches cms.css */
        .cms-two-column [data-puck-dropzone] {
          min-height: 100px;
          border: 1px dashed #c6c6c6;
          border-radius: 8px;
          padding: 0.75rem;
          background-color: #fafafa;
        }
        /* Spacer visual indicator in editor */
        .cms-spacer {
          border: 1px dotted #c6c6c6;
          border-radius: 4px;
          background-color: #fafafa;
        }
        /* ViewportControls - balanced vertical padding */
        [class*="ViewportControls_"] {
          padding-top: 8px !important;
          padding-bottom: 8px !important;
        }
        /* PuckCanvas - remove padding and hide overflow to prevent extra scrollbar */
        [class*="PuckCanvas_"] {
          padding: 0 !important;
          overflow: hidden !important;
        }
        /* ViewportControls zoom select - left padding */
        [class*="ViewportControls-zoomSelect"] {
          padding-left: 8px !important;
        }
        /* Preview iframe - fill available space minus custom header (64px) */
        [class*="PuckPreview"] iframe {
          height: calc(100% - 64px) !important;
        }
        /* Sidebars - account for our custom header (64px) */
        [class*="_Sidebar"][class*="--left"],
        [class*="_Sidebar"][class*="--right"] {
          height: calc(100% - 64px) !important;
        }
        /* Rich text links match cms.css */
        .cms-rich-text a {
          color: #093b66;
          text-decoration: underline;
        }
        .cms-rich-text a:hover {
          color: #f8981d;
        }
      `}</style>
      <div style={{ flex: 1, overflow: 'hidden', minHeight: 0 }}>
        <PuckErrorBoundary onReset={fetchPage}>
          <Puck
            config={puckConfig}
            data={initialData}
            headerTitle={page.title}
            onChange={(data) => {
              currentPuckDataRef.current = data;
              if (!hasUnsavedChanges) setHasUnsavedChanges(true);
            }}
            onPublish={handleSave}
            overrides={{
              // Hide Puck's default header actions - we have our own Publish button in the top bar
              headerActions: () => <></>,
              iframe: function IframeWrapper({ children, document: iframeDoc }) {
                // Get dealer info for header/footer inside iframe
                const dealerName =
                  dealer?.businessName || dealer?.contactName || 'Your Dealer Name';
                const dealerCity = dealer?.city || 'City';
                const dealerState = dealer?.state || 'ST';
                const dealerPhone = dealer?.phone || '(555) 123-4567';
                const dealerEmail = dealer?.contactEmail || 'contact@dealer.com';

                useEffect(() => {
                  // Apply styles with null checks for documentElement and body
                  if (iframeDoc?.documentElement && iframeDoc?.body) {
                    try {
                      // Let iframe body flow naturally - content grows, iframe scrolls
                      iframeDoc.documentElement.style.cssText = 'margin: 0; background: #fff;';
                      iframeDoc.body.style.cssText = 'margin: 0; padding: 0; background: #fff;';
                    } catch {
                      // Silently handle edge cases (detached document, etc.)
                    }
                  }
                }, [iframeDoc]);

                return (
                  <>
                    {/* Header inside iframe for true WYSIWYG */}
                    <header
                      style={{
                        background: 'linear-gradient(180deg, #1a1a1a 0%, #2d2d2d 100%)',
                        color: '#fff',
                        padding: 0,
                      }}
                    >
                      <div
                        style={{
                          display: 'flex',
                          justifyContent: 'space-between',
                          alignItems: 'center',
                          padding: '0.5rem 1rem',
                          borderBottom: '1px solid rgba(255,255,255,0.1)',
                          fontSize: '0.75rem',
                        }}
                      >
                        <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
                          <Image
                            src="/images/logo/amsoil-logo.png"
                            alt="AMSOIL"
                            width={120}
                            height={30}
                            style={{ objectFit: 'contain' }}
                          />
                          <span
                            style={{
                              color: '#f8981d',
                              fontWeight: 600,
                              fontSize: '0.65rem',
                              textTransform: 'uppercase',
                            }}
                          >
                            Independent Dealer
                          </span>
                        </div>
                        <div style={{ display: 'flex', gap: '1.5rem', color: '#ccc' }}>
                          <span>
                            📍 {dealerCity}, {dealerState}
                          </span>
                          <span>📞 {dealerPhone}</span>
                        </div>
                      </div>
                      <div
                        style={{
                          display: 'flex',
                          justifyContent: 'space-between',
                          alignItems: 'center',
                          padding: '0.75rem 1rem',
                        }}
                      >
                        <h1
                          style={{ margin: 0, fontSize: '1.25rem', fontWeight: 700, color: '#fff' }}
                        >
                          {dealerName}
                        </h1>
                        {navigation.length > 0 ? (
                          <nav style={{ display: 'flex', gap: '1.25rem', fontSize: '0.8rem' }}>
                            {navigation.map((item, index) => (
                              <div
                                key={item.id}
                                style={{ position: 'relative' }}
                                className="nav-preview-item"
                              >
                                <span
                                  style={{
                                    color: index === 0 ? '#f8981d' : '#ccc',
                                    cursor: 'pointer',
                                    fontWeight: 600,
                                    display: 'inline-flex',
                                    alignItems: 'center',
                                    gap: '0.25rem',
                                  }}
                                >
                                  {item.label}
                                  {item.children.length > 0 && (
                                    <span style={{ fontSize: '0.6rem', opacity: 0.7 }}>▾</span>
                                  )}
                                </span>
                              </div>
                            ))}
                          </nav>
                        ) : (
                          <nav style={{ display: 'flex', gap: '1.5rem', fontSize: '0.8rem' }}>
                            <span style={{ color: '#ccc', fontStyle: 'italic', opacity: 0.6 }}>
                              No navigation items configured
                            </span>
                          </nav>
                        )}
                      </div>
                    </header>
                    {/* Main content area - Puck components go here */}
                    <main
                      style={{
                        padding: '0 12px',
                        background: '#fff',
                      }}
                    >
                      {children}
                    </main>
                    <footer
                      style={{
                        background: '#1a1a1a',
                        color: '#fff',
                        padding: '1.5rem 1rem',
                      }}
                    >
                      <div
                        style={{
                          display: 'grid',
                          gridTemplateColumns: 'repeat(4, 1fr)',
                          gap: '2rem',
                          maxWidth: '1200px',
                          margin: '0 auto',
                          fontSize: '0.8rem',
                        }}
                      >
                        <div>
                          <Image
                            src="/images/logo/amsoil-logo.png"
                            alt="AMSOIL"
                            width={140}
                            height={35}
                            style={{ objectFit: 'contain', filter: 'brightness(0) invert(1)' }}
                          />
                        </div>
                        <div>
                          <h4
                            style={{
                              color: '#f8981d',
                              marginBottom: '0.75rem',
                              fontSize: '0.75rem',
                              fontWeight: 600,
                            }}
                          >
                            PRODUCTS
                          </h4>
                          <div style={{ color: '#999', lineHeight: 1.8 }}>
                            Motor Oil • Hydraulic Oil • Transmission Fluid • Gear Lube • Fuel
                            Additives
                          </div>
                        </div>
                        <div>
                          <h4
                            style={{
                              color: '#f8981d',
                              marginBottom: '0.75rem',
                              fontSize: '0.75rem',
                              fontWeight: 600,
                            }}
                          >
                            VEHICLE
                          </h4>
                          <div style={{ color: '#999', lineHeight: 1.8 }}>
                            Auto/Light Truck • Motorcycle • ATV/UTV • Marine • Snowmobile • Heavy
                            Duty
                          </div>
                        </div>
                        <div>
                          <h4
                            style={{
                              color: '#f8981d',
                              marginBottom: '0.75rem',
                              fontSize: '0.75rem',
                              fontWeight: 600,
                            }}
                          >
                            CONTACT
                          </h4>
                          <div style={{ color: '#999', lineHeight: 1.8 }}>
                            <strong style={{ color: '#fff' }}>{dealerName}</strong>
                            <br />
                            {dealerCity}, {dealerState}
                            <br />
                            {dealerPhone}
                            <br />
                            {dealerEmail}
                          </div>
                        </div>
                      </div>
                      <div
                        style={{
                          borderTop: '1px solid rgba(255,255,255,0.1)',
                          marginTop: '1.5rem',
                          paddingTop: '1rem',
                          textAlign: 'center',
                          color: '#666',
                          fontSize: '0.7rem',
                        }}
                      >
                        © AMSOIL INC. {new Date().getFullYear()}
                      </div>
                    </footer>
                  </>
                );
              },
            }}
          />
        </PuckErrorBoundary>
      </div>
    </div>
  );
}
