<?php

namespace GeminiLabs\SiteReviews\Controllers;

use GeminiLabs\SiteReviews\Commands\ApproveReview;
use GeminiLabs\SiteReviews\Commands\EnqueueAdminAssets;
use GeminiLabs\SiteReviews\Commands\ExportRatings;
use GeminiLabs\SiteReviews\Commands\ImportRatings;
use GeminiLabs\SiteReviews\Commands\TogglePinned;
use GeminiLabs\SiteReviews\Commands\ToggleStatus;
use GeminiLabs\SiteReviews\Database;
use GeminiLabs\SiteReviews\Defaults\ColumnFilterbyDefaults;
use GeminiLabs\SiteReviews\Helpers\Arr;
use GeminiLabs\SiteReviews\Helpers\Svg;
use GeminiLabs\SiteReviews\Install;
use GeminiLabs\SiteReviews\License;
use GeminiLabs\SiteReviews\Modules\Html\Builder;
use GeminiLabs\SiteReviews\Modules\Migrate;
use GeminiLabs\SiteReviews\Modules\Notice;
use GeminiLabs\SiteReviews\Modules\Queue;
use GeminiLabs\SiteReviews\Modules\Sanitizer;
use GeminiLabs\SiteReviews\Modules\Translation;
use GeminiLabs\SiteReviews\Request;

class AdminController extends AbstractController
{
    /**
     * @action site-reviews/route/get/admin/approve
     */
    public function approveReview(Request $request): void
    {
        $postId = Arr::get($request->data, 0);
        $review = glsr_get_review($postId);
        if ($review->isValid()) {
            $command = $this->execute(new ApproveReview($review));
            if ($command->successful()) {
                glsr(Notice::class)->store(); // because of the redirect
            }
        }
        wp_redirect(glsr_admin_url());
        exit;
    }

    /**
     * @action in_plugin_update_message-{glsr()->basename}
     */
    public function displayUpdateWarning(array $data): void
    {
        $version = Arr::get($data, 'new_version');
        $parts = explode('.', $version);
        $newVersion = Arr::getAs('int', $parts, 0, 0);
        if ($newVersion > (int) glsr()->version('major')) {
            glsr()->render('views/partials/update-warning');
        }
    }

    /**
     * @action admin_enqueue_scripts
     */
    public function enqueueAssets(): void
    {
        $this->execute(new EnqueueAdminAssets());
    }

    /**
     * @filter plugin_action_links_site-reviews/site-reviews.php
     */
    public function filterActionLinks(array $links): array
    {
        $actions = [];
        if (glsr()->hasPermission('settings')) {
            $actions['settings'] = glsr_admin_link('settings', _x('Settings', 'admin-text', 'site-reviews'));
        }
        return array_merge($actions, $links);
    }

    /**
     * @filter export_args
     */
    public function filterExportArgs(array $args): array
    {
        if (in_array(Arr::get($args, 'content'), ['all', glsr()->post_type])) {
            $this->execute(new ExportRatings(glsr()->args($args)));
        }
        return $args;
    }

    /**
     * @filter plugin_row_meta
     */
    public function filterRowMeta(array $links, string $file): array
    {
        if ($file !== glsr()->basename) {
            return $links;
        }
        $actions = [];
        if (glsr()->hasPermission('documentation')) {
            $actions['documentation'] = glsr_admin_link('documentatio.n', _x('Documentation', 'admin-text', 'site-reviews'));
        }
        $actions['support'] = glsr(Builder::class)->a([
            'aria-label' => esc_attr_x('Visit community forums', 'admin-text', 'site-reviews'),
            'href' => esc_url('https://wordpress.org/support/plugin/site-reviews'),
            'text' => esc_html_x('Community support', 'admin-text', 'site-reviews'),
        ]);
        return array_merge($links, $actions);
    }

    /**
     * @filter screen_options_show_submit
     */
    public function filterScreenOptionsButton(bool $showButton): bool
    {
        global $post_type_object, $title, $typenow;
        if (!str_starts_with($typenow, glsr()->post_type)) {
            return $showButton;
        }
        $submit = get_submit_button(_x('Apply', 'admin-text', 'site-reviews'), 'primary', 'screen-options-apply', false);
        $close = glsr(Builder::class)->button([
            'aria-controls' => 'screen-options-wrap',
            'class' => 'button button-secondary glsr-screen-meta-toggle',
            'text' => _x('Close Panel', 'admin-text', 'site-reviews'),
            'type' => 'button',
        ]);
        echo glsr(Builder::class)->p([
            'style' => 'display:inline-flex;gap:6px;',
            'text' => $submit.$close,
        ]);
        return false; // don't display the default submit button
    }

    /**
     * @filter mce_external_plugins
     */
    public function filterTinymcePlugins(array $plugins): array
    {
        if (glsr()->can('edit_posts')) {
            $plugins['glsr_shortcode'] = glsr()->url('assets/scripts/mce-plugin.js');
        }
        return $plugins;
    }

    /**
     * @action admin_init
     */
    public function onActivation(): void
    {
        if (empty(get_option(glsr()->prefix.'activated'))) {
            glsr(Install::class)->run(); // this hard-resets role permissions
            glsr(Migrate::class)->run();
            update_option(glsr()->prefix.'activated', true);
            glsr()->action('activated');
        }
    }

    /**
     * @action deactivate_{glsr()->basename}
     */
    public function onDeactivation(bool $isNetworkDeactivation): void
    {
        glsr(Install::class)->deactivate($isNetworkDeactivation);
    }

