<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Handles the [nnax_user_file_manager] shortcode.
 */
class NNAXFUF_Shortcode {

    /**
     * @var NNAXFUF_Handlers
     */
    private $handlers;

    /**
     * @param NNAXFUF_Handlers $handlers Handlers instance for form/actions.
     */
    public function __construct( $handlers ) {
        $this->handlers = $handlers;
        add_shortcode( 'nnax_user_file_manager', array( $this, 'render_file_manager' ) );
    }

    public function render_file_manager( $atts = array(), $content = '' ) {
        // Ensure $folders is always defined to satisfy static analysis tools.
        $folders = array();

        if ( ! is_user_logged_in() ) {
            return '<p>' . esc_html__( 'Please log in to manage files.', 'nnax-frontend-user-files' ) . '</p>';
        }

        $current_user_id = get_current_user_id();

        // aktueller Ordner aus Query-Var
        $current_folder_id = 0;
        if ( get_query_var( NNAXFUF_Plugin::FOLDER_VAR ) ) {
            $current_folder_id = (int) get_query_var( NNAXFUF_Plugin::FOLDER_VAR );
        }

        // Papierkorb
        $view = get_query_var( NNAXFUF_Plugin::VIEW_VAR );
        $view = $view ? sanitize_key( $view ) : 'default';
        $post_status = ( $view === 'trash' ) ? 'trash' : 'publish';

        $current_filter = get_query_var( NNAXFUF_Plugin::FILTER_VAR );
        $current_filter = $current_filter ? sanitize_key( $current_filter ) : 'all';
        if ( ! in_array( $current_filter, array( 'all', 'owned', 'shared', 'shared_by_me' ), true ) ) {
            $current_filter = 'all';
        }

        // Suche
        $current_search = get_query_var( NNAXFUF_Plugin::SEARCH_VAR );
        $current_search = $current_search ? sanitize_text_field( $current_search ) : '';

        // Dateityp-Filter
        $current_type_filter = NNAXFUF_Helpers::sanitize_file_type_filter( get_query_var( NNAXFUF_Plugin::TYPE_VAR ) );

        // Sortierung
        $current_sort_key = get_query_var( NNAXFUF_Plugin::SORT_VAR );
        $current_sort_key = $current_sort_key ? sanitize_key( (string) $current_sort_key ) : 'name';
        if ( ! in_array( $current_sort_key, array( 'name', 'size', 'date' ), true ) ) {
            $current_sort_key = 'name';
        }
        $current_sort_direction = get_query_var( NNAXFUF_Plugin::ORDER_VAR );
        $current_sort_direction = $current_sort_direction ? sanitize_key( (string) $current_sort_direction ) : 'asc';
        if ( ! in_array( $current_sort_direction, array( 'asc', 'desc' ), true ) ) {
            $current_sort_direction = 'asc';
        }
        $current_show_mode = get_query_var( NNAXFUF_Plugin::SHOW_VAR );
        $current_show_mode = $current_show_mode ? sanitize_key( (string) $current_show_mode ) : '';
        $show_all_items = ( $current_show_mode === 'all' );

        // Paginierung
        $paged = get_query_var( NNAXFUF_Plugin::PAGED_VAR );
        $paged = $paged ? max( 1, (int) $paged ) : 1;
        $requested_paged = $paged;
        $settings = NNAXFUF_Helpers::get_settings();
        $posts_per_page = isset( $settings['items_per_page'] ) ? max( 1, (int) $settings['items_per_page'] ) : 20;

        // IDs vorfiltern für Sichtbarkeit und Ownership
        $visible_ids = $this->get_user_visible_item_ids( $current_user_id, $current_folder_id, $post_status, $current_filter, $current_search, $current_type_filter );

        $all_items = array();
        $items = array();
        $total_pages = 0;
        $total_items = count( $visible_ids );

        if ( ! empty( $visible_ids ) ) {
            $query_args = array(
                'post_type'      => array( NNAXFUF_Plugin::CPT, NNAXFUF_Plugin::CPT_FOLDER ),
                'post_status'    => $post_status,
                'post__in'       => $visible_ids,
                'posts_per_page' => -1,
            );

            $query = new WP_Query( $query_args );
            $all_items = is_array( $query->posts ) ? $query->posts : array();
            $all_items = $this->sort_items( $all_items, $current_sort_key, $current_sort_direction );
            $total_items = count( $all_items );
            $total_pages = (int) ceil( $total_items / $posts_per_page );
            if ( $total_pages < 1 && $total_items > 0 ) {
                $total_pages = 1;
            }
            if ( $show_all_items ) {
                $paged = 1;
                $total_pages = 1;
                $items = $all_items;
            } else {
                $offset = ( $paged - 1 ) * $posts_per_page;
                $items = array_slice( $all_items, $offset, $posts_per_page );
            }

            // Wenn nach Aktionen (z.B. Löschen/Verschieben) die aktuelle Seite außerhalb
            // des gültigen Bereichs liegt, auf die letzte gültige Seite zurückfallen.
            if ( ! $show_all_items && $total_pages > 0 && $paged > $total_pages ) {
                $paged = (int) $total_pages;

                // Bei normalen GET-Aufrufen URL auf die gültige Seite korrigieren.
                // Bei POST lassen wir die Seite ohne Redirect rendern, damit Notices erhalten bleiben.
                $request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( (string) $_SERVER['REQUEST_METHOD'] ) ) : '';
                $is_get_request = strtoupper( $request_method ) === 'GET';
                if ( $is_get_request && $requested_paged !== $paged && ! headers_sent() ) {
                    wp_safe_redirect(
                        NNAXFUF_Helpers::get_file_manager_url(
                            array(
                                NNAXFUF_Plugin::PAGED_VAR => $paged,
                            )
                        )
                    );
                    exit;
                }

                $offset = ( $paged - 1 ) * $posts_per_page;
                $items = array_slice( $all_items, $offset, $posts_per_page );
            }
        }

