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

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

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

        if ( ! $src ) {
            return '';
        }

        $dim = fn( $v ) => preg_match( '/^\d+(\.\d+)?(px|em|rem|%|vw|vh)$/', (string) $v ) ? $v : '';
        $col = fn( $v ) => preg_match( '/^#[0-9a-fA-F]{3,8}$|^rgba?\(/', (string) $v ) ? $v : '';
        $pct = fn( $v ) => ( is_numeric( $v ) ? (float) $v / 100 : '' );

        // Wrapper styles (textAlign, margin, width, maxWidth, height from node.styles)
        $renderer->add_css( $prefix . '{display:block;' . $renderer->styles_to_css( $styles ) . '}' );

        // ── img-specific CSS from settings ────────────────────────────────────
        $img_css = 'max-width:100%;display:block;';

        $object_fit = sanitize_key( $settings['img_objectFit'] ?? '' );
        if ( $object_fit ) $img_css .= 'object-fit:' . esc_attr( $object_fit ) . ';';

        // Opacity
        $opacity_raw = (string) ( $settings['img_opacity'] ?? '100' );
        $opacity_val = is_numeric( $opacity_raw ) ? (float) $opacity_raw / 100 : 1;
        if ( $opacity_val < 1 ) $img_css .= 'opacity:' . $opacity_val . ';';

        // CSS Filters
        $filter_parts = [];
        $blur       = $dim( $settings['img_blur']       ?? '' );
        $brightness = $settings['img_brightness'] ?? '';
        $contrast   = $settings['img_contrast']   ?? '';
        $saturate   = $settings['img_saturate']   ?? '';
        $hue        = $settings['img_hue']        ?? '';
        if ( $blur ) $filter_parts[] = 'blur(' . esc_attr( $blur ) . ')';
        if ( is_numeric( $brightness ) && (int) $brightness !== 100 ) $filter_parts[] = 'brightness(' . ( (float) $brightness / 100 ) . ')';
        if ( is_numeric( $contrast )   && (int) $contrast   !== 100 ) $filter_parts[] = 'contrast('   . ( (float) $contrast   / 100 ) . ')';
        if ( is_numeric( $saturate )   && (int) $saturate   !== 100 ) $filter_parts[] = 'saturate('   . ( (float) $saturate   / 100 ) . ')';
        if ( is_numeric( $hue ) && (int) $hue !== 0 ) $filter_parts[] = 'hue-rotate(' . (int) $hue . 'deg)';
        if ( $filter_parts ) $img_css .= 'filter:' . implode( ' ', $filter_parts ) . ';';

        // Border Radius
        $br_t = $dim( $settings['img_br_top']    ?? '' );
        $br_r = $dim( $settings['img_br_right']  ?? '' );
        $br_b = $dim( $settings['img_br_bottom'] ?? '' );
        $br_l = $dim( $settings['img_br_left']   ?? '' );
        if ( $br_t || $br_r || $br_b || $br_l ) {
            $img_css .= 'border-radius:' . esc_attr( ($br_t?:'0') . ' ' . ($br_r?:'0') . ' ' . ($br_b?:'0') . ' ' . ($br_l?:'0') ) . ';';
        }

        // Border
        $bd_type = sanitize_key( $settings['img_bdType'] ?? 'default' );
        if ( $bd_type && $bd_type !== 'none' && $bd_type !== 'default' ) {
            $bd_color = $col( $settings['img_bdColor'] ?? '' ) ?: '#000';
            $bd_allowed = [ 'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'inset', 'outset' ];
            if ( in_array( $bd_type, $bd_allowed, true ) ) {
                $bdw_t = $dim( $settings['img_bdw_top']    ?? '' ) ?: '1px';
                $bdw_r = $dim( $settings['img_bdw_right']  ?? '' ) ?: '1px';
                $bdw_b = $dim( $settings['img_bdw_bottom'] ?? '' ) ?: '1px';
                $bdw_l = $dim( $settings['img_bdw_left']   ?? '' ) ?: '1px';
                $img_css .= 'border-top:' . esc_attr( $bdw_t ) . ' ' . $bd_type . ' ' . esc_attr( $bd_color ) . ';';
                $img_css .= 'border-right:' . esc_attr( $bdw_r ) . ' ' . $bd_type . ' ' . esc_attr( $bd_color ) . ';';
                $img_css .= 'border-bottom:' . esc_attr( $bdw_b ) . ' ' . $bd_type . ' ' . esc_attr( $bd_color ) . ';';
                $img_css .= 'border-left:' . esc_attr( $bdw_l ) . ' ' . $bd_type . ' ' . esc_attr( $bd_color ) . ';';
            }
        }

        // Box Shadow
        $box_shadow = sanitize_text_field( $settings['img_boxShadow'] ?? '' );
        if ( $box_shadow ) $img_css .= 'box-shadow:' . esc_attr( $box_shadow ) . ';';

        // Hover state CSS
        $has_hover = isset( $settings['img_opacityHover'] ) || isset( $settings['img_blurHover'] )
                  || isset( $settings['img_brightnessHover'] ) || isset( $settings['img_contrastHover'] )
                  || isset( $settings['img_saturateHover'] )   || isset( $settings['img_hueHover'] );
        if ( $has_hover ) {
            $img_css .= 'transition:opacity 0.3s ease,filter 0.3s ease;';
            $hover_css = '';
            $op_hover = $settings['img_opacityHover'] ?? '100';
            if ( is_numeric( $op_hover ) && (int) $op_hover !== 100 ) {
                $hover_css .= 'opacity:' . ( (float) $op_hover / 100 ) . ';';
            }
            $hf = [];
            $blur_h = $dim( $settings['img_blurHover'] ?? '' );
            $bri_h  = $settings['img_brightnessHover'] ?? '';
            $con_h  = $settings['img_contrastHover']   ?? '';
            $sat_h  = $settings['img_saturateHover']   ?? '';
            $hue_h  = $settings['img_hueHover']        ?? '';
            if ( $blur_h ) $hf[] = 'blur(' . esc_attr( $blur_h ) . ')';
            if ( is_numeric( $bri_h ) && (int) $bri_h !== 100 ) $hf[] = 'brightness(' . ( (float) $bri_h / 100 ) . ')';
            if ( is_numeric( $con_h ) && (int) $con_h !== 100 ) $hf[] = 'contrast('   . ( (float) $con_h / 100 ) . ')';
            if ( is_numeric( $sat_h ) && (int) $sat_h !== 100 ) $hf[] = 'saturate('   . ( (float) $sat_h / 100 ) . ')';
            if ( is_numeric( $hue_h ) && (int) $hue_h !== 0   ) $hf[] = 'hue-rotate(' . (int) $hue_h . 'deg)';
            if ( $hf ) $hover_css .= 'filter:' . implode( ' ', $hf ) . ';';
            if ( $hover_css ) $renderer->add_css( $prefix . ':hover img{' . $hover_css . '}' );
        }

        $renderer->add_css( $prefix . ' img{' . $img_css . '}' );

        // ── Legacy image size presets ──────────────────────────────────────────
        $img_size_presets = [ 'thumbnail' => '150px', 'medium' => '300px', 'medium_large' => '768px', 'large' => '1024px' ];
        $img_size = sanitize_text_field( $content['imageSize'] ?? '' );
        if ( isset( $img_size_presets[ $img_size ] ) ) {
            $renderer->add_css( $prefix . ' img{width:' . $img_size_presets[ $img_size ] . ';}' );
        } elseif ( $img_size === 'custom' ) {
            $cw = sanitize_text_field( $content['width']  ?? '' );
            $ch = sanitize_text_field( $content['height'] ?? '' );
            if ( $cw && $cw !== 'auto' ) $renderer->add_css( $prefix . ' img{width:'  . esc_attr( $cw ) . ';}' );
            if ( $ch && $ch !== 'auto' ) {
                $renderer->add_css( $prefix . ' img{height:' . esc_attr( $ch ) . ';}' );

                // A fixed pixel height authored for a wide desktop column turns
                // into a TALL, NARROW box on a phone. Combined with
                // object-fit:cover that crops the subject away horizontally -
                // a 350x520 box on a 3:2 landscape photo discards ~55% of it.
                // Cap the height on mobile so the box stays landscape-ish and
                // the image keeps its subject. Percentage / viewport heights
                // are already fluid, so only clamp explicit px.
                if ( preg_match( '/^(\d+(?:\.\d+)?)px$/', $ch, $m ) && (float) $m[1] > 260 ) {
                    $renderer->add_mobile_css( $prefix . ' img{height:auto;max-height:' . (int) min( 300, (float) $m[1] ) . 'px;aspect-ratio:3/2;}' );
                }
            }
        }

        // ── Link ──────────────────────────────────────────────────────────────
        $link_open  = '';
        $link_close = '';
        if ( ! empty( $content['linkUrl'] ) ) {
            $target     = ! empty( $content['newTab'] ) ? ' target="_blank" rel="noopener noreferrer"' : '';
            $link_open  = '<a href="' . $renderer->tags( $renderer->get_current_post_id() )->resolve_url( $content['linkUrl'] ) . '"' . $target . '>';
            $link_close = '</a>';
        }

        // ── Caption ───────────────────────────────────────────────────────────
        $caption      = sanitize_text_field( $content['caption'] ?? '' );
        $figcaption   = '';
        if ( $caption ) {
            $cap_css   = '';
            $cap_align = sanitize_key( $settings['img_cap_textAlign'] ?? '' );
            $cap_color = $col( $settings['img_cap_color']   ?? '' );
            $cap_bg    = $col( $settings['img_cap_bgColor'] ?? '' );
            $cap_pad   = $dim( $settings['img_cap_spacing'] ?? '' ) ?: '8px';
            if ( $cap_align ) $cap_css .= 'text-align:'      . esc_attr( $cap_align ) . ';';
            if ( $cap_color ) $cap_css .= 'color:'            . esc_attr( $cap_color ) . ';';
            if ( $cap_bg    ) $cap_css .= 'background-color:' . esc_attr( $cap_bg ) . ';';
            $cap_css .= 'padding:' . esc_attr( $cap_pad ) . ';';
            $typo_css_map = [
                'fontFamily'    => 'font-family',    'fontSize'      => 'font-size',
                'fontWeight'    => 'font-weight',    'lineHeight'    => 'line-height',
                'letterSpacing' => 'letter-spacing', 'textTransform' => 'text-transform',
            ];
            foreach ( $typo_css_map as $k => $prop ) {
                $v = sanitize_text_field( $settings["img_cap_{$k}"] ?? '' );
                if ( $v ) $cap_css .= $prop . ':' . esc_attr( $v ) . ';';
            }
            $sh_h = $dim( $settings['img_cap_textShadowH']    ?? '' );
            $sh_v = $dim( $settings['img_cap_textShadowV']    ?? '' );
            $sh_b = $dim( $settings['img_cap_textShadowBlur'] ?? '' );
            $sh_c = $col( $settings['img_cap_textShadowColor'] ?? '' );
            if ( $sh_h || $sh_v || $sh_b ) {
                $cap_css .= 'text-shadow:' . esc_attr( ($sh_h?:'0px') . ' ' . ($sh_v?:'0px') . ' ' . ($sh_b?:'0px') . ' ' . ($sh_c?:'rgba(0,0,0,0.5)') ) . ';';
            }
            if ( $cap_css ) $renderer->add_css( $prefix . ' figcaption{' . $cap_css . '}' );
            $figcaption = '<figcaption>' . esc_html( $caption ) . '</figcaption>';
        }

        $lazy_attr = Jalpi_Settings::get( 'performance', 'enable_lazy_loading', '1' ) ? ' loading="lazy"' : '';

        return '<figure class="jalpi-el jalpi-' . esc_attr( $id ) . $a['extra_cls'] . '"' . $a['id_attr'] . '>'
             . $link_open
             . '<img src="' . $src . '" alt="' . $alt . '"' . $lazy_attr . '>'
             . $link_close
             . $figcaption
             . '</figure>';
    }
}
