// ─────────────────────────────────────────────────────────────────────────
// Product Categories — canvas preview.
//
// Mirrors the PHP element's markup and CSS closely enough to be WYSIWYG:
// same skins (classic/cards/overlay/minimal), layouts (grid/list/carousel),
// columns, gaps and style settings. Category DATA is sampled locally (the
// editor has no term query), matching the PHP placeholder behaviour.
//
// The carousel renders as a static first "page" — arrows and dots are drawn
// for layout fidelity but don't animate in-canvas, so editing stays stable.
// ─────────────────────────────────────────────────────────────────────────
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;
}
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: 'Clothing',      count: 24, hue: '#eef2f7' },
  { name: 'Accessories',   count: 12, hue: '#f3eef7' },
  { name: 'Footwear',      count: 18, hue: '#eef7f2' },
  { name: 'Bags',          count: 9,  hue: '#f7f3ee' },
  { name: 'Electronics',   count: 31, hue: '#eef2f7' },
  { name: 'Home & Living', count: 15, hue: '#f3eef7' },
  { name: 'Beauty',        count: 7,  hue: '#eef7f2' },
  { name: 'Outdoors',      count: 21, hue: '#f7f3ee' },
];

function Thumb({ hue, fit }: { hue: string; fit: string }) {
  return (
    <svg viewBox="0 0 400 400" preserveAspectRatio="none"
      style={{ width: '100%', height: '100%', objectFit: fit as React.CSSProperties['objectFit'], display: 'block' }}>
      <rect width="400" height="400" fill={hue} />
      <path d="M120 160h70l18 26h72v94H120z" fill="#c3ccd8" />
    </svg>
  );
}