        // Nutzungs- und Quota-Infos
        $usage = NNAXFUF_Helpers::get_user_usage( $current_user_id );
        $quota = NNAXFUF_Helpers::get_user_quota_for( $current_user_id );
        $used_mb = $usage['total_bytes'] / ( 1024 * 1024 );

        $remaining_files = ( $quota['max_files'] > 0 ) ? max( 0, $quota['max_files'] - $usage['file_count'] ) : null;
        $remaining_mb = ( $quota['max_mb'] > 0 ) ? max( 0, $quota['max_mb'] - $used_mb ) : null;

        $used_mb_display       = number_format_i18n( $used_mb, 2 );
        $remaining_mb_display  = ( $remaining_mb !== null ) ? number_format_i18n( $remaining_mb, 2 ) : '';
        $quota_max_mb_display  = ( $quota['max_mb'] > 0 ) ? number_format_i18n( $quota['max_mb'], 2 ) : '';
        $frontend_form_action_url = admin_url( 'admin-post.php' );
        $frontend_notice_key      = $this->handlers->get_frontend_notice_key();
        $request_uri              = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( (string) $_SERVER['REQUEST_URI'] ) ) : '/';
        $frontend_redirect_url    = esc_url_raw( home_url( $request_uri ) );
        $notices               = $this->handlers->get_notices();

        ob_start();
        // Template laden
        require_once NNAXFUF_PLUGIN_PATH . 'templates/file-manager-template.php';
        return ob_get_clean();
    }

    /**
     * Sort items array according to key/direction.
     *
     * @param array $items
     * @param string $sort_key
     * @param string $sort_direction
     * @return array
     */
    private function sort_items( $items, $sort_key, $sort_direction ) {
        if ( empty( $items ) ) {
            return array();
        }

        usort( $items, function ( $a, $b ) use ( $sort_key, $sort_direction ) {
            $a_is_folder = ( isset( $a->post_type ) && $a->post_type === NNAXFUF_Plugin::CPT_FOLDER );
            $b_is_folder = ( isset( $b->post_type ) && $b->post_type === NNAXFUF_Plugin::CPT_FOLDER );

            if ( $a_is_folder !== $b_is_folder ) {
                return $a_is_folder ? -1 : 1;
            }

            $direction_factor = ( $sort_direction === 'desc' ) ? -1 : 1;
            $value = 0;

            if ( $sort_key === 'date' ) {
                $value = (int) get_post_modified_time( 'U', true, $a ) - (int) get_post_modified_time( 'U', true, $b );
            } elseif ( $sort_key === 'size' ) {
                $value = $this->get_item_sort_size( $a ) - $this->get_item_sort_size( $b );
            } else {
                $a_title = strtolower( wp_strip_all_tags( (string) $a->post_title ) );
                $b_title = strtolower( wp_strip_all_tags( (string) $b->post_title ) );
                $value = strcmp( $a_title, $b_title );
            }

            if ( $value === 0 ) {
                $a_title = strtolower( wp_strip_all_tags( (string) $a->post_title ) );
                $b_title = strtolower( wp_strip_all_tags( (string) $b->post_title ) );
                $value = strcmp( $a_title, $b_title );
            }

            return $value * $direction_factor;
        } );

        return $items;
    }

    /**
     * Get comparable size for an item (filesize or aggregated folder size).
     *
     * @param WP_Post|object|null $item
     * @return int
     */
    private function get_item_sort_size( $item ) {
        if ( ! $item || ! isset( $item->ID ) ) {
            return 0;
        }

        if ( isset( $item->post_type ) && $item->post_type === NNAXFUF_Plugin::CPT_FOLDER ) {
            return (int) NNAXFUF_Helpers::sum_folder_size_recursive( (int) $item->ID );
        }

        $file_path = get_post_meta( (int) $item->ID, NNAXFUF_Plugin::META_FILEPATH, true );
        if ( ! empty( $file_path ) && file_exists( $file_path ) ) {
            return (int) filesize( $file_path );
        }

        return 0;
    }

    /**
     * Sammelt alle sichtbaren Item-IDs für den aktuellen Kontext und Filter.
     */
    /**
     * Collect visible item IDs for given user and context.
     *
     * @param int $current_user_id
     * @param int $folder_id
     * @param string $post_status
     * @param string $current_filter
     * @param string $search_term
     * @param string $type_filter
     * @return int[]
     */
    private function get_user_visible_item_ids( $current_user_id, $folder_id = 0, $post_status = 'publish', $current_filter = 'all', $search_term = '', $type_filter = 'all' ) {
        $args = array(
            'post_type'      => array( NNAXFUF_Plugin::CPT, NNAXFUF_Plugin::CPT_FOLDER ),
            'post_status'    => $post_status,
            'posts_per_page' => -1,
            'fields'         => 'ids',
        );

        if ( (int) $folder_id > 0 ) {
            $args['post_parent'] = (int) $folder_id;
        }

        if ( ! empty( $search_term ) ) {
            $args['s'] = $search_term;
        }

        // Besitztum-Filter direkt in SQL für Performance
        if ( 'owned' === $current_filter ) {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Ownership filter intentionally pushed to SQL for performance.
            $args['meta_query'] = array(
                array(
                    'key'   => NNAXFUF_Plugin::META_OWNER,
                    'value' => $current_user_id,
                ),
            );
        } elseif ( 'shared_by_me' === $current_filter ) {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Shared-by-me filter requires owner+shared meta constraints.
            $args['meta_query'] = array(
                array(
                    'key'   => NNAXFUF_Plugin::META_OWNER,
                    'value' => $current_user_id,
                ),
                array(
                    'key'     => NNAXFUF_Plugin::META_SHARED,
                    'compare' => 'EXISTS',
                ),
            );
        }

        $all_ids = get_posts( $args );

        return array_values( array_filter( $all_ids, function ( $id ) use ( $current_user_id, $folder_id, $post_status, $current_filter, $search_term, $type_filter ) {
            $id = (int) $id;

            $post = get_post( $id );
            if ( ! $post || ( $post->post_type !== NNAXFUF_Plugin::CPT && $post->post_type !== NNAXFUF_Plugin::CPT_FOLDER ) ) {
                return false;
            }

            // Basis-Zugriffsprüfung
            if ( ! NNAXFUF_Helpers::user_can_access_item( $current_user_id, $id ) ) {
                return false;
            }

            // Typfilter gilt nur für Dateien. Ordner bleiben sichtbar, damit Navigation intakt bleibt.
            if ( $post->post_type === NNAXFUF_Plugin::CPT && ! NNAXFUF_Helpers::item_matches_file_type_filter( $id, $type_filter ) ) {
                return false;
            }

            $ctx = NNAXFUF_Helpers::get_share_context_for_user( $current_user_id, $id );
            $is_owner = ! empty( $ctx['is_owner'] );
            $is_shared_with_me = ! $is_owner && ! empty( $ctx['is_shared'] );
            $shared_with = null;

            // Wenn wir in einem Ordner sind, reicht can_access und post_parent (bereits per SQL eingeschränkt)
            if ( (int) $folder_id > 0 ) {
                if ( 'owned' === $current_filter ) {
                    return $is_owner;
                }
                if ( 'shared' === $current_filter ) {
                    return $is_shared_with_me;
                }
                if ( 'shared_by_me' === $current_filter ) {
                    if ( ! $is_owner ) {
                        return false;
                    }
                    $shared_with = NNAXFUF_Helpers::get_active_shared_user_ids( $id );
                    return ! empty( $shared_with );
                }
                return true;
            }

            // Speziallogik für Root: Nur Items zeigen, deren Parent man NICHT sieht
            // oder die man selbst besitzt.
            if ( 'owned' === $current_filter && ! $is_owner ) {
                return false;
            }
            if ( 'shared' === $current_filter && ! $is_shared_with_me ) {
                return false;
            }
            if ( 'shared_by_me' === $current_filter ) {
                if ( ! $is_owner ) {
                    return false;
                }
                $shared_with = NNAXFUF_Helpers::get_active_shared_user_ids( $id );
                if ( empty( $shared_with ) ) {
                    return false;
                }
            }

            if ( (int) $post->post_parent === 0 ) {
                return true;
            }
            
            // Im Papierkorb: Eigene löschbare Items immer im Root zeigen
            if ( 'trash' === $post_status && ! empty( $ctx['is_owner'] ) ) {
                return true;
            }

            // Wenn man der Owner ist, aber in einem Unterordner: Nicht im Root zeigen
            if ( ! empty( $ctx['is_owner'] ) ) {
                return false;
            }

            // Shared Items: Nur zeigen, wenn der Parent für den User nicht erreichbar ist (Einstiegspunkt)
            if ( ! NNAXFUF_Helpers::user_can_access_item( $current_user_id, (int) $post->post_parent ) ) {
                return true;
            }

            // Fallback: Wenn wir explizit nach shared_by_me filtern, nochmal prüfen ob wirklich shares da sind
            if ( 'shared_by_me' === $current_filter ) {
                if ( null === $shared_with ) {
                    $shared_with = NNAXFUF_Helpers::get_active_shared_user_ids( $id );
                }
                return ! empty( $shared_with );
            }

            return false;
        } ) );
    }
}
