<?php
defined( 'ABSPATH' ) || exit;

class Jalpi_Element_Gallery extends Jalpi_Element {
    public static function type(): string { return 'gallery'; }

    public function render( array $node, Jalpi_Renderer $renderer ): string {
        $id       = sanitize_html_class( $node['id'] ?? '' );
        $content  = $node['content']  ?? [];
        $styles   = $node['styles']   ?? [];
        $settings = $node['settings'] ?? [];
        $items    = (array) ( $content['items'] ?? [] );
        $a        = $renderer->get_css_attrs( $node );
        $prefix   = '.jalpi-el.jalpi-' . $id;

        // Helpers
        $px  = fn( $v, $d = '' ) => ( $v !== '' && $v !== null )
            ? ( preg_match('/^-?[\d.]+$/', (string)$v) ? ( (string)$v === '0' ? '0' : (string)$v . 'px' ) : (string)$v )
            : $d;
        $raw = static fn( $k, $d = '' ) => isset( $settings[$k] ) && $settings[$k] !== '' ? (string) $settings[$k] : $d;
        $col = fn( $v, $d = '' ) => ( $v !== '' && $v !== null ) ? (string) $v : $d;

        // Layout options
        $layout   = ( ($content['layout'] ?? 'grid') === 'masonry' ) ? 'masonry' : 'grid';
        $lightbox = ! empty( $content['enableLightbox'] );
        $filter   = ! empty( $content['enableFilter'] );

        // Columns (responsive)
        $cols_d = max( 1, min( 12, intval( $raw( 'gal_cols_desktop', '3' ) ) ) );
        $cols_t = max( 1, min( 12, intval( $raw( 'gal_cols_tablet',  '2' ) ) ) );
        $cols_m = max( 1, min( 12, intval( $raw( 'gal_cols_mobile',  '1' ) ) ) );
        $gap    = $px( $raw( 'gal_gap', '12' ), '12px' );

        // Image style
        $ratio_val  = $raw( 'gal_img_ratio', '1/1' );
        $ratio      = preg_match( '#^\d+/\d+$#', $ratio_val ) ? $ratio_val : '';
        $hover      = in_array( $raw('gal_hover','zoom'), ['none','zoom','scale','fade','overlay'], true ) ? $raw('gal_hover','zoom') : 'zoom';
        $ovl_color  = esc_attr( $col( $raw('gal_overlay_color','rgba(0,0,0,0.5)') ) );
        $ovl_opa    = is_numeric( $raw('gal_overlay_opacity','0.5') ) ? (float) $raw('gal_overlay_opacity','0.5') : 0.5;

        $br_top    = esc_attr( $px( $raw('gal_img_br_top',   '8'), '8px' ) );
        $br_right  = esc_attr( $px( $raw('gal_img_br_right', '8'), '8px' ) );
        $br_bottom = esc_attr( $px( $raw('gal_img_br_bottom','8'), '8px' ) );
        $br_left   = esc_attr( $px( $raw('gal_img_br_left',  '8'), '8px' ) );
        $br_css    = 'border-radius:' . $br_top . ' ' . $br_right . ' ' . $br_bottom . ' ' . $br_left . ';';

        // Border
        $bd_type = $raw( 'gal_img_bd_type', 'none' );
        $bd_css  = '';
        if ( $bd_type && $bd_type !== 'none' ) {
            $bw_top    = esc_attr( $px( $raw('gal_img_bdw_top',   '1'), '1px' ) );
            $bw_right  = esc_attr( $px( $raw('gal_img_bdw_right', '1'), '1px' ) );
            $bw_bottom = esc_attr( $px( $raw('gal_img_bdw_bottom','1'), '1px' ) );
            $bw_left   = esc_attr( $px( $raw('gal_img_bdw_left',  '1'), '1px' ) );
            $bd_color  = esc_attr( $col( $raw('gal_img_bd_color','#e5e7eb') ) );
            $bd_css    = 'border:' . $bw_top . ' ' . esc_attr($bd_type) . ' ' . $bd_color . ';'
                       . 'border-width:' . $bw_top . ' ' . $bw_right . ' ' . $bw_bottom . ' ' . $bw_left . ';';
        }

        // Shadow - sanitize to prevent CSS injection using strict validation
        $shadow_raw = $raw('gal_img_shadow');
        $shadow = $shadow_raw ? Jalpi_Sanitizer::sanitize_css_value( $shadow_raw ) : '';
        $shd_css = $shadow ? 'box-shadow:' . $shadow . ';' : '';

        // Caption
        $cap_show  = in_array( $raw('gal_caption_show','hover'), ['always','hover','never'], true ) ? $raw('gal_caption_show','hover') : 'hover';
        $cap_color = esc_attr( $col( $raw('gal_caption_color','#ffffff') ) );
        $cap_bg    = esc_attr( $col( $raw('gal_caption_bg','rgba(0,0,0,0.6)') ) );
        $cap_size  = esc_attr( $px( $raw('gal_caption_size','13'), '13px' ) );
        $cap_align = in_array( $raw('gal_caption_align','center'), ['left','center','right'], true ) ? $raw('gal_caption_align','center') : 'center';

        // Wrapper CSS
        $renderer->add_css( $prefix . '{' . $renderer->styles_to_css($styles) . '}' );

        // Grid / masonry layout
        $item_css = 'position:relative;overflow:hidden;' . $br_css . $bd_css . $shd_css;
        if ( $layout === 'grid' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__grid{display:grid;grid-template-columns:repeat(' . $cols_d . ',1fr);gap:' . $gap . ';}' );
            if ( $ratio ) {
                $renderer->add_css( $prefix . ' .jalpi-gallery__item{' . $item_css . 'aspect-ratio:' . $ratio . ';}' );
            } else {
                $renderer->add_css( $prefix . ' .jalpi-gallery__item{' . $item_css . '}' );
            }
            $renderer->add_css( $prefix . ' .jalpi-gallery__item img{width:100%;height:' . ( $ratio ? '100%' : 'auto' ) . ';object-fit:cover;display:block;}' );
            $renderer->add_css( '@media(max-width:768px){' . $prefix . ' .jalpi-gallery__grid{grid-template-columns:repeat(' . $cols_t . ',1fr);}}' );
            $renderer->add_css( '@media(max-width:480px){' . $prefix . ' .jalpi-gallery__grid{grid-template-columns:repeat(' . $cols_m . ',1fr);}}' );
        } else {
            $renderer->add_css( $prefix . ' .jalpi-gallery__grid{columns:' . $cols_d . ';column-gap:' . $gap . ';}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item{break-inside:avoid;margin-bottom:' . $gap . ';' . $item_css . '}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item img{width:100%;height:auto;display:block;}' );
            $renderer->add_css( '@media(max-width:768px){' . $prefix . ' .jalpi-gallery__grid{columns:' . $cols_t . ';}}' );
            $renderer->add_css( '@media(max-width:480px){' . $prefix . ' .jalpi-gallery__grid{columns:' . $cols_m . ';}}' );
        }

        // Hover transitions
        if ( $hover === 'zoom' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__item img{transition:transform .4s ease;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item:hover img{transform:scale(1.08);}' );
        } elseif ( $hover === 'scale' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__item{transition:transform .3s ease;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item:hover{transform:scale(1.04);}' );
        } elseif ( $hover === 'fade' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__item img{transition:opacity .3s ease;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item:hover img{opacity:' . $ovl_opa . ';}' );
        } elseif ( $hover === 'overlay' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__overlay{position:absolute;inset:0;background:' . $ovl_color . ';opacity:0;transition:opacity .3s ease;pointer-events:none;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item:hover .jalpi-gallery__overlay{opacity:1;}' );
        }

        // Caption
        $cap_base = 'position:absolute;bottom:0;left:0;right:0;padding:8px 12px;font-size:' . $cap_size . ';color:' . $cap_color . ';background:' . $cap_bg . ';text-align:' . $cap_align . ';';
        if ( $cap_show === 'never' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__caption{display:none;}' );
        } elseif ( $cap_show === 'hover' ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__caption{' . $cap_base . 'opacity:0;transition:opacity .3s ease;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item:hover .jalpi-gallery__caption{opacity:1;}' );
        } else {
            $renderer->add_css( $prefix . ' .jalpi-gallery__caption{' . $cap_base . '}' );
        }

        // Lightbox cursor
        if ( $lightbox ) {
            $renderer->add_css( $prefix . ' .jalpi-gallery__item{cursor:zoom-in;}' );
        }

        // Filter bar
        if ( $filter ) {
            $fil_color     = esc_attr( $col( $raw('gal_filter_color',       '#374151')     ) );
            $fil_bg        = esc_attr( $col( $raw('gal_filter_bg',          'transparent') ) );
            $fil_act_color = esc_attr( $col( $raw('gal_filter_active_color','#ffffff')     ) );
            $fil_act_bg    = esc_attr( $col( $raw('gal_filter_active_bg',   '#6366f1')     ) );
            $renderer->add_css( $prefix . ' .jalpi-gallery__filter{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:' . $gap . ';justify-content:center;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__filter-btn{background:' . $fil_bg . ';color:' . $fil_color . ';border:1px solid currentColor;border-radius:20px;padding:5px 18px;cursor:pointer;font-size:13px;transition:background .2s,color .2s,border-color .2s;}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__filter-btn.jalpi-active{background:' . $fil_act_bg . ';color:' . $fil_act_color . ';border-color:' . $fil_act_bg . ';}' );
            $renderer->add_css( $prefix . ' .jalpi-gallery__item.jalpi-hidden{display:none;}' );
        }

        // Build items HTML
        $categories = [];
        $items_html = '';
        foreach ( $items as $item ) {
            $url     = esc_url(  $item['url']        ?? '' );
            $alt     = esc_attr( $item['alt']        ?? '' );
            $caption = esc_html( $item['caption']    ?? '' );
            $link    = esc_url(  $item['linkUrl']    ?? '' );
            $target  = ( ($item['linkTarget'] ?? '_blank') === '_self' ) ? '_self' : '_blank';
            $cat     = sanitize_html_class( $item['category'] ?? '' );
            if ( ! $url ) continue;

            if ( $filter && $cat ) $categories[] = $cat;

            $cat_attr = $cat ? ' data-category="' . $cat . '"' : '';
            $lb_attr  = $lightbox ? ' data-jalpi-lb="' . esc_attr($url) . '" data-jalpi-lb-alt="' . $alt . '"' : '';
            $overlay  = ( $hover === 'overlay' ) ? '<div class="jalpi-gallery__overlay" aria-hidden="true"></div>' : '';
            $cap_html = $caption ? '<div class="jalpi-gallery__caption">' . $caption . '</div>' : '';

            $img_html = '<img src="' . $url . '" alt="' . $alt . '" loading="lazy">';
            $inner    = '<div class="jalpi-gallery__media">' . $img_html . $overlay . $cap_html . '</div>';

            // Link (only when no lightbox)
            if ( $link && ! $lightbox ) {
                $inner = '<a href="' . $link . '" target="' . esc_attr($target) . '" rel="noopener noreferrer">' . $inner . '</a>';
            }

            $items_html .= '<figure class="jalpi-gallery__item"' . $cat_attr . $lb_attr . '>' . $inner . '</figure>';
        }

        // Filter HTML
        $filter_html = '';
        if ( $filter && $categories ) {
            $unique_cats = array_unique( $categories );
            $filter_html = '<div class="jalpi-gallery__filter"><button class="jalpi-gallery__filter-btn jalpi-active" data-filter="all">' . esc_html__( 'All', 'jalpi-page-builder' ) . '</button>';
            foreach ( $unique_cats as $cat ) {
                $label       = esc_html( ucwords( str_replace( ['-','_'], ' ', $cat ) ) );
                $filter_html .= '<button class="jalpi-gallery__filter-btn" data-filter="' . esc_attr($cat) . '">' . $label . '</button>';
            }
            $filter_html .= '</div>';
        }

        // Element classes
        $cls = 'jalpi-el jalpi-gallery jalpi-gallery--' . $layout . ( $hover !== 'none' ? ' jalpi-gallery--h-' . $hover : '' )
             . ' jalpi-' . esc_attr($id) . $a['extra_cls'];

        // Data attributes drive the JS in jalpi-frontend.js — no inline scripts needed.
        $data_attrs = '';
        if ( $filter ) {
            $data_attrs .= ' data-jalpi-gallery-filter';
        }
        if ( $lightbox ) {
            $data_attrs .= ' data-jalpi-gallery-lightbox';
        }

        $html = '<div class="' . $cls . '"' . $a['id_attr'] . $data_attrs . '>'
              . $filter_html
              . '<div class="jalpi-gallery__grid">' . $items_html . '</div>'
              . '</div>';

        if ( $filter || $lightbox ) {
            $renderer->set_needs_js( 'gallery' );
        }

        return $html;
    }
}
