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

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

    public function render( array $node, Jalpi_Renderer $renderer ): string {
        $id       = sanitize_html_class( $node['id'] ?? '' );
        $settings = $node['settings'] ?? [];
        $styles   = $node['styles']   ?? [];

        $sel = ".jalpi-container.jalpi-{$id}";

        // Columns mode: detect when all children are column nodes
        $children    = $node['children'] ?? [];
        $has_columns = count( $children ) > 0
            && count( array_filter( $children, fn( $c ) => ( $c['type'] ?? '' ) === 'column' ) ) === count( $children );

        $layout_mode = sanitize_text_field( $settings['layoutMode'] ?? 'block' );

        // Base CSS — shared frame
        $css = "{$sel}{box-sizing:border-box;width:100%;margin-left:auto;margin-right:auto;";

        // Content width (Boxed)
        $cw = sanitize_text_field( $settings['contentWidth'] ?? 'full' );
        $bw = sanitize_text_field( $settings['boxedWidth']   ?? '' );
        if ( $cw === 'boxed' && $bw ) {
            $css .= 'max-width:' . esc_attr( $bw ) . ';';
        }

        // Layout (explicit grid/flex modes take priority over auto-detected column children)
        if ( $has_columns && $layout_mode !== 'grid' && $layout_mode !== 'flex' ) {
            // Column children → flex row (backwards-compat + explicit block-mode columns).
            // Only applies when the container has NOT been put in explicit flex mode:
            // otherwise this branch would swallow the author's flexAlign/flexGap/
            // flexWrap settings and silently hard-code stretch + a 20px gap.
            $col_gap = sanitize_text_field( $settings['columnGap'] ?? '20px' );
            $css .= "display:flex;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:{$col_gap};padding-left:0;padding-right:0;";
        } elseif ( $layout_mode === 'flex' ) {
            $flex_dir  = sanitize_text_field( $settings['flexDirection'] ?? 'row' );
            $flex_wrap = sanitize_text_field( $settings['flexWrapMode']  ?? 'nowrap' );
            $flex_just = sanitize_text_field( $settings['flexJustify']   ?? 'flex-start' );
            $flex_ali  = sanitize_text_field( $settings['flexAlign']     ?? 'stretch' );
            $flex_gap  = sanitize_text_field( $settings['flexGap']       ?? '0' );
            $css .= "display:flex;flex-direction:{$flex_dir};flex-wrap:{$flex_wrap};"
                  . "justify-content:{$flex_just};align-items:{$flex_ali};gap:{$flex_gap};"
                  . "padding-left:0;padding-right:0;";
        } elseif ( $layout_mode === 'grid' ) {
            $grid_auto  = sanitize_text_field( $settings['gridAutoMode']    ?? 'none' );
            $grid_cols  = sanitize_text_field( $settings['gridColumns']     ?? '3' );
            $grid_rows  = sanitize_text_field( $settings['gridRows']        ?? '' );
            $grid_gap   = sanitize_text_field( $settings['gridGap']         ?? '20px' );
            $min_size   = sanitize_text_field( $settings['gridMinColSize']  ?? '200px' );
            if ( $grid_auto === 'fill' ) {
                $template_cols = "repeat(auto-fill,minmax({$min_size},1fr))";
            } elseif ( $grid_auto === 'fit' ) {
                $template_cols = "repeat(auto-fit,minmax({$min_size},1fr))";
            } else {
                $col_count    = max( 1, absint( $grid_cols ) );
                $template_cols = "repeat({$col_count},1fr)";
            }
            $css .= "display:grid;grid-template-columns:{$template_cols};gap:{$grid_gap};padding-left:0;padding-right:0;";
            if ( $grid_rows && $grid_rows !== 'auto' ) {
                $row_count = max( 1, absint( $grid_rows ) );
                $css .= "grid-template-rows:repeat({$row_count},1fr);";
            }
        } else {
            // Block mode + backwards-compat
            $css .= 'display:block;padding-left:20px;padding-right:20px;';
            $align = sanitize_text_field( $settings['alignItems'] ?? '' );
            $cols  = absint( $settings['columns']       ?? 1 );
            $dir   = sanitize_text_field( $settings['direction']      ?? '' );
            $just  = sanitize_text_field( $settings['justifyContent'] ?? '' );
            $wrap  = sanitize_text_field( $settings['flexWrap']       ?? '' );
            $gap   = sanitize_text_field( $settings['gap']            ?? '' );
            if ( $align ) {
                $css .= "display:flex;flex-direction:column;align-items:{$align};";
            } elseif ( $cols > 1 ) {
                $css .= "display:grid;grid-template-columns:repeat({$cols},1fr);gap:" . ( $gap ?: '30px' ) . ";";
            } elseif ( $dir ) {
                $css .= "display:flex;flex-direction:{$dir};justify-content:" . ( $just ?: 'flex-start' )
                      . ";align-items:stretch;flex-wrap:" . ( $wrap ?: 'nowrap' )
                      . ";gap:" . ( $gap ?: '0' ) . ";";
            }
        }

        // Background (new model)
        $bg = $settings['bgNormal'] ?? [];
        $css .= $renderer->bg_data_to_css( $bg );

        // Border (new model)
        $bd = $settings['borderNormal'] ?? [];
        $css .= $renderer->border_data_to_css( $bd );

        // Overlay requires position:relative on the container
        $ov = $settings['overlayNormal'] ?? [];
        if ( ! empty( $ov['color'] ) || ! empty( $ov['imageUrl'] ) || ! empty( $ov['gradient'] ) ) {
            $css .= 'position:relative;';
        }

        // Style-tab overrides appended last so they win
        $css .= $renderer->styles_to_css( $styles );
        $css .= '}';

        // Hover state
        $bg_h      = $settings['bgHover']     ?? [];
        $bd_h      = $settings['borderHover'] ?? [];
        $hover_css = $renderer->bg_data_to_css( $bg_h ) . $renderer->border_data_to_css( $bd_h );
        if ( $hover_css ) {
            $css .= "{$sel}:hover{{$hover_css}}";
        }

        // Overlay CSS
        if ( ! empty( $ov['color'] ) || ! empty( $ov['imageUrl'] ) || ! empty( $ov['gradient'] ) ) {
            $ov_css  = "{$sel} .jalpi-container-overlay{position:absolute;inset:0;pointer-events:none;z-index:0;";
            $ov_css .= $renderer->bg_data_to_css( $ov );
            $opacity = floatval( $ov['opacity'] ?? 0.5 );
            $ov_css .= "opacity:{$opacity};}";
            $css .= $ov_css;
            // Lift container children above the overlay so content remains visible
            $css .= "{$sel}>:not(.jalpi-container-overlay){position:relative;z-index:1;}";
        }

        // Responsive: stack columns vertically on mobile (only in flex column mode, not grid)
        if ( $has_columns && $layout_mode !== 'grid' ) {
            $mobile_bp = (int) Jalpi_Settings::get( 'breakpoints', 'mobile_breakpoint', 767 );
            $css .= "@media(max-width:{$mobile_bp}px){{$sel}{flex-direction:column;}{$sel} .jalpi-column{flex:0 0 100%;max-width:100%;}}";
        }
        // Backwards-compat: grid collapse
        $cols = absint( $settings['columns'] ?? 1 );
        if ( $cols > 1 ) {
            $css .= "@media(max-width:768px){{$sel}{grid-template-columns:1fr;}}";
        }
        // Auto grid collapse on mobile
        if ( $layout_mode === 'grid' && ( $settings['gridAutoMode'] ?? 'none' ) === 'none' ) {
            $mobile_bp = (int) Jalpi_Settings::get( 'breakpoints', 'mobile_breakpoint', 767 );
            $css .= "@media(max-width:{$mobile_bp}px){{$sel}{grid-template-columns:1fr;}}";
        }

        $renderer->add_css( $css );

        // CSS ID / CSS Class from Settings tab — also resolves any attached
        // reusable classes (Class-Based Styling System).
        $attrs = $renderer->get_css_attrs( $node );

        $class   = 'jalpi-container jalpi-' . $id . $attrs['extra_cls'];
        $id_attr = $attrs['id_attr'];

        // Inline style — guarantees layout even if theme CSS interferes.
        // Padding resets are intentionally omitted here: the CSS class rule
        // (.jalpi-container.jalpi-{id}) already overrides frontend.css defaults with
        // higher specificity, and keeping padding-left/right out of the inline
        // style lets user-set padding from the Style tab take effect.
        // max-width for boxed containers IS included in the inline style so it
        // wins over any theme CSS (even rules with !important on generic selectors).
        $inline_props = [];

        // Same precedence rule as the stylesheet branch above: an explicit
        // layoutMode:'flex' must not be swallowed by the column-children
        // shortcut, or the author's flexAlign/flexGap are silently discarded.
        // This inline copy matters most — inline styles beat the class rule.
        if ( $has_columns && $layout_mode !== 'grid' && $layout_mode !== 'flex' ) {
            $col_gap_inline = sanitize_text_field( $settings['columnGap'] ?? '20px' );
            $inline_props[] = 'display:flex';
            $inline_props[] = 'flex-direction:row';
            $inline_props[] = 'flex-wrap:nowrap';
            $inline_props[] = 'align-items:stretch';
            $inline_props[] = 'gap:' . esc_attr( $col_gap_inline );
        } elseif ( $layout_mode === 'flex' ) {
            $d = sanitize_text_field( $settings['flexDirection'] ?? 'row' );
            $w = sanitize_text_field( $settings['flexWrapMode']  ?? 'nowrap' );
            $j = sanitize_text_field( $settings['flexJustify']   ?? 'flex-start' );
            $a = sanitize_text_field( $settings['flexAlign']     ?? 'stretch' );
            $g = sanitize_text_field( $settings['flexGap']       ?? '0' );
            $inline_props[] = 'display:flex';
            $inline_props[] = 'flex-direction:' . esc_attr( $d );
            $inline_props[] = 'flex-wrap:' . esc_attr( $w );
            $inline_props[] = 'justify-content:' . esc_attr( $j );
            $inline_props[] = 'align-items:' . esc_attr( $a );
            $inline_props[] = 'gap:' . esc_attr( $g );
        } elseif ( $layout_mode === 'grid' ) {
            $inline_props[] = 'display:grid';
            $inline_props[] = 'grid-template-columns:' . esc_attr( $template_cols );
            $inline_props[] = 'gap:' . esc_attr( $grid_gap );
            if ( $grid_rows && $grid_rows !== 'auto' ) {
                $row_count_i    = max( 1, absint( $grid_rows ) );
                $inline_props[] = 'grid-template-rows:repeat(' . $row_count_i . ',1fr)';
            }
        }

        // Enforce max-width via inline style so it beats any theme CSS rule.
        // Priority: Boxed setting > Style tab maxWidth.
        $eff_mw = '';
        if ( $cw === 'boxed' && $bw ) {
            $eff_mw = $bw;
        } elseif ( ! empty( $styles['maxWidth'] ) ) {
            $eff_mw = sanitize_text_field( (string) $styles['maxWidth'] );
        }

        if ( $eff_mw ) {
            $inline_props[] = 'max-width:' . esc_attr( $eff_mw );
            // Add centering margin only when the user hasn't set explicit side margins.
            if ( empty( $styles['marginLeft'] ) ) {
                $inline_props[] = 'margin-left:auto';
            }
            if ( empty( $styles['marginRight'] ) ) {
                $inline_props[] = 'margin-right:auto';
            }
        }

        $inline_style = $inline_props
            ? ' style="' . implode( ';', $inline_props ) . ';"'
            : '';

        // Overlay div
        $overlay_html = ( ! empty( $ov['color'] ) || ! empty( $ov['imageUrl'] ) || ! empty( $ov['gradient'] ) )
            ? '<div class="jalpi-container-overlay" aria-hidden="true"></div>'
            : '';

        return '<div class="' . esc_attr( $class ) . '"' . $id_attr . $inline_style . '>'
             . $overlay_html
             . $renderer->render_children( $node )
             . '</div>';
    }
}
