// ─────────────────────────────────────────────────────────────────────────
// Products Grid — canvas preview.
//
// Mirrors the PHP element's markup and CSS closely enough that the editor is
// genuinely WYSIWYG: same grid/gap/columns, same card anatomy, same style
// settings. Product DATA is sampled locally (the editor has no WC_Query), so
// the grid always shows a full, realistic set of cards regardless of whether
// WooCommerce is installed — matching the PHP placeholder behaviour.
//
// Responsive: the canvas breakpoint drives which column count is used, so
// switching to Tablet/Mobile in the toolbar reflows the preview exactly like
// the frontend media queries do.
// ─────────────────────────────────────────────────────────────────────────
import React from 'react';
import type { CBNode, Breakpoint } from '../types';

function str(v: unknown, fallback = ''): string { return v == null || v === '' ? fallback : String(v); }
function num(v: unknown, fallback: number): number {
  const n = parseFloat(String(v));
  return Number.isFinite(n) ? n : fallback;
}
/** Bare number → px; anything already carrying a unit passes through. */
function px(v: unknown, fallback: string): string {
  const s = str(v);
  if (!s) return fallback;
  return /^-?[\d.]+$/.test(s) ? `${s}px` : s;
}

const SAMPLE = [
  { name: 'Classic Product',   price: '29.00',  sale: true,  hue: '#eef2f7' },
  { name: 'Premium Item',      price: '49.00',  sale: false, hue: '#f3eef7' },
  { name: 'Everyday Essential', price: '19.50', sale: false, hue: '#eef7f2' },
  { name: 'Limited Edition',   price: '89.00',  sale: true,  hue: '#f7f3ee' },
  { name: 'Signature Piece',   price: '35.00',  sale: false, hue: '#eef2f7' },
  { name: 'Studio Collection', price: '64.00',  sale: false, hue: '#f3eef7' },
  { name: 'Traveler Set',      price: '24.00',  sale: true,  hue: '#eef7f2' },
  { name: 'Weekend Bundle',    price: '120.00', sale: false, hue: '#f7f3ee' },
];

/** Inline SVG stand-in — no network request inside the editor iframe. */
function Thumb({ hue, fit, radius }: { hue: string; fit: string; radius: string }) {
  return (
    <svg viewBox="0 0 400 400" preserveAspectRatio="none"
      style={{ width: '100%', height: '100%', objectFit: fit as React.CSSProperties['objectFit'], display: 'block', borderRadius: radius }}>
      <rect width="400" height="400" fill={hue} />
      <path d="M150 250h100l-20-70h-60z" fill="#c3ccd8" />
      <circle cx="200" cy="160" r="34" fill="#c3ccd8" />
    </svg>
  );
}

function Stars({ size, fill, empty }: { size: number; fill: string; empty: string }) {
  // Two stacked rows clipped by width — same technique as the PHP renderer.
  return (
    <span style={{ position: 'relative', display: 'inline-block', width: '5.2em', height: '1em', fontSize: size, lineHeight: 1 }}>
      <span style={{ color: empty, letterSpacing: '.05em' }}>★★★★★</span>
      <span style={{ position: 'absolute', inset: 0, overflow: 'hidden', whiteSpace: 'nowrap', width: '90%' }}>
        <span style={{ color: fill, letterSpacing: '.05em' }}>★★★★★</span>
      </span>
    </span>
  );
}

