/**
 * Tests for marketing block schema registration
 *
 * Verifies all blocks have the expected fields and defaults.
 */
import { describe, it, expect } from 'vitest';

import { puckConfig } from '../config';

describe('Marketing Block Schemas', () => {
  describe('Header block', () => {
    const block = puckConfig.components.Header;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have brand fields', () => {
      expect(block.fields.brandText).toBeDefined();
      expect(block.fields.brandLogo).toBeDefined();
    });

    it('should have links field', () => {
      expect(block.fields.links).toBeDefined();
      expect(block.fields.links.type).toBe('array');
    });

    it('should have CTA button field', () => {
      expect(block.fields.ctaButton).toBeDefined();
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
      const options = block.fields.variant.options;
      expect(options.some((o: { value: string }) => o.value === 'transparent-on-dark')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'light')).toBe(true);
    });

    it('should have mobile menu toggle', () => {
      expect(block.fields.showMobileMenu).toBeDefined();
    });

    it('should have sensible defaults', () => {
      expect(block.defaultProps).toBeDefined();
      expect(block.defaultProps.variant).toBe('light');
      expect(block.defaultProps.showMobileMenu).toBe(true);
    });
  });

  describe('Hero block', () => {
    const block = puckConfig.components.Hero;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have headline and subheadline', () => {
      expect(block.fields.headline).toBeDefined();
      expect(block.fields.subheadline).toBeDefined();
    });

    it('should have primary and secondary CTA', () => {
      expect(block.fields.primaryCta).toBeDefined();
      expect(block.fields.secondaryCta).toBeDefined();
    });

    it('should have background variant with gradient option', () => {
      expect(block.fields.backgroundVariant).toBeDefined();
      const options = block.fields.backgroundVariant.options;
      expect(options.some((o: { value: string }) => o.value === 'gradient')).toBe(true);
    });

    it('should have gradient preset field', () => {
      expect(block.fields.gradientPreset).toBeDefined();
    });

    it('should have media field', () => {
      expect(block.fields.media).toBeDefined();
    });

    it('should have optional badge field', () => {
      expect(block.fields.badge).toBeDefined();
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
    });

    it('should have fullWidth field', () => {
      expect(block.fields.fullWidth).toBeDefined();
    });
  });

  describe('LogoCloud block', () => {
    const block = puckConfig.components.LogoCloud;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have optional heading', () => {
      expect(block.fields.heading).toBeDefined();
    });

    it('should have logos array', () => {
      expect(block.fields.logos).toBeDefined();
      expect(block.fields.logos.type).toBe('array');
    });

    it('should have grayscale toggle', () => {
      expect(block.fields.grayscale).toBeDefined();
    });

    it('should have spacing density', () => {
      expect(block.fields.spacingDensity).toBeDefined();
    });
  });

  describe('SplitContent block', () => {
    const block = puckConfig.components.SplitContent;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have eyebrow label', () => {
      expect(block.fields.eyebrow).toBeDefined();
    });

    it('should have heading', () => {
      expect(block.fields.heading).toBeDefined();
    });

    it('should have rich text content', () => {
      expect(block.fields.content).toBeDefined();
    });

    it('should have bullets list', () => {
      expect(block.fields.bullets).toBeDefined();
      expect(block.fields.bullets.type).toBe('array');
    });

    it('should have optional CTA', () => {
      expect(block.fields.cta).toBeDefined();
    });

    it('should have media field', () => {
      expect(block.fields.media).toBeDefined();
    });

    it('should have media position (left/right)', () => {
      expect(block.fields.mediaPosition).toBeDefined();
      const options = block.fields.mediaPosition.options;
      expect(options.some((o: { value: string }) => o.value === 'left')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'right')).toBe(true);
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
    });
  });

  describe('CTASection block', () => {
    const block = puckConfig.components.CTASection;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have heading', () => {
      expect(block.fields.heading).toBeDefined();
    });

    it('should have supporting text', () => {
      expect(block.fields.supportingText).toBeDefined();
    });

    it('should have buttons', () => {
      expect(block.fields.buttons).toBeDefined();
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
      const options = block.fields.variant.options;
      expect(options.some((o: { value: string }) => o.value === 'light')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'dark')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'gradient')).toBe(true);
    });
  });

  describe('StatsStrip block', () => {
    const block = puckConfig.components.StatsStrip;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have stats array', () => {
      expect(block.fields.stats).toBeDefined();
      expect(block.fields.stats.type).toBe('array');
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
    });

    it('should default to 4 stats', () => {
      expect(block.defaultProps.stats.length).toBe(4);
    });
  });

  describe('GalleryGrid block', () => {
    const block = puckConfig.components.GalleryGrid;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have items array', () => {
      expect(block.fields.items).toBeDefined();
      expect(block.fields.items.type).toBe('array');
    });

    it('should have columns per breakpoint', () => {
      expect(block.fields.columnsMobile).toBeDefined();
      expect(block.fields.columnsTablet).toBeDefined();
      expect(block.fields.columnsDesktop).toBeDefined();
    });
  });

  describe('Testimonials block', () => {
    const block = puckConfig.components.Testimonials;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have items array', () => {
      expect(block.fields.items).toBeDefined();
      expect(block.fields.items.type).toBe('array');
    });

    it('should have layout field', () => {
      expect(block.fields.layout).toBeDefined();
      const options = block.fields.layout.options;
      expect(options.some((o: { value: string }) => o.value === 'carousel')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'stacked')).toBe(true);
    });

    it('should have rating stars toggle', () => {
      expect(block.fields.showRating).toBeDefined();
    });
  });

  describe('VideoEmbed block', () => {
    const block = puckConfig.components.VideoEmbed;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have heading and text', () => {
      expect(block.fields.heading).toBeDefined();
      expect(block.fields.text).toBeDefined();
    });

    it('should have thumbnail image', () => {
      expect(block.fields.thumbnailImage).toBeDefined();
    });

    it('should have video provider field with allowlist', () => {
      expect(block.fields.provider).toBeDefined();
      const options = block.fields.provider.options;
      expect(options.some((o: { value: string }) => o.value === 'youtube')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'vimeo')).toBe(true);
      // Should NOT have arbitrary options
      expect(options.length).toBe(2);
    });

    it('should have video ID field', () => {
      expect(block.fields.videoId).toBeDefined();
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
    });
  });

  describe('ContentBlocks block', () => {
    const block = puckConfig.components.ContentBlocks;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have features array', () => {
      expect(block.fields.features).toBeDefined();
      expect(block.fields.features.type).toBe('array');
    });

    it('should have section heading', () => {
      expect(block.fields.sectionHeading).toBeDefined();
    });
  });

  describe('PricingCards block', () => {
    const block = puckConfig.components.PricingCards;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have currency field', () => {
      expect(block.fields.currency).toBeDefined();
    });

    it('should have billing period label', () => {
      expect(block.fields.billingPeriod).toBeDefined();
    });

    it('should have plans array', () => {
      expect(block.fields.plans).toBeDefined();
      expect(block.fields.plans.type).toBe('array');
    });

    it('should have highlight plan index', () => {
      expect(block.fields.highlightIndex).toBeDefined();
    });

    it('should have recommended badge text', () => {
      expect(block.fields.popularBadgeText).toBeDefined();
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
    });

    it('should default to 3 plans with middle highlighted', () => {
      expect(block.defaultProps.plans.length).toBe(3);
      expect(block.defaultProps.highlightIndex).toBe(1);
    });
  });

  describe('Footer block', () => {
    const block = puckConfig.components.Footer;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have brand logo/text', () => {
      expect(block.fields.brandLogo).toBeDefined();
      expect(block.fields.brandText).toBeDefined();
    });

    it('should have description', () => {
      expect(block.fields.description).toBeDefined();
    });

    it('should have link columns', () => {
      expect(block.fields.columns).toBeDefined();
      expect(block.fields.columns.type).toBe('array');
    });

    it('should have social links', () => {
      expect(block.fields.socialLinks).toBeDefined();
    });

    it('should have small print', () => {
      expect(block.fields.smallPrint).toBeDefined();
    });

    it('should have optional mini CTA', () => {
      expect(block.fields.miniCta).toBeDefined();
    });
  });

  describe('FAQAccordion block', () => {
    const block = puckConfig.components.FAQAccordion;

    it('should be registered in config', () => {
      expect(block).toBeDefined();
    });

    it('should have items array', () => {
      expect(block.fields.items).toBeDefined();
      expect(block.fields.items.type).toBe('array');
    });

    it('should have expand behavior', () => {
      expect(block.fields.expandBehavior).toBeDefined();
      const options = block.fields.expandBehavior.options;
      expect(options.some((o: { value: string }) => o.value === 'single')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'multiple')).toBe(true);
    });

    it('should have variant field', () => {
      expect(block.fields.variant).toBeDefined();
      const options = block.fields.variant.options;
      expect(options.some((o: { value: string }) => o.value === 'light')).toBe(true);
      expect(options.some((o: { value: string }) => o.value === 'dark')).toBe(true);
    });
  });
});

