import React, { useCallback, useState } from 'react';
import { useEditor } from '@craftjs/core';
import { useIsMobile } from '../../hooks/useIsMobile';
import { useMobileChrome } from '../../state/MobileChromeContext';
import { Container } from '../../components/layout/Container';
import { Section } from '../../components/layout/Section';
import { ColumnLayout } from '../../components/layout/ColumnLayout';
import { BackgroundSection } from '../../components/layout/BackgroundSection';
import { Heading } from '../../components/basic/Heading';
import { TextBlock } from '../../components/basic/TextBlock';
import { ButtonLink } from '../../components/basic/ButtonLink';
import { Logo } from '../../components/basic/Logo';
import { Menu } from '../../components/basic/Menu';
import { Footer } from '../../components/basic/Footer';
import { Divider } from '../../components/basic/Divider';
import { Spacer } from '../../components/basic/Spacer';
import { Icon } from '../../components/basic/Icon';
import { HtmlBlock } from '../../components/basic/HtmlBlock';
import { ImageBlock } from '../../components/media/ImageBlock';
import { VideoBlock } from '../../components/media/VideoBlock';
import { MapEmbed } from '../../components/media/MapEmbed';
import { HeroSimple } from '../../components/sections/HeroSimple';
import { FeaturesGrid } from '../../components/sections/FeaturesGrid';
import { CallToAction } from '../../components/sections/CallToAction';
import { Countdown } from '../../components/sections/Countdown';
import { Testimonials } from '../../components/sections/Testimonials';
import { Accordion } from '../../components/sections/Accordion';
import { Tabs } from '../../components/sections/Tabs';
import { PricingTable } from '../../components/sections/PricingTable';
import { Gallery } from '../../components/sections/Gallery';
import { ContentSlider } from '../../components/sections/ContentSlider';
import { NumberCounter } from '../../components/sections/NumberCounter';
import { FormContainer } from '../../components/forms/FormContainer';
import { InputField } from '../../components/forms/InputField';
import { TextareaField } from '../../components/forms/TextareaField';
import { FormButton } from '../../components/forms/FormButton';
import { ContactForm } from '../../components/forms/ContactForm';
import { SubscribeForm } from '../../components/forms/SubscribeForm';
import { StarRating } from '../../components/basic/StarRating';
import { SocialLinks } from '../../components/basic/SocialLinks';

interface BlockDef {
  id: string;
  label: string;
  icon: string;
  component: React.ReactElement;
}

interface CategoryDef {
  id: string;
  label: string;
  blocks: BlockDef[];
}

