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

/**
 * Tabs (Advanced): each tab's content is a real container child node holding
 * nested widgets. `content.items[]` carries tab metadata (title/icon/cssId),
 * index-aligned to `children[]` (the per-tab container panels). Panels render
 * through the normal pipeline via Jalpi_Renderer::render_children(), so any
 * widget dropped into a tab renders exactly as it would elsewhere.
 *
 * Reuses the existing `.jalpi-tabs__*` CSS/JS from the classic Tabs element.
 */
class Jalpi_Element_Tabs_Adv extends Jalpi_Element {
    public static function type(): string { return 'tabs-adv'; }

    public function render( array $node, Jalpi_Renderer $renderer ): string {
        $id       = sanitize_html_class( $node['id'] ?? '' );
        $content  = $node['content'] ?? [];
        $styles   = $node['styles']  ?? [];
        $items    = (array) ( $content['items'] ?? [] );
        $panels   = (array) ( $node['children'] ?? [] );
        $tab_style = in_array( $content['tabStyle'] ?? 'underline', [ 'underline', 'boxed', 'pill' ], true )
                     ? $content['tabStyle'] : 'underline';
        $a        = $renderer->get_css_attrs( $node );

        $base_css = $renderer->styles_to_css( $styles );
        $renderer->add_css( '.jalpi-el.jalpi-' . $id . '{' . $base_css . '}' );
        $renderer->set_needs_js( 'tabs' );

        // ── Style-tab settings → scoped CSS for the tab buttons ──────────────
        $this->emit_tab_css( $id, (array) ( $node['settings'] ?? [] ), $renderer );

        $cls = 'jalpi-el jalpi-tabs jalpi-tabs--' . esc_attr( $tab_style ) . ' jalpi-' . esc_attr( $id ) . $a['extra_cls'];

        $nav   = '';
        $panes = '';
        foreach ( $items as $idx => $item ) {
            /* translators: %d: tab number */
            $title  = esc_html( $item['title'] ?? sprintf( __( 'Tab %d', 'jalpi-page-builder' ), $idx + 1 ) );
            $icon   = isset( $item['icon'] ) && ! empty( $item['icon'] )
                ? $renderer->render_icon_value( $item['icon'] )
                : '';
            $css_id = ! empty( $item['cssId'] ) ? ' id="' . esc_attr( sanitize_html_class( $item['cssId'] ) ) . '"' : '';
            $active = 0 === $idx;

            $glyph = '' !== $icon ? '<span class="jalpi-tabs__icon">' . $icon . '</span>' : '';
            $nav  .= '<button class="jalpi-tabs__btn' . ( $active ? ' is-active' : '' ) . '"'
                   . ' role="tab" aria-selected="' . ( $active ? 'true' : 'false' ) . '">'
                   . $glyph . $title
                   . '</button>';

            // Render this tab's panel = its container child's nested widgets.
            $panel_node = $panels[ $idx ] ?? null;
            $inner = is_array( $panel_node ) ? $renderer->render_children( $panel_node ) : '';
            $panes .= '<div class="jalpi-tabs__pane"' . $css_id . ( $active ? '' : ' hidden' ) . '>' . $inner . '</div>';
        }

        return '<div class="' . $cls . '"' . $a['id_attr'] . '>'
             . '<div class="jalpi-tabs__nav" role="tablist">' . $nav . '</div>'
             . '<div class="jalpi-tabs__body">' . $panes . '</div>'
             . '</div>';
    }

