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

use BLR\Backline\Core\Access;
use BLR\Backline\Core\CrudHelpers;
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_releases_list(array $ctx): string {
        $ctx['releases_list'] = self::releases_list_data($ctx);
        return Views::render('pages/discography-releases', $ctx);
    }

    public static function render_release_form(array $ctx): string {
        return Views::render('pages/discography-release-form', $ctx);
    }

    public static function render_release_view(array $ctx): string {
        return Views::render('pages/view-release', $ctx);
    }

    public static function render_tracks_list(array $ctx): string {
        $ctx['tracks_list'] = self::tracks_list_data($ctx);
        return Views::render('pages/discography-tracks', $ctx);
    }

    public static function render_track_form(array $ctx): string {
        return Views::render('pages/discography-track-form', $ctx);
    }

    public static function render_track_view(array $ctx): string {
        return Views::render('pages/view-track', $ctx);
    }

    public static function handle_release_delete(array $ctx): string {
        return self::handle_post_delete($ctx, 'blr_release', 'albums');
    }

    public static function handle_track_delete(array $ctx): string {
        return self::handle_post_delete($ctx, 'blr_track', 'tracks');
    }

    public static function releases_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');
        $release_type_filter = Request::query_key('release_type');
        $release_status_filter = Request::query_key('release_status');

        $release_type_terms = get_terms([
            'taxonomy'   => 'blr_release_type',
            'hide_empty' => false,
        ]);
        $release_type_terms = is_wp_error($release_type_terms) ? [] : $release_type_terms;

        $release_status_terms = get_terms([
            'taxonomy'   => 'blr_release_status',
            'hide_empty' => false,
        ]);
        $release_status_terms = is_wp_error($release_status_terms) ? [] : $release_status_terms;

        $query_args = [
            'post_type'      => 'blr_release',
            'post_status'    => ['publish'],
            'posts_per_page' => 25,
            'paged'          => $page_num,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ];

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

        $tax_query = [];
        if ($release_type_filter !== '' && taxonomy_exists('blr_release_type')) {
            $selected_type_term = get_term_by('slug', $release_type_filter, 'blr_release_type');
            if ($selected_type_term && !is_wp_error($selected_type_term)) {
                $tax_query[] = [
                    'taxonomy' => 'blr_release_type',
                    'field'    => 'slug',
                    'terms'    => [$release_type_filter],
                ];
            }
        }

        if ($release_status_filter !== '' && taxonomy_exists('blr_release_status')) {
            $selected_status_term = get_term_by('slug', $release_status_filter, 'blr_release_status');
            if ($selected_status_term && !is_wp_error($selected_status_term)) {
                $tax_query[] = [
                    'taxonomy' => 'blr_release_status',
                    'field'    => 'slug',
                    'terms'    => [$release_status_filter],
                ];
            }
        }

        if (!empty($tax_query)) {
            $query_args['tax_query'] = PostQueries::and_tax_query($tax_query);
        }

        $albums = new \WP_Query($query_args);
        $releases_summary = Views::pagination_summary_data($albums, 'pg');

        $persist_args = [];
        if ($search_term !== '') {
            $persist_args['s'] = $search_term;
        }
        if ($release_type_filter !== '') {
            $persist_args['release_type'] = $release_type_filter;
        }
        if ($release_status_filter !== '') {
            $persist_args['release_status'] = $release_status_filter;
        }

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

            $post_id = (int) $post->ID;
            $type_terms = wp_get_object_terms($post_id, 'blr_release_type', ['fields' => 'names']);
            $type = (!is_wp_error($type_terms) && !empty($type_terms)) ? (string) $type_terms[0] : '';
            if ($type === '') {
                $type = (string) get_post_meta($post_id, 'blr_release_type', true);
            }

            $status_terms = wp_get_object_terms($post_id, 'blr_release_status', ['fields' => 'names']);
            $release_status = (!is_wp_error($status_terms) && !empty($status_terms)) ? (string) $status_terms[0] : '';

            $album_items[] = [
                'id'         => $post_id,
                'title'      => get_the_title($post),
                'artist'     => (string) get_post_meta($post_id, 'blr_artist', true),
                'type'       => $type,
                'date'       => (string) get_post_meta($post_id, 'blr_release_date', true),
                'status'     => $release_status,
                'view_url'   => $base . 'albums/view/' . $post_id . '/',
                'edit_url'   => $base . 'albums/edit/' . $post_id . '/',
                'delete_url' => $base . 'albums/delete/' . $post_id . '/',
            ];
        }

        return array_merge(ListPage::notices(), ListPage::view_urls($base, 'albums', $persist_args, $view_mode), [
            'base'                  => $base,
            'new_url'               => $base . 'albums/new/',
            'page_num'              => $page_num,
            'search_term'           => $search_term,
            'release_type_filter'   => $release_type_filter,
            'release_status_filter' => $release_status_filter,
            'view_mode'             => $view_mode,
            'release_type_terms'    => $release_type_terms,
            'release_status_terms'  => $release_status_terms,
            'albums'                => $albums,
            'releases_summary'      => $releases_summary,
            'album_items'           => $album_items,
        ]);
    }

    public static function tracks_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');
        $release_status_filter = Request::query_key('release_status');

        $release_status_terms = get_terms([
            'taxonomy'   => 'blr_release_status',
            'hide_empty' => false,
        ]);
        $release_status_terms = is_wp_error($release_status_terms) ? [] : $release_status_terms;

        $query_args = [
            'post_type'      => 'blr_track',
            'post_status'    => ['publish'],
            'posts_per_page' => 25,
            'paged'          => $page_num,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ];

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

        if ($release_status_filter !== '' && taxonomy_exists('blr_release_status')) {
            $selected_status_term = get_term_by('slug', $release_status_filter, 'blr_release_status');
            if ($selected_status_term && !is_wp_error($selected_status_term)) {
                $query_args['tax_query'] = [[
                    'taxonomy' => 'blr_release_status',
                    'field'    => 'slug',
                    'terms'    => [$release_status_filter],
                ]];
            }
        }

        $tracks = new \WP_Query($query_args);
        $tracks_summary = Views::pagination_summary_data($tracks, 'pg');

        $persist_args = [];
        if ($search_term !== '') {
            $persist_args['s'] = $search_term;
        }
        if ($release_status_filter !== '') {
            $persist_args['release_status'] = $release_status_filter;
        }

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

            $post_id = (int) $post->ID;
            $status_terms = wp_get_object_terms($post_id, 'blr_release_status', ['fields' => 'names']);
            $release_status = (!is_wp_error($status_terms) && !empty($status_terms)) ? (string) $status_terms[0] : '';
            $release_date = (string) get_post_meta($post_id, 'blr_release_date', true);

            $bits = [];
            if ($release_status !== '') {
                $bits[] = $release_status;
            }
            if ($release_date !== '') {
                $bits[] = $release_date;
            }

            $track_items[] = [
                'id'             => $post_id,
                'title'          => get_the_title($post),
                'duration'       => (string) get_post_meta($post_id, 'blr_duration', true),
                'release_date'   => $release_date,
                'release_status' => $release_status,
                'status_bits'    => $bits,
                'view_url'       => $base . 'tracks/view/' . $post_id . '/',
                'edit_url'       => $base . 'tracks/edit/' . $post_id . '/',
                'delete_url'     => $base . 'tracks/delete/' . $post_id . '/',
            ];
        }

        return array_merge(ListPage::notices(), ListPage::view_urls($base, 'tracks', $persist_args, $view_mode), [
            'base'                  => $base,
            'page_num'              => $page_num,
            'new_url'               => $base . 'tracks/new/',
            'search_term'           => $search_term,
            'release_status_filter' => $release_status_filter,
            'view_mode'             => $view_mode,
            'release_status_terms'  => $release_status_terms,
            'tracks'                => $tracks,
            'tracks_summary'        => $tracks_summary,
            'track_items'           => $track_items,
        ]);
    }

    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 '';
    }
}