const categories: CategoryDef[] = [
  {
    id: 'basic',
    label: 'Basic',
    blocks: [
      { id: 'heading', label: 'Heading', icon: 'fa-header',
        component: <Heading text="Your Heading" level="h2" style={{ fontSize: '36px', fontWeight: '700', fontFamily: 'Inter, sans-serif', color: '#1f2937', marginBottom: '16px' }} /> },
      { id: 'text', label: 'Text', icon: 'fa-paragraph',
        component: <TextBlock text="Add your text here. Click to edit." style={{ fontSize: '16px', lineHeight: '1.6', color: '#4b5563', fontFamily: 'Inter, sans-serif' }} /> },
      { id: 'button', label: 'Button', icon: 'fa-square',
        component: <ButtonLink text="Click Me" href="#" style={{ display: 'inline-block', padding: '14px 32px', background: '#3b82f6', color: '#ffffff', textDecoration: 'none', borderRadius: '8px', fontWeight: '600', fontSize: '16px', fontFamily: 'Inter, sans-serif' }} /> },
      { id: 'logo', label: 'Logo', icon: 'fa-bookmark', component: <Logo /> },
      { id: 'menu', label: 'Menu', icon: 'fa-bars', component: <Menu /> },
      { id: 'footer', label: 'Footer', icon: 'fa-window-minimize', component: <Footer /> },
      { id: 'divider', label: 'Divider', icon: 'fa-minus', component: <Divider /> },
      { id: 'spacer', label: 'Spacer', icon: 'fa-arrows-v', component: <Spacer /> },
      { id: 'icon', label: 'Icon', icon: 'fa-star', component: <Icon icon="fa-star" size="48px" color="#3b82f6" /> },
      { id: 'star-rating', label: 'Star Rating', icon: 'fa-star-half-o', component: <StarRating /> },
      { id: 'social-links', label: 'Social Links', icon: 'fa-share-alt', component: <SocialLinks /> },
      { id: 'html-block', label: 'HTML', icon: 'fa-code', component: <HtmlBlock code="<div>Custom HTML</div>" /> },
    ],
  },
  {
    id: 'layout',
    label: 'Layout',
    blocks: [
      { id: 'section', label: 'Section', icon: 'fa-window-maximize',
        component: <Section style={{ padding: '60px 20px', backgroundColor: '#ffffff' }} /> },
      { id: 'container', label: 'Container', icon: 'fa-square-o',
        component: <Container style={{ padding: '20px', minHeight: '100px' }} /> },
      { id: 'columns-1', label: '1 Column', icon: 'fa-stop',
        component: <ColumnLayout columns={1} split="100" /> },
      { id: 'columns-2', label: '2 Columns', icon: 'fa-th-large',
        component: <ColumnLayout columns={2} split="50-50" /> },
      { id: 'columns-3', label: '3 Columns', icon: 'fa-th',
        component: <ColumnLayout columns={3} split="33-33-33" /> },
      { id: 'columns-4', label: '4 Columns', icon: 'fa-th',
        component: <ColumnLayout columns={4} split="25-25-25-25" /> },
      { id: 'columns-5', label: '5 Columns', icon: 'fa-th',
        component: <ColumnLayout columns={5} split="20-20-20-20-20" /> },
      { id: 'columns-6', label: '6 Columns', icon: 'fa-th',
        component: <ColumnLayout columns={6} split="16-16-16-16-16-16" /> },
      { id: 'sidebar-left', label: 'Sidebar Left', icon: 'fa-columns',
        component: <ColumnLayout columns={2} split="30-70" /> },
      { id: 'sidebar-right', label: 'Sidebar Right', icon: 'fa-columns',
        component: <ColumnLayout columns={2} split="70-30" /> },
      { id: 'bg-section', label: 'BG Section', icon: 'fa-picture-o', component: <BackgroundSection /> },
    ],
  },
  {
    id: 'sections',
    label: 'Sections',
    blocks: [
      { id: 'hero-simple', label: 'Hero', icon: 'fa-star', component: <HeroSimple /> },
      { id: 'features-grid', label: 'Features', icon: 'fa-th-large', component: <FeaturesGrid /> },
      { id: 'cta-section', label: 'CTA', icon: 'fa-bullhorn', component: <CallToAction /> },
      { id: 'accordion', label: 'Accordion', icon: 'fa-list', component: <Accordion /> },
      { id: 'tabs', label: 'Tabs', icon: 'fa-folder-o', component: <Tabs /> },
      { id: 'pricing-table', label: 'Pricing', icon: 'fa-usd', component: <PricingTable /> },
      { id: 'gallery', label: 'Gallery', icon: 'fa-th', component: <Gallery /> },
      { id: 'countdown', label: 'Countdown', icon: 'fa-clock-o',
        component: <Countdown targetDate={new Date(Date.now() + 30 * 86400000).toISOString()} /> },
      { id: 'testimonials', label: 'Testimonials', icon: 'fa-quote-left',
        component: <Testimonials testimonials={[{ quote: "Great service!", name: "John", title: "CEO", rating: 5 }]} layout="grid" columns={3} /> },
      { id: 'content-slider', label: 'Slider', icon: 'fa-sliders', component: <ContentSlider /> },
      { id: 'number-counter', label: 'Counters', icon: 'fa-sort-numeric-asc', component: <NumberCounter /> },
    ],
  },
  {
    id: 'media',
    label: 'Media',
    blocks: [
      { id: 'image', label: 'Image', icon: 'fa-image',
        component: <ImageBlock alt="Image" style={{ maxWidth: '100%', height: 'auto', display: 'block', borderRadius: '8px' }} /> },
      { id: 'video', label: 'Video', icon: 'fa-play-circle',
        component: <VideoBlock videoUrl="" isBackground={false} /> },
      { id: 'map-embed', label: 'Map', icon: 'fa-map-marker',
        component: <MapEmbed address="New York, NY" zoom={14} height="400px" /> },
    ],
  },
  {
    id: 'forms',
    label: 'Forms',
    blocks: [
      { id: 'contact-form', label: 'Contact Form', icon: 'fa-envelope', component: <ContactForm /> },
      { id: 'subscribe-form', label: 'Subscribe', icon: 'fa-paper-plane', component: <SubscribeForm /> },
      { id: 'form-container', label: 'Form', icon: 'fa-wpforms', component: <FormContainer /> },
      { id: 'input-field', label: 'Input', icon: 'fa-i-cursor', component: <InputField /> },
      { id: 'textarea-field', label: 'Textarea', icon: 'fa-align-left', component: <TextareaField /> },
      { id: 'form-button', label: 'Submit', icon: 'fa-paper-plane', component: <FormButton /> },
    ],
  },
];