    /**
     * Emit scoped CSS for the tab buttons from the Style-tab settings
     * (tab_gap, tab_distance, and per-state tab_{normal|hover|active}_*).
     * Absent keys emit nothing, so an unstyled Tabs (Advanced) is unchanged.
     */
    private function emit_tab_css( string $id, array $s, Jalpi_Renderer $renderer ): void {
        $scope = '.jalpi-' . $id;
        $len   = static function ( $v ) { $v = self::css_len( $v ); return '' !== $v ? $v : null; };
        $col   = static function ( $v ) { return Jalpi_Sanitizer::sanitize_color( (string) $v ); };
        // 4-side shorthand from _top/_right/_bottom/_left; '' when all empty.
        $dim4  = function ( $prefix ) use ( $s, $len ) {
            $sides = [];
            $any   = false;
            foreach ( [ 'top', 'right', 'bottom', 'left' ] as $side ) {
                $v = $len( $s[ $prefix . '_' . $side ] ?? '' );
                if ( null !== $v ) { $any = true; }
                $sides[] = null !== $v ? $v : '0';
            }
            return $any ? implode( ' ', $sides ) : null;
        };

        $css = '';

        // Gap between tab buttons (flex gap on the nav).
        $gap = $len( $s['tab_gap'] ?? '' );
        if ( null !== $gap ) {
            $css .= $scope . ' .jalpi-tabs__nav{gap:' . $gap . '}';
        }
        // Distance between the nav and the content body.
        $dist = $len( $s['tab_distance'] ?? '' );
        if ( null !== $dist ) {
            $css .= $scope . ' .jalpi-tabs__body{margin-top:' . $dist . '}';
        }

        // Per-state button rules.
        $state_sel = [
            'normal' => $scope . ' .jalpi-tabs__btn',
            'hover'  => $scope . ' .jalpi-tabs__btn:hover',
            'active' => $scope . ' .jalpi-tabs__btn.is-active',
        ];

        // ── Titles: typography (state-independent) on the button text ──
        $typo = '';
        $ff = trim( (string) ( $s['title_fontFamily'] ?? '' ) );
        if ( '' !== $ff ) { $typo .= 'font-family:' . esc_attr( $ff ) . ';'; }
        $fsz = $len( $s['title_fontSize'] ?? '' );
        if ( null !== $fsz ) { $typo .= 'font-size:' . $fsz . ';'; }
        $fw = (string) ( $s['title_fontWeight'] ?? '' );
        if ( preg_match( '/^(100|200|300|400|500|600|700|800|900|normal|bold)$/', $fw ) ) { $typo .= 'font-weight:' . $fw . ';'; }
        $lh = $len( $s['title_lineHeight'] ?? '' );
        if ( null !== $lh ) { $typo .= 'line-height:' . $lh . ';'; }
        $ls = $len( $s['title_letterSpacing'] ?? '' );
        if ( null !== $ls ) { $typo .= 'letter-spacing:' . $ls . ';'; }
        $tt = (string) ( $s['title_textTransform'] ?? '' );
        if ( in_array( $tt, [ 'none', 'uppercase', 'lowercase', 'capitalize' ], true ) ) { $typo .= 'text-transform:' . $tt . ';'; }
        $fst = (string) ( $s['title_fontStyle'] ?? '' );
        if ( in_array( $fst, [ 'normal', 'italic', 'oblique' ], true ) ) { $typo .= 'font-style:' . $fst . ';'; }
        $tdc = (string) ( $s['title_textDecoration'] ?? '' );
        if ( in_array( $tdc, [ 'none', 'underline', 'overline', 'line-through' ], true ) ) { $typo .= 'text-decoration:' . $tdc . ';'; }
        if ( '' !== $typo ) {
            $css .= $scope . ' .jalpi-tabs__btn{' . $typo . '}';
        }

        // Build a "H V blur color" text-shadow from the 4 shadow keys.
        $text_shadow = function ( $prefix ) use ( $s, $len, $col ) {
            $h = $len( $s[ $prefix . '_textShadowH' ] ?? '' );
            $v = $len( $s[ $prefix . '_textShadowV' ] ?? '' );
            $b = $len( $s[ $prefix . '_textShadowBlur' ] ?? '' );
            $c = $col( $s[ $prefix . '_textShadowColor' ] ?? '' );
            if ( null === $h && null === $v && null === $b && '' === $c ) { return null; }
            return ( $h ?? '0' ) . ' ' . ( $v ?? '0' ) . ' ' . ( $b ?? '0' ) . ' ' . ( '' !== $c ? $c : 'rgba(0,0,0,0.3)' );
        };

        foreach ( $state_sel as $state => $selector ) {
            $p    = 'tab_' . $state . '_';
            $tpfx = 'title_' . $state;
            $rule = '';

            $bg = $col( $s[ $p . 'bg' ] ?? '' );
            if ( '' !== $bg )    { $rule .= 'background:' . $bg . ';'; }
            $fg = $col( $s[ $p . 'color' ] ?? '' );
            if ( '' !== $fg )    { $rule .= 'color:' . $fg . ';'; }

            // Title color (overrides the button color when set for this state).
            $title_color = $col( $s[ $tpfx . '_color' ] ?? '' );
            if ( '' !== $title_color ) { $rule .= 'color:' . $title_color . ';'; }

            // Title text shadow.
            $ts = $text_shadow( $tpfx );
            if ( null !== $ts ) { $rule .= 'text-shadow:' . $ts . ';'; }

            // Title text stroke (width + color → -webkit-text-stroke).
            $stroke_w = $len( $s[ $tpfx . '_strokeWidth' ] ?? '' );
            $stroke_c = $col( $s[ $tpfx . '_strokeColor' ] ?? '' );
            if ( null !== $stroke_w && '' !== $stroke_c ) {
                $rule .= '-webkit-text-stroke:' . $stroke_w . ' ' . $stroke_c . ';';
            }

            $b_type = $s[ $p . 'borderType' ] ?? 'none';
            if ( in_array( $b_type, [ 'solid', 'dashed', 'dotted', 'double' ], true ) ) {
                $rule .= 'border-style:' . $b_type . ';';
                $bw    = $dim4( $p . 'borderWidth' );
                if ( null !== $bw ) { $rule .= 'border-width:' . $bw . ';'; }
                $bc = $col( $s[ $p . 'borderColor' ] ?? '' );
                if ( '' !== $bc ) { $rule .= 'border-color:' . $bc . ';'; }
            }

            $shadow = Jalpi_Sanitizer::sanitize_css_value( (string) ( $s[ $p . 'boxShadow' ] ?? '' ) );
            if ( '' !== $shadow ) { $rule .= 'box-shadow:' . $shadow . ';'; }

            $radius = $dim4( $p . 'radius' );
            if ( null !== $radius ) { $rule .= 'border-radius:' . $radius . ';'; }

            $padding = $dim4( $p . 'padding' );
            if ( null !== $padding ) { $rule .= 'padding:' . $padding . ';'; }

            // Per-state icon color.
            $icon_color = $col( $s[ 'icon_' . $state . '_color' ] ?? '' );
            if ( '' !== $icon_color ) {
                $css .= $selector . ' .jalpi-tabs__icon{color:' . $icon_color . ';}';
            }

            if ( '' !== $rule ) {
                $css .= $selector . '{' . $rule . '}';
            }
        }

        // ── Icon layout (state-independent): position / size / spacing ──
        $btn_sel  = $scope . ' .jalpi-tabs__btn';
        $icon_sel = $scope . ' .jalpi-tabs__icon';
        $position = $s['icon_position'] ?? 'left';
        if ( ! in_array( $position, [ 'top', 'right', 'bottom', 'left' ], true ) ) {
            $position = 'left';
        }
        $spacing = $len( $s['icon_spacing'] ?? '' );
        $size    = $len( $s['icon_size'] ?? '' );

        // The button lays out icon + title as flex; direction depends on position.
        $flex_dir = [ 'left' => 'row', 'right' => 'row-reverse', 'top' => 'column', 'bottom' => 'column-reverse' ][ $position ];
        $btn_rule = 'display:inline-flex;align-items:center;justify-content:center;flex-direction:' . $flex_dir . ';';
        if ( null !== $spacing ) { $btn_rule .= 'gap:' . $spacing . ';'; }
        $css .= $btn_sel . '{' . $btn_rule . '}';

        if ( null !== $size ) {
            $css .= $icon_sel . '{display:inline-flex;font-size:' . $size . ';width:' . $size . ';height:' . $size . ';}';
        }

        // ── Content area (.jalpi-tabs__body): background / border / radius /
        //    padding (state-independent). ──
        $body_rule = '';
        $bg_type = $s['content_bgType'] ?? 'classic';
        if ( 'gradient' === $bg_type ) {
            $c1 = $col( $s['content_gradColor1'] ?? '' );
            $c2 = $col( $s['content_gradColor2'] ?? '' );
            if ( '' !== $c1 && '' !== $c2 ) {
                // Angle already sanitized to "Ndeg" (or a bare number → add deg).
                $ang_raw = trim( (string) ( $s['content_gradAngle'] ?? '' ) );
                if ( is_numeric( $ang_raw ) ) { $ang_raw .= 'deg'; }
                $ang = preg_match( '/^-?\d+(\.\d+)?deg$/', $ang_raw ) ? $ang_raw : '180deg';
                $body_rule .= 'background:linear-gradient(' . $ang . ',' . $c1 . ',' . $c2 . ');';
            }
        } else {
            $bg = $col( $s['content_bg'] ?? '' );
            if ( '' !== $bg ) { $body_rule .= 'background:' . $bg . ';'; }
        }

        $c_btype = $s['content_borderType'] ?? 'none';
        if ( in_array( $c_btype, [ 'solid', 'dashed', 'dotted', 'double' ], true ) ) {
            $body_rule .= 'border-style:' . $c_btype . ';';
            $cbw = $dim4( 'content_borderWidth' );
            if ( null !== $cbw ) { $body_rule .= 'border-width:' . $cbw . ';'; }
            $cbc = $col( $s['content_borderColor'] ?? '' );
            if ( '' !== $cbc ) { $body_rule .= 'border-color:' . $cbc . ';'; }
        }

        $c_radius = $dim4( 'content_radius' );
        if ( null !== $c_radius ) { $body_rule .= 'border-radius:' . $c_radius . ';'; }

        $c_padding = $dim4( 'content_padding' );
        if ( null !== $c_padding ) { $body_rule .= 'padding:' . $c_padding . ';'; }

        if ( '' !== $body_rule ) {
            $css .= $scope . ' .jalpi-tabs__body{' . $body_rule . '}';
        }

        if ( '' !== $css ) {
            $renderer->add_css( $css );
        }
    }

    /** "12" / "12px" / "0.5em" → a safe CSS length ('' if not a number). */
    private static function css_len( $val ): string {
        $val = trim( (string) $val );
        if ( '' === $val ) { return ''; }
        if ( is_numeric( $val ) ) { return $val . 'px'; }
        return preg_match( '/^-?\d+(\.\d+)?(px|em|rem|%|vh|vw)$/', $val ) ? $val : '';
    }
}