export function ProductsGridPreview({
  node, inlineStyles, breakpoint,
}: { node: CBNode; inlineStyles: React.CSSProperties; breakpoint?: Breakpoint }) {
  const c = (node.content  ?? {}) as Record<string, unknown>;
  const s = (node.settings ?? {}) as Record<string, unknown>;

  // ── Layout ───────────────────────────────────────────────────────────────
  const colsD = Math.max(1, Math.min(6, num(s.pg_cols_desktop, 4)));
  const colsT = Math.max(1, Math.min(6, num(s.pg_cols_tablet, 2)));
  const colsM = Math.max(1, Math.min(6, num(s.pg_cols_mobile, 1)));
  const cols  = breakpoint === 'mobile' ? colsM : breakpoint === 'tablet' ? colsT : colsD;

  const colGap  = px(s.pg_col_gap, '24px');
  const rowGap  = px(s.pg_row_gap, '32px');
  const masonry = !!c.masonry;
  const equalH  = c.equalHeight !== false;

  // Elementor semantics: Rows multiplies the desktop column count.
  const perPage = Math.max(1, Math.min(100, num(c.perPage, 8)));
  const count   = c.useRows
    ? Math.max(1, Math.min(24, colsD * Math.max(1, num(c.rows, 1))))
    : Math.min(perPage, 12); // cap the preview so huge values stay editable
  const items = Array.from({ length: count }, (_, i) => SAMPLE[i % SAMPLE.length]);

  // ── Visible elements ─────────────────────────────────────────────────────
  const on = (k: string, d: boolean): boolean => (k in c ? !!c[k] : d);
  const el = {
    image:      on('showImage', true),
    badge:      on('showSaleBadge', true),
    title:      on('showTitle', true),
    rating:     on('showRating', true),
    price:      on('showPrice', true),
    excerpt:    on('showExcerpt', false),
    cart:       on('showAddToCart', true),
    wishlist:   on('showWishlist', false),
    compare:    on('showCompare', false),
    quickview:  on('showQuickView', false),
    categories: on('showCategories', false),
    sku:        on('showSku', false),
  };

  // ── Style ────────────────────────────────────────────────────────────────
  const align      = str(s.pg_card_align, 'left') as React.CSSProperties['textAlign'];
  const cardBg     = str(s.pg_card_bg);
  const cardPad    = str(s.pg_card_pad);
  const cardRadius = px(s.pg_card_radius, '12px');
  const cardBdType = str(s.pg_card_bd_type, 'none');
  const cardShadow = str(s.pg_card_shadow);

  const ratio  = str(s.pg_img_ratio, '1/1');
  const imgFit = str(s.pg_img_fit, 'cover');
  const imgRad = px(s.pg_img_radius, '0px');

  const badgeBg   = str(s.pg_badge_bg, '#111827');
  const badgeCol  = str(s.pg_badge_color, '#ffffff');
  const badgePos  = str(s.pg_badge_pos, 'top-left');
  const titleCol  = str(s.pg_title_color);
  const priceCol  = str(s.pg_price_color);
  const saleCol   = str(s.pg_sale_price_color);
  const starFill  = str(s.pg_star_color, '#f59e0b');
  const starEmpty = str(s.pg_star_empty_color, '#d1d5db');

  const btnBg     = str(s.pg_btn_bg, '#111827');
  const btnCol    = str(s.pg_btn_color, '#ffffff');
  const btnRadius = px(s.pg_btn_radius, '8px');
  const btnPad    = str(s.pg_btn_pad, '10px 18px');
  const btnIcon   = str(s.pg_btn_icon, 'none');
  const btnIconAt = str(s.pg_btn_icon_pos, 'before');
  const btnText   = str(c.buttonText, 'Add to cart');

  const iconGlyph: Record<string, string> = { cart: '🛒', bag: '🛍', plus: '＋', arrow: '→' };
  const glyph = iconGlyph[btnIcon] || '';

  const cardStyle: React.CSSProperties = {
    position: 'relative',
    overflow: 'hidden',
    textAlign: align,
    borderRadius: cardRadius,
    background: cardBg || undefined,
    padding: cardPad || undefined,
    boxShadow: cardShadow || undefined,
    ...(cardBdType !== 'none'
      ? {
          borderStyle: cardBdType,
          borderWidth: px(s.pg_card_bd_width, '1px'),
          borderColor: str(s.pg_card_bd_color, '#e5e7eb'),
        }
      : {}),
    ...(equalH && !masonry ? { display: 'flex', flexDirection: 'column', height: '100%' } : {}),
  };

  const gridStyle: React.CSSProperties = masonry
    ? { columns: cols, columnGap: colGap }
    : { display: 'grid', gridTemplateColumns: `repeat(${cols}, minmax(0,1fr))`, gap: `${rowGap} ${colGap}` };

  const vert = badgePos.startsWith('top') ? 'top' : 'bottom';
  const horz = badgePos.endsWith('left') ? 'left' : 'right';

  const currency = '$';

  return (
    <div style={inlineStyles}>
      <div style={gridStyle}>
        {items.map((p, i) => (
          <div key={i} style={masonry ? { breakInside: 'avoid', marginBottom: rowGap } : undefined}>
            <div style={cardStyle}>
              {el.image && (
                <div style={{
                  position: 'relative', overflow: 'hidden', lineHeight: 0,
                  aspectRatio: ratio !== 'auto' ? ratio.replace('/', ' / ') : undefined,
                  width: str(s.pg_img_width) ? px(s.pg_img_width, '') : undefined,
                  height: str(s.pg_img_height) ? px(s.pg_img_height, '') : undefined,
                  borderRadius: imgRad,
                }}>
                  <Thumb hue={p.hue} fit={imgFit} radius={imgRad} />

                  {el.badge && p.sale && (
                    <span style={{
                      position: 'absolute', [vert]: 10, [horz]: 10, zIndex: 2,
                      background: badgeBg, color: badgeCol,
                      borderRadius: px(s.pg_badge_radius, '4px'),
                      padding: str(s.pg_badge_pad, '4px 10px'),
                      fontSize: num(s.pg_badge_size, 12),
                      fontWeight: num(s.pg_badge_weight, 600),
                      lineHeight: 1.4,
                    } as React.CSSProperties}>Sale</span>
                  )}

                  {(el.wishlist || el.compare || el.quickview) && (
                    <div style={{
                      position: 'absolute', top: 10, right: 10, zIndex: 2,
                      display: 'flex', flexDirection: 'column', gap: 6,
                    }}>
                      {[el.wishlist && '♥', el.compare && '⇄', el.quickview && '⊕']
                        .filter(Boolean)
                        .map((g, k) => (
                          <span key={k} style={{
                            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                            width: '2em', height: '2em', fontSize: num(s.pg_action_size, 16),
                            borderRadius: '50%', background: str(s.pg_action_bg, '#ffffff'),
                            color: str(s.pg_action_color, '#111827'),
                            boxShadow: '0 1px 4px rgba(0,0,0,.15)', lineHeight: 1,
                          }}>{g}</span>
                        ))}
                    </div>
                  )}
                </div>
              )}

              <div style={{
                padding: str(s.pg_body_pad, '14px 0 0'),
                ...(equalH && !masonry ? { display: 'flex', flexDirection: 'column', flex: '1 1 auto' } : {}),
              }}>
                {el.categories && <div style={{ fontSize: 12, opacity: 0.7, marginBottom: 4 }}>Sample</div>}

                {el.title && (
                  <h3 style={{
                    margin: str(s.pg_title_margin, '0 0 6px'),
                    fontSize: num(s.pg_title_size, 16),
                    fontWeight: num(s.pg_title_weight, 600),
                    color: titleCol || undefined,
                    lineHeight: 1.4,
                  }}>{p.name}</h3>
                )}

                {el.sku && <div style={{ fontSize: 12, opacity: 0.7, marginBottom: 4 }}>SKU: DEMO-{String(i + 1).padStart(3, '0')}</div>}

                {el.rating && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: num(s.pg_rating_spacing, 4) }}>
                    <Stars size={num(s.pg_star_size, 15)} fill={starFill} empty={starEmpty} />
                    <span style={{ fontSize: '.78em', opacity: 0.7 }}>(12)</span>
                  </div>
                )}

                {el.price && (
                  <div style={{
                    marginTop: num(s.pg_price_spacing, 6),
                    fontSize: num(s.pg_price_size, 15),
                    fontWeight: num(s.pg_price_weight, 600),
                    color: priceCol || undefined,
                  }}>
                    {p.sale ? (
                      <>
                        <del style={{ opacity: 0.55, fontWeight: 400, marginRight: 6 }}>
                          {currency}{(parseFloat(p.price) * 1.3).toFixed(2)}
                        </del>
                        <ins style={{ color: saleCol || undefined, textDecoration: 'none' }}>
                          {currency}{p.price}
                        </ins>
                      </>
                    ) : <>{currency}{p.price}</>}
                  </div>
                )}

                {el.excerpt && (
                  <div style={{ fontSize: 13, opacity: 0.8, marginTop: 6, lineHeight: 1.55 }}>
                    A short sample description for this product.
                  </div>
                )}

                {el.cart && (
                  <div style={{
                    display: 'flex', alignItems: 'center', gap: 8,
                    marginTop: num(s.pg_btn_spacing, 12),
                    ...(equalH && !masonry ? { marginTop: 'auto', paddingTop: num(s.pg_btn_spacing, 12) } : {}),
                    justifyContent: align === 'center' ? 'center' : align === 'right' ? 'flex-end' : 'flex-start',
                  }}>
                    {!!c.showQuantity && (
                      <span style={{
                        width: 64, padding: 8, border: '1px solid #e5e7eb', borderRadius: 6,
                        fontSize: 13, textAlign: 'center', boxSizing: 'border-box',
                      }}>1</span>
                    )}
                    <span style={{
                      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                      background: btnBg, color: btnCol, borderRadius: btnRadius, padding: btnPad,
                      fontSize: num(s.pg_btn_size, 14), fontWeight: num(s.pg_btn_weight, 600),
                      ...(str(s.pg_btn_bd_type, 'none') !== 'none'
                        ? {
                            borderStyle: str(s.pg_btn_bd_type),
                            borderWidth: px(s.pg_btn_bd_width, '1px'),
                            borderColor: str(s.pg_btn_bd_color, 'currentColor'),
                          }
                        : {}),
                    }}>
                      {glyph && btnIconAt === 'before' && <span>{glyph}</span>}
                      <span>{btnText}</span>
                      {glyph && btnIconAt === 'after' && <span>{glyph}</span>}
                    </span>
                  </div>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>

      {str(c.pagination, 'none') !== 'none' && (
        <div style={{
          display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center',
          gap: num(s.pg_pag_spacing, 8), marginTop: num(s.pg_pag_margin, 28),
        }}>
          {c.pagination === 'load-more' ? (
            <span style={{
              padding: '8px 14px', borderRadius: px(s.pg_pag_radius, '6px'),
              border: `1px solid ${str(s.pg_pag_bd_color, '#e5e7eb')}`,
              fontSize: num(s.pg_pag_size, 14), color: str(s.pg_pag_color) || undefined,
            }}>{str(c.loadMoreText, 'Load More')}</span>
          ) : c.pagination === 'infinite' ? (
            <span style={{ fontSize: 12, color: '#94a3b8' }}>Infinite scroll — loads on scroll</span>
          ) : (
            <>
              <span style={{
                padding: '8px 14px', borderRadius: px(s.pg_pag_radius, '6px'),
                border: `1px solid ${str(s.pg_pag_bd_color, '#e5e7eb')}`,
                fontSize: num(s.pg_pag_size, 14), opacity: 0.45,
              }}>Previous</span>
              {c.pagination === 'numbers' && [1, 2, 3].map((n) => (
                <span key={n} style={{
                  padding: '8px 14px', borderRadius: px(s.pg_pag_radius, '6px'),
                  fontSize: num(s.pg_pag_size, 14),
                  border: `1px solid ${n === 1 ? str(s.pg_pag_active_color, '#111827') : str(s.pg_pag_bd_color, '#e5e7eb')}`,
                  background: n === 1 ? str(s.pg_pag_active_color, '#111827') : 'transparent',
                  color: n === 1 ? '#fff' : (str(s.pg_pag_color) || undefined),
                }}>{n}</span>
              ))}
              <span style={{
                padding: '8px 14px', borderRadius: px(s.pg_pag_radius, '6px'),
                border: `1px solid ${str(s.pg_pag_bd_color, '#e5e7eb')}`,
                fontSize: num(s.pg_pag_size, 14), color: str(s.pg_pag_color) || undefined,
              }}>Next</span>
            </>
          )}
        </div>
      )}
    </div>
  );
}