export const BlocksPanel: React.FC = () => {
  const { connectors, actions, query } = useEditor();
  const isMobile = useIsMobile();
  const { closeSheet } = useMobileChrome();
  const [collapsed, setCollapsed] = useState<Record<string, boolean>>(() => {
    const initial: Record<string, boolean> = {};
    categories.forEach((cat, index) => {
      initial[cat.id] = index !== 0; // First category open
    });
    return initial;
  });

  const toggleCategory = (categoryId: string) => {
    setCollapsed((prev) => ({ ...prev, [categoryId]: !prev[categoryId] }));
  };

  /** Default insertion target when there's no usable selection to anchor
   *  to: the first real Craft.js canvas in the document (falls back to
   *  ROOT). Extracted from the pre-existing onDoubleClick handler so
   *  tap-to-add (mobile, item 3) and double-click (desktop, unchanged) share
   *  the exact same fallback. */
  const findDefaultCanvasId = useCallback((): string => {
    try {
      const serialized = JSON.parse(query.serialize());
      const nodeIds = Object.keys(serialized);
      for (const id of nodeIds) {
        if (serialized[id].isCanvas && id !== 'ROOT') return id;
      }
    } catch {
      // Fall through to ROOT below.
    }
    return 'ROOT';
  }, [query]);

  /**
   * Builds a fresh node tree for `block` and inserts it into the canvas,
   * returning the new node's id (or null on failure). Shared by desktop's
   * double-click (unchanged behavior/position: always appended to
   * `findDefaultCanvasId()`) and mobile's tap-to-add (item 3), which instead
   * prefers inserting as a sibling right after the current selection --
   * `insertAfterSelection: true` only from the mobile tap handler below.
   */
  const addBlockNode = useCallback((block: BlockDef, insertAfterSelection: boolean): string | null => {
    try {
      const tree = query.parseReactElement(React.cloneElement(block.component)).toNodeTree();

      let inserted = false;
      if (insertAfterSelection) {
        try {
          const selectedIds = query.getEvent('selected').all();
          const selectedId = selectedIds.length > 0 ? selectedIds[0] : null;
          if (selectedId && selectedId !== 'ROOT') {
            const selectedNode = query.node(selectedId).get();
            const parentId = selectedNode?.data?.parent;
            if (parentId) {
              const parent = query.node(parentId).get();
              const siblings: string[] = parent?.data?.nodes || [];
              const idx = siblings.indexOf(selectedId);
              if (idx !== -1) {
                actions.addNodeTree(tree, parentId, idx + 1);
                inserted = true;
              }
            }
          }
        } catch {
          // Selection isn't a valid sibling target (e.g. lives in a
          // linkedNodes slot) -- fall through to the default canvas below.
        }
      }

      if (!inserted) {
        actions.addNodeTree(tree, findDefaultCanvasId());
      }

      return tree.rootNodeId;
    } catch (e) {
      console.error('Failed to add block:', e);
      return null;
    }
  }, [query, actions, findDefaultCanvasId]);

  /**
   * Mobile tap-to-add (item 3): a single tap on a block tile inserts it,
   * closes the Blocks sheet, then selects the new node and scrolls it into
   * view so the user immediately sees it (and gets the selection toolbar).
   * The select/scroll step is deferred two animation frames past the
   * `addNodeTree` call -- Craft.js's own state update (and thus the new
   * node's real DOM element) lands asynchronously after this handler
   * returns, so `query.node(id).get().dom` isn't populated yet if read
   * synchronously here.
   */
  const handleTapToAdd = useCallback((block: BlockDef) => {
    const newId = addBlockNode(block, true);
    closeSheet();
    if (!newId) return;
    requestAnimationFrame(() => {
      try {
        actions.selectNode(newId);
      } catch {
        // Node may have failed to mount -- nothing to select.
      }
      requestAnimationFrame(() => {
        try {
          query.node(newId).get()?.dom?.scrollIntoView({ behavior: 'smooth', block: 'center' });
        } catch {
          // Best-effort scroll -- not fatal if the node/DOM isn't found.
        }
      });
    });
  }, [addBlockNode, closeSheet, actions, query]);

  return (
    <div>
      {categories.map((category) => {
        const isCollapsed = collapsed[category.id];
        return (
          <div key={category.id} className="block-category">
            <div
              className={`block-category-header ${isCollapsed ? 'collapsed' : ''}`}
              onClick={() => toggleCategory(category.id)}
            >
              <span>{category.label}</span>
              <i className="fa fa-chevron-down chevron" />
            </div>
            <div className={`block-category-items ${isCollapsed ? 'collapsed' : ''}`}>
              <div className="block-grid">
                {category.blocks.map((block) => (
                  <div
                    key={block.id}
                    className="block-item"
                    ref={(ref) => { if (ref) connectors.create(ref, block.component); }}
                    onDoubleClick={() => addBlockNode(block, false)}
                    onClick={isMobile ? () => handleTapToAdd(block) : undefined}
                    title={isMobile ? `Tap to add ${block.label}` : `Drag or double-click to add ${block.label}`}
                  >
                    <i className={`fa ${block.icon} block-item-icon`} />
                    <span className="block-item-label">{block.label}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
};