describe('Block Categories', () => {
  it('should have function-based categories', () => {
    expect(puckConfig.categories.navigation).toBeDefined();
    expect(puckConfig.categories.hero).toBeDefined();
    expect(puckConfig.categories.content).toBeDefined();
    expect(puckConfig.categories.trust).toBeDefined();
    expect(puckConfig.categories.conversion).toBeDefined();
    expect(puckConfig.categories.media).toBeDefined();
    expect(puckConfig.categories.info).toBeDefined();
  });

  it('should have navigation blocks', () => {
    expect(puckConfig.components.Header).toBeDefined();
    expect(puckConfig.components.Footer).toBeDefined();
  });

  it('should have content blocks', () => {
    expect(puckConfig.components.SplitContent).toBeDefined();
    expect(puckConfig.components.ContentBlocks).toBeDefined();
    expect(puckConfig.components.GalleryGrid).toBeDefined();
  });

  it('should have trust/social proof blocks', () => {
    expect(puckConfig.components.LogoCloud).toBeDefined();
    expect(puckConfig.components.Testimonials).toBeDefined();
    expect(puckConfig.components.StatsStrip).toBeDefined();
  });

  it('should have conversion blocks', () => {
    expect(puckConfig.components.CTASection).toBeDefined();
    expect(puckConfig.components.PricingCards).toBeDefined();
  });
});

describe('Shared Design Controls Integration', () => {
  const blocksWithDesignControls = [
    'Hero',
    'SplitContent',
    'CTASection',
    'StatsStrip',
    'GalleryGrid',
    'Testimonials',
    'VideoEmbed',
    'ContentBlocks',
    'PricingCards',
    'FAQAccordion',
  ];

  blocksWithDesignControls.forEach(blockName => {
    describe(`${blockName} design controls`, () => {
      const block = puckConfig.components[blockName];

      it('should have padding field', () => {
        expect(block.fields.padding).toBeDefined();
      });

      it('should have backgroundVariant field', () => {
        expect(block.fields.backgroundVariant).toBeDefined();
      });

      it('should have contentMaxWidth field', () => {
        expect(block.fields.contentMaxWidth).toBeDefined();
      });
    });
  });
});
