<?php
namespace BLR\Backline\Modules\Events;

use BLR\Backline\Core\Access;
use BLR\Backline\Core\CrudHelpers;
use BLR\Backline\Core\Format;
use BLR\Backline\Core\ListPage;
use BLR\Backline\Core\PostQueries;
use BLR\Backline\Core\Request;
use BLR\Backline\Core\Router;
use BLR\Backline\Core\Views;

if (!defined('ABSPATH')) {
    exit;
}

final class Pages {
    public static function render_list(array $ctx): string {
        $ctx['events_list'] = self::list_data($ctx);
        return Views::render('pages/events', $ctx);
    }

    public static function render_form(array $ctx): string {
        $ctx['event_form'] = self::form_data($ctx);
        return Views::render('pages/event-form', $ctx);
    }

    public static function render_view(array $ctx): string {
        $ctx['event_view'] = self::view_data($ctx);
        return Views::render('pages/view-event', $ctx);
    }

    public static function handle_delete(array $ctx): string {
        return self::handle_post_delete($ctx, 'blr_event', 'events');
    }

    public static function list_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $page_num = Views::current_page_from_query_arg('pg');
        $view_mode = ListPage::view_mode();
        $search_term = Request::query_text('s');
        $status_filter = Request::query_key('event_status');
        $time_filter = Request::query_key('timeframe');
        $event_status_options = Module::status_options();
        $current_time_value = current_time('Y-m-d H:i');

        if ($time_filter !== '' && !in_array($time_filter, ['upcoming', 'past'], true)) {
            $time_filter = '';
        }

        $query_args = [
            'post_type'      => 'blr_event',
            'post_status'    => ['publish'],
            'posts_per_page' => 20,
            'paged'          => $page_num,
            'meta_key'       => 'blr_event_start',
            'orderby'        => 'meta_value',
            'order'          => ($time_filter === 'upcoming' ? 'ASC' : 'DESC'),
        ];

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

        $meta_query = [];
        if ($status_filter !== '' && array_key_exists($status_filter, $event_status_options)) {
            $meta_query[] = [
                'key'   => 'blr_event_status',
                'value' => $status_filter,
            ];
        }

        if ($time_filter === 'upcoming') {
            $meta_query[] = [
                'key'     => 'blr_event_start',
                'value'   => $current_time_value,
                'compare' => '>=',
                'type'    => 'CHAR',
            ];
        } elseif ($time_filter === 'past') {
            $meta_query[] = [
                'key'     => 'blr_event_start',
                'value'   => $current_time_value,
                'compare' => '<',
                'type'    => 'CHAR',
            ];
        }

        if (!empty($meta_query)) {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Event archive intentionally filters by event meta.
            $query_args['meta_query'] = PostQueries::and_meta_query($meta_query);
        }

        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Event archive intentionally sorts by stored event start meta.
        $events = new \WP_Query($query_args);
        $events_summary = Views::pagination_summary_data($events, 'pg');

        $persist_args = [];
        if ($search_term !== '') {
            $persist_args['s'] = $search_term;
        }
        if ($status_filter !== '') {
            $persist_args['event_status'] = $status_filter;
        }
        if ($time_filter !== '') {
            $persist_args['timeframe'] = $time_filter;
        }

        $event_items = [];
        foreach ((array) $events->posts as $post) {
            if (!$post instanceof \WP_Post) {
                continue;
            }

            $post_id = (int) $post->ID;
            $start = (string) get_post_meta($post_id, 'blr_event_start', true);
            $venue = (string) get_post_meta($post_id, 'blr_venue_name', true);
            $city = (string) get_post_meta($post_id, 'blr_venue_city', true);
            $state = (string) get_post_meta($post_id, 'blr_venue_state', true);
            $status = (string) get_post_meta($post_id, 'blr_event_status', true);

            $event_items[] = [
                'id'           => $post_id,
                'title'        => get_the_title($post),
                'start'        => $start,
                'venue'        => $venue,
                'city'         => $city,
                'state'        => $state,
                'location'     => Format::city_state($city, $state),
                'status'       => $status,
                'status_label' => ($status !== '' && isset($event_status_options[$status])) ? (string) $event_status_options[$status] : '',
                'view_url'     => $base . 'events/view/' . $post_id . '/',
                'edit_url'     => $base . 'events/edit/' . $post_id . '/',
                'delete_url'   => $base . 'events/delete/' . $post_id . '/',
            ];
        }

        return array_merge(ListPage::notices(), ListPage::view_urls($base, 'events', $persist_args, $view_mode), [
            'base'                 => $base,
            'page_num'             => $page_num,
            'new_url'              => $base . 'events/new/',
            'search_term'          => $search_term,
            'status_filter'        => $status_filter,
            'time_filter'          => $time_filter,
            'view_mode'            => $view_mode,
            'event_status_options' => $event_status_options,
            'events'               => $events,
            'events_summary'       => $events_summary,
            'event_items'          => $event_items,
        ]);
    }

    public static function form_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $is_edit = ($ctx['action'] ?? '') === 'edit';
        $post_id = $is_edit ? (int) ($ctx['id'] ?? 0) : 0;
        $post = $is_edit ? get_post($post_id) : null;

        return [
            'base'                 => $base,
            'is_edit'              => $is_edit,
            'post_id'              => $post_id,
            'post'                 => $post,
            'saved_notice'         => Request::query_absint('saved'),
            'errors'               => isset($ctx['errors']) && is_array($ctx['errors']) ? $ctx['errors'] : [],
            'title_v'              => $post instanceof \WP_Post ? (string) $post->post_title : '',
            'content_v'            => $post instanceof \WP_Post ? (string) $post->post_content : '',
            'current_image_id'     => $post_id ? absint(get_post_thumbnail_id($post_id)) : 0,
            'event_status_options' => Module::status_options(),
        ];
    }

    public static function view_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $id = (int) ($ctx['id'] ?? 0);
        $post = $id ? get_post($id) : null;
        if (!$post instanceof \WP_Post || $post->post_type !== 'blr_event') {
            return ['not_found' => true, 'base' => $base, 'id' => $id, 'post' => null];
        }

        return [
            'not_found' => false,
            'base'      => $base,
            'id'        => $id,
            'post'      => $post,
            'edit_url'  => $base . 'events/edit/' . $id . '/',
            'delete_url'=> $base . 'events/delete/' . $id . '/',
        ];
    }

    private static function handle_post_delete(array $ctx, string $post_type, string $section): string {
        $id = (int) ($ctx['id'] ?? 0);
        $redirect_to = rtrim((string) ($ctx['base_url'] ?? Router::base_url()), '/') . '/' . $section . '/?deleted=1';

        if ($id <= 0) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'missing_id'], $redirect_to));
            return '';
        }

        if (Request::method() !== 'POST') {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'invalid_method'], $redirect_to));
            return '';
        }

        $nonce_action = 'blr_ba_delete_' . $post_type . '_' . $id;
        $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field((string) wp_unslash($_POST['_wpnonce'])) : '';
        if ($nonce === '' || !wp_verify_nonce($nonce, $nonce_action)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'invalid_nonce'], $redirect_to));
            return '';
        }

        $post = get_post($id);
        if (!$post instanceof \WP_Post || $post->post_type !== $post_type) {
            return Views::render('pages/404', $ctx);
        }

        if (!Access::can_delete_post($id, $post_type)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'forbidden'], $redirect_to));
            return '';
        }

        if (!wp_delete_post($id, true)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'delete_failed'], $redirect_to));
            return '';
        }

        CrudHelpers::redirect($redirect_to);
        return '';
    }
}