    /**
     * @action import_end
     */
    public function onImportEnd(): void
    {
        $this->execute(new ImportRatings());
    }

    /**
     * @action admin_head
     */
    public function printInlineStyle(): void
    {
        $rules = [];
        $rules[] = '@media only screen and (max-width: 960px) {'.
            '.auto-fold #adminmenu .menu-icon-site-review div.wp-menu-image {'.
                'height: 34px;'.
            '}'.
        '}';
        $rules[] = 'li:is(.submenu_glsr-settings,.submenu_glsr-premium)::before {'.
            'background: hsla(0,0%,100%,.2);'.
            'content: \'\';'.
            'display: block;'.
            'height: 1px;'.
            'margin: 5px 0;'.
            'width: 100%;'.
        '}';
        if (!glsr(License::class)->isPremium()) {
            $rules[] = 'li.submenu_glsr-premium a {'.
                'color: #e8ff5e !important;'. // --glsr-primary
            '}';
        }
        printf('<style type="text/css">%s</style>', implode('', $rules));
    }

    /**
     * @action in_admin_header
     */
    public function renderPageHeader(): void
    {
        global $post_type_object, $title;
        if (!$this->isAdminScreen()) {
            return;
        }
        $buttons = [];
        $screen = glsr_current_screen();
        if (glsr()->post_type === $screen->post_type && !glsr(License::class)->isPremium()) {
            $buttons['premium'] = [
                'class' => 'components-button is-primary glsr-try-premium',
                'href' => glsr_premium_url('site-reviews-premium'),
                'target' => '_blank',
                'text' => _x('Try Premium', 'admin-text', 'site-reviews'),
            ];
        }
        if (glsr()->can('import') && 'edit' === $screen->base) {
            $buttons['import'] = [
                'class' => 'components-button is-secondary',
                'data-expand' => '#tools-import-reviews',
                'href' => glsr_admin_url('tools', 'general'),
                'text' => _x('Import', 'admin-text', 'site-reviews'),
            ];
        }
        if (glsr()->can('create_posts') && in_array($screen->base, ['edit', 'post'])) {
            $buttons['new'] = [
                'class' => 'components-button is-secondary glsr-new-post',
                'data-new' => '',
                'href' => admin_url("post-new.php?post_type={$screen->post_type}"),
                'text' => Arr::get($post_type_object, 'labels.add_new'),
            ];
        }
        $buttons = glsr()->filterArray('page-header/buttons', $buttons);
        glsr()->render('views/partials/page-header', [
            'buttons' => $buttons,
            'hasScreenOptions' => in_array($screen->base, ['edit', 'edit-tags', 'post']),
            'logo' => Svg::get('assets/images/icon.svg', ['width' => 44]),
            'title' => esc_html($title),
        ]);
    }

    /**
     * @action admin_init
     */
    public function scheduleMigration(): void
    {
        if (defined('GLSR_UNIT_TESTS')) {
            return;
        }
        if (!$this->isAdminScreen()) {
            return;
        }
        if (glsr(Queue::class)->isPending('queue/migration')) {
            return;
        }
        if (!glsr(Migrate::class)->isMigrationNeeded() && !glsr(Database::class)->isMigrationNeeded()) {
            return;
        }
        glsr(Queue::class)->once(time() + MINUTE_IN_SECONDS, 'queue/migration');
    }

    /**
     * @action site-reviews/route/ajax/filter-assigned_post
     */
    public function searchAssignedPostsAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $results = glsr(Database::class)->searchAssignedPosts($search)->results();
        wp_send_json_success([
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/filter-assigned_user
     */
    public function searchAssignedUsersAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $results = glsr(Database::class)->searchAssignedUsers($search)->results();
        array_walk($results, function ($user) {
            $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
        });
        wp_send_json_success([
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/filter-author
     */
    public function searchAuthorsAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $results = glsr(Database::class)->searchUsers($search)->results();
        array_walk($results, function ($user) {
            $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
        });
        wp_send_json_success([
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/search-posts
     */
    public function searchPostsAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $results = glsr(Database::class)->searchPosts($search)->render();
        wp_send_json_success([
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/search-strings
     */
    public function searchStringsAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $exclude = Arr::consolidate($request->exclude);
        $results = glsr(Translation::class)
            ->search($search)
            ->exclude()
            ->exclude($exclude)
            ->renderResults();
        wp_send_json_success([
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/search-users
     */
    public function searchUsersAjax(Request $request): void
    {
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
        $results = glsr(Database::class)->searchUsers($search)->render();
        wp_send_json_success([
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
            'items' => $results,
        ]);
    }

    /**
     * @action site-reviews/route/ajax/toggle-filters
     */
    public function toggleFiltersAjax(Request $request): void
    {
        if ($userId = get_current_user_id()) {
            $filters = array_keys(glsr(ColumnFilterbyDefaults::class)->defaults());
            $enabled = glsr(Sanitizer::class)->sanitizeArrayString($request->enabled);
            $enabled = array_intersect($filters, $enabled);
            update_user_meta($userId, 'edit_'.glsr()->post_type.'_filters', $enabled);
        }
        wp_send_json_success();
    }

    /**
     * @action site-reviews/route/ajax/toggle-pinned
     */
    public function togglePinnedAjax(Request $request): void
    {
        $this->execute(new TogglePinned($request))->sendJsonResponse();
    }

    /**
     * @action site-reviews/route/ajax/toggle-status
     */
    public function toggleStatusAjax(Request $request): void
    {
        $this->execute(new ToggleStatus($request))->sendJsonResponse();
    }
}