export function ProductCategoriesPreview({
  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>;

  const skin   = str(c.skin, 'classic');
  const layout = str(c.layout, 'grid');
  const isList = layout === 'list';
  const isCar  = layout === 'carousel';

  const colsD = Math.max(1, Math.min(6, num(s.pc_cols_desktop, 4)));
  const colsT = Math.max(1, Math.min(6, num(s.pc_cols_tablet, 2)));
  const colsM = Math.max(1, Math.min(6, num(s.pc_cols_mobile, 1)));
  const cols  = breakpoint === 'mobile' ? colsM : breakpoint === 'tablet' ? colsT : colsD;

  const colGap = px(s.pc_col_gap, '24px');
  const rowGap = px(s.pc_row_gap, '24px');
  const align  = str(s.pc_align, 'center') as React.CSSProperties['textAlign'];
  const equalH = c.equalHeight !== false;

  const on = (k: string, d: boolean): boolean => (k in c ? !!c[k] : d);
  const el = {
    image:  on('showImage', true),
    name:   on('showName', true),
    count:  on('showCount', true),
    desc:   on('showDescription', false),
    button: on('showButton', false),
  };

  // Carousel shows slidesPerView items; grid/list show the requested number.
  const perView = Math.max(1, Math.min(6, num(c.slidesPerView, colsD)));
  const total   = Math.max(0, Math.min(24, num(c.number, 12)));
  const count   = isCar ? Math.min(perView, SAMPLE.length) : Math.min(total || 6, 12);
  const items   = Array.from({ length: count }, (_, i) => SAMPLE[i % SAMPLE.length]);

  // ── Style ────────────────────────────────────────────────────────────────
  const ratio   = str(s.pc_img_ratio, '1/1');
  const imgFit  = str(s.pc_img_fit, 'cover');
  const imgRad  = px(s.pc_img_radius, '0px');
  const cardRad = px(s.pc_card_radius, '12px');
  const cardBd  = str(s.pc_card_bd_type, 'none');
  const isOverlay = skin === 'overlay';

  const cardStyle: React.CSSProperties = {
    position: 'relative',
    overflow: 'hidden',
    display: isList ? 'flex' : 'block',
    alignItems: isList ? 'center' : undefined,
    gap: isList ? colGap : undefined,
    textAlign: align,
    borderRadius: cardRad,
    background: str(s.pc_card_bg) || undefined,
    padding: str(s.pc_card_pad) || undefined,
    margin: str(s.pc_card_margin) || undefined,
    boxShadow: str(s.pc_card_shadow) || undefined,
    ...(cardBd !== 'none'
      ? { borderStyle: cardBd, borderWidth: px(s.pc_card_bd_width, '1px'), borderColor: str(s.pc_card_bd_color, '#e5e7eb') }
      : {}),
    ...(equalH && !isList ? { display: 'flex', flexDirection: 'column', height: '100%' } : {}),
  };

  const gridStyle: React.CSSProperties = isList
    ? { display: 'flex', flexDirection: 'column', gap: rowGap }
    : isCar
      ? { display: 'flex', gap: colGap, overflow: 'hidden' }
      : { display: 'grid', gridTemplateColumns: `repeat(${cols}, minmax(0,1fr))`, gap: `${rowGap} ${colGap}` };

  const titleColor = isOverlay ? str(s.pc_title_color, '#ffffff') : (str(s.pc_title_color) || undefined);
  const countBg    = str(s.pc_count_bg);

  return (
    <div style={{ ...inlineStyles, position: 'relative' }}>
      <div style={gridStyle}>
        {items.map((cat, i) => (
          <div key={i} style={isCar ? { flex: `0 0 calc((100% - (${colGap} * ${perView - 1})) / ${perView})` } : undefined}>
            <div style={cardStyle}>
              {el.image && (
                <div style={{
                  position: 'relative', overflow: 'hidden', lineHeight: 0,
                  aspectRatio: !isList && ratio !== 'auto' ? ratio.replace('/', ' / ') : undefined,
                  flex: isList ? '0 0 auto' : undefined,
                  width: isList ? px(s.pc_img_width, '96px') : (str(s.pc_img_width) ? px(s.pc_img_width, '') : undefined),
                  height: str(s.pc_img_height) ? px(s.pc_img_height, '') : undefined,
                  borderRadius: imgRad,
                }}>
                  <Thumb hue={cat.hue} fit={imgFit} />
                  {isOverlay && (
                    <span style={{
                      position: 'absolute', inset: 0, pointerEvents: 'none',
                      background: `linear-gradient(to top, ${str(s.pc_overlay_color, 'rgba(0,0,0,.55)')} 0%, transparent 70%)`,
                    }} />
                  )}
                </div>
              )}

              <div style={{
                padding: str(s.pc_body_pad) || (isOverlay ? '16px' : '14px 0 0'),
                ...(isOverlay
                  ? { position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 2 }
                  : {}),
                ...(isList ? { flex: '1 1 auto' } : {}),
                ...(equalH && !isList && !isOverlay ? { display: 'flex', flexDirection: 'column', flex: '1 1 auto' } : {}),
              }}>
                {el.name && (
                  <h3 style={{
                    margin: str(s.pc_title_margin, '0 0 4px'),
                    fontSize: num(s.pc_title_size, 17),
                    fontWeight: num(s.pc_title_weight, 600),
                    lineHeight: num(s.pc_title_lh, 1.4),
                    letterSpacing: str(s.pc_title_ls) ? px(s.pc_title_ls, '') : undefined,
                    textTransform: (str(s.pc_title_transform, 'none') !== 'none'
                      ? str(s.pc_title_transform) : undefined) as React.CSSProperties['textTransform'],
                    fontFamily: str(s.pc_title_font) || undefined,
                    color: titleColor,
                  }}>{cat.name}</h3>
                )}

                {el.count && (
                  <span style={{
                    display: 'inline-block',
                    fontSize: num(s.pc_count_size, 13),
                    lineHeight: 1.5,
                    color: isOverlay ? '#fff' : (str(s.pc_count_color) || undefined),
                    opacity: !isOverlay && !str(s.pc_count_color) ? 0.72 : undefined,
                    ...(countBg
                      ? {
                          background: countBg,
                          padding: str(s.pc_count_pad, '2px 8px'),
                          borderRadius: px(s.pc_count_radius, '999px'),
                        }
                      : {}),
                  }}>{cat.count} Products</span>
                )}

                {el.desc && (
                  <div style={{
                    fontSize: num(s.pc_desc_size, 13), lineHeight: 1.6,
                    marginTop: num(s.pc_desc_spacing, 6),
                    color: isOverlay ? '#fff' : (str(s.pc_desc_color) || undefined),
                    opacity: !isOverlay && !str(s.pc_desc_color) ? 0.8 : undefined,
                    textAlign: (str(s.pc_desc_align, 'inherit') !== 'inherit'
                      ? str(s.pc_desc_align) : undefined) as React.CSSProperties['textAlign'],
                  }}>Sample category description for the editor preview.</div>
                )}

                {el.button && (
                  <span style={{
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
                    marginTop: num(s.pc_btn_spacing, 12),
                    ...(equalH && !isList && !isOverlay ? { marginTop: 'auto', paddingTop: num(s.pc_btn_spacing, 12) } : {}),
                    padding: str(s.pc_btn_pad, '8px 16px'),
                    fontSize: num(s.pc_btn_size, 13),
                    fontWeight: num(s.pc_btn_weight, 600),
                    color: str(s.pc_btn_color, '#ffffff'),
                    background: str(s.pc_btn_bg, '#111827'),
                    borderRadius: px(s.pc_btn_radius, '8px'),
                    ...(str(s.pc_btn_bd_type, 'none') !== 'none'
                      ? {
                          borderStyle: str(s.pc_btn_bd_type),
                          borderWidth: px(s.pc_btn_bd_width, '1px'),
                          borderColor: str(s.pc_btn_bd_color, 'currentColor'),
                        }
                      : {}),
                  }}>
                    {str(s.pc_btn_icon, 'none') !== 'none' && str(s.pc_btn_icon_pos, 'after') === 'before' && (
                      <span>{({ arrow: '→', chevron: '›', plus: '＋', cart: '🛒' } as Record<string, string>)[str(s.pc_btn_icon)]}</span>
                    )}
                    <span>{str(c.buttonText, 'View Products')}</span>
                    {str(s.pc_btn_icon, 'none') !== 'none' && str(s.pc_btn_icon_pos, 'after') === 'after' && (
                      <span>{({ arrow: '→', chevron: '›', plus: '＋', cart: '🛒' } as Record<string, string>)[str(s.pc_btn_icon)]}</span>
                    )}
                  </span>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* Carousel chrome — drawn for fidelity, static in-canvas. */}
      {isCar && on('showArrows', true) && (
        <>
          {['prev', 'next'].map((dir) => (
            <span key={dir} style={{
              position: 'absolute', top: '50%', transform: 'translateY(-50%)',
              [dir === 'prev' ? 'left' : 'right']: -8, zIndex: 3,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              width: '2.2em', height: '2.2em', fontSize: num(s.pc_arrow_size, 18),
              borderRadius: '50%', background: str(s.pc_arrow_bg, '#ffffff'),
              color: str(s.pc_arrow_color, '#111827'),
              boxShadow: '0 1px 6px rgba(0,0,0,.18)', lineHeight: 1,
            } as React.CSSProperties}>{dir === 'prev' ? '‹' : '›'}</span>
          ))}
        </>
      )}

      {isCar && on('showDots', true) && (
        <div style={{
          display: 'flex', justifyContent: 'center',
          gap: num(s.pc_dot_spacing, 8), marginTop: 16,
        }}>
          {[0, 1, 2].map((d) => (
            <span key={d} style={{
              width: 9, height: 9, borderRadius: '50%',
              background: d === 0 ? str(s.pc_dot_active_color, '#111827') : str(s.pc_dot_color, '#d1d5db'),
              transform: d === 0 ? 'scale(1.25)' : undefined,
            }} />
          ))}
        </div>
      )}
    </div>
  );
}